__asm__ __volatile__ (
"movl 0x4(%ebp), %eax \n"
"addl $15, %eax \n"
"movl %eax, 0x4(%ebp)"
);
我知道%eax
会存储返回值,但这里的%ebp
是什么?
答案 0 :(得分:4)
假设你的函数的prolog看起来像这样:
pushl %ebp
movl %esp, %ebp
...
%ebp将是存储基指针的寄存器(也称为帧指针)。基指针是当前堆栈帧在堆栈中开始的位置。与x86一样,堆栈向下增长,本地数被引用为%ebp的负偏移量。参数和返回地址由%ebp的正偏移引用。 %ebp中的值指向堆栈上调用者的%ebp值(由prolog推送)。这有效地形成了可用于“遍历”堆栈的基本指针的链接列表。注意:这假设每个堆栈帧都有一个基指针;有一种称为帧指针省略(FPO)的优化可以释放%ebp用于其他用途。
所以给了一个带有该prolog的函数,如果用调用指令调用它(即调用者的返回地址被压入堆栈),则0x4(%ebp)将存储返回地址,因为它是最后推送的东西在被调用者的序言执行之前进入堆栈。因此,您的代码片段会导致下一条指令在被调用者返回到调用者的调用指令末尾15字节后执行,而不是在调用后的下一条指令。
编辑:到目前为止,我的大量编辑都是为了更好地解释我的答案。
答案 1 :(得分:2)
ebp
是帧指针。 ebp和esp标记当前进程的堆栈帧。
0x4(%ebp)实际上是返回地址,此调用后返回的函数的地址结束。
检查此图片中的堆栈帧。
答案 2 :(得分:1)
%ebp
寄存器指向当前堆栈帧,其中存储了函数参数和局部变量。该代码正在访问%ebp偏移量0x4处的值(该值代表的值未显示)。
答案 3 :(得分:0)
ebp是一个基指针。存储在堆栈中的函数参数,首先在堆栈中是返回地址,因此(如果我们使用32位机器)0x4(%ebp)指向函数的第一个参数。