有关函数返回值的一段汇编代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        .file   "convert.c"
.text
.globl compute
.type compute, @function
compute:
.LFB0:
.cfi_startproc
movl $1, %eax
ret
.cfi_endproc
.LFE0:
.size compute, .-compute
.globl compute0
.type compute0, @function
compute0:
.LFB1:
.cfi_startproc
rep ret
.cfi_endproc
.LFE1:
.size compute0, .-compute0
.ident "GCC: (Debian 4.9.2-10) 4.9.2"
.section .note.GNU-stack,"",@progbits
1
2
3
4
5
6
int compute() {
return 1;
}
void compute0() {
//do nothing
}

可以看出compute和compute0函数在C上区别为返回值类型不同,在汇编上区别则体现在movl $1, %eax这一行上,$1是立即数(用来表示常熟之的操作数类型)1,%eax则是存放返回值的寄存器,这里的意思就是将1复制到%eax中。

那么也就是说当用到函数返回值时,其实是调用函数,然后去专门用来存放返回值的寄存器中取值。

rep ret相关可参考StackOverflow上的问答,其中高票答案提到

Basically, there was an issue in the AMD’s branch predictor when a single-byte ret immediately followed a conditional jump as in the code you quoted (and a few other situations), and the workaround was to add the rep prefix, which is ignored by CPU but fixes the predictor penalty.

也就是rep ret基本等效于ret