在 x86 架构的计算机中,ebp(Extended Base Pointer)寄存器通常用于指向当前函数的栈帧(stack frame)的基地址。栈帧是函数调用期间在栈上分配的一块内存区域,用于存储局部变量、函数参数、返回地址和其他临时数据。Linux 中,用户注册的信号处理函数,就是从内核态回到用户态时,发现有此信号,于是内核修改用户态的栈,增加一个栈帧来对应执行信号处理函数,从而实现了 Linux 信号机制。
1,栈帧和 ebp 的作用
1.1. 栈帧的结构:
每次函数调用时,都会在栈上分配一个新的栈帧。栈帧通常包含以下内容:
<1> 函数的局部变量
<2> 函数参数
<3> 返回地址(调用函数的地址)
<4> 前一个栈帧的基地址(即调用者的 ebp 值)
1.2. ebp 的作用:
<1> ebp 寄存器指向当前栈帧的基地址。通过 ebp,程序可以方便地访问栈帧中的各个元素。
<2> 在函数调用时,ebp 的值会被保存到栈上,并且 ebp 会被更新为当前栈帧的基地址。
<3> 当函数返回时,ebp 会被恢复为调用者的栈帧基地址。
2,函数调用过程中的 ebp 使用
2.1. 函数入口:
在函数入口处,当前的 ebp 值会被保存到栈上,然后 ebp 会被更新为当前栈顶的值。这通常通过以下汇编指令实现:
push ebp ; 保存调用者的 ebp 值
mov ebp, esp ; 更新 ebp 为当前栈顶的值
这是32为x86中的寄存器名字,x86_64 有对应的急促起,rbp,rsp等
C语言函数的 push ebp 的作用是压栈保存调用函数的栈帧基址;
被调用这的栈帧基址如何获得呢?即调用者的栈帧栈顶地址,所以调用者执行
mov ebp, esp;
即将调用者的栈帧栈顶地址,作为被调者的帧基址使用。
实现了栈帧堆叠效果,Linux中栈向下增长:
main() -> func1() -> func2() ->
——————————
全局数据区
main() 栈帧
func1() 栈帧
func2() 栈帧
以下面的hello.c 中的 add() 为例:
int add(int x, int y)
{
return x+y;
}
int main()
{
int s = 3;
int t = 4;
int u = 5;
u = u + add(s, 5);
return u;
}
生成 -m32 汇编代码如下:

注意,
x86 call 指令,附带功能:将下一条指令的偏移地址ip入栈,然后跳转至被调函数标号处;
调用结束时,ret指令会将IP弹出
这对应着编译原理中活动记录的内容。C语言的函数栈帧即函数执行一次的活动记录。
main中 call add指令之后的 addl $8, %esp,就是俗称的平栈,esp本来是子函数活动记录的TOP指针,现在返回后应当恢复回来。
即,移动TOP这个动作,在x86中,是调用者返回后做的第一件事儿,即返回地址的第一条指令是修改TOP值,即esp寄存器的值。通常是 add esp, 8 之类的;这个8是由实际参数个数和其他数据的长度决定。
2.2. 函数内部:
在函数内部,通过 ebp 可以访问函数参数和局部变量。例如:
- 函数参数:[ebp + 8] 表示第一个参数,[ebp + 12] 表示第二个参数,依此类推。

- 局部变量:[ebp - 4] 表示第一个局部变量,[ebp - 8] 表示第二个局部变量,依此类推。
2.3. 函数返回:
在函数返回时,ebp 会被恢复为调用者的栈帧基地址,然后栈顶指针 esp 会被更新为 ebp 的值,如图一所示。
这通常通过以下汇编指令实现:
pop ebp
ret
其中:
pop ebp ; 恢复调用者的 ebp 值,栈帧基址,即活动记录基地址
ret ; 返回调用者,会自动将call指令push IP寄存器值,再自动pop 出去恢复IP寄存器的值,确保调用程序调用子函数返回后继续往下执行。
3,示例 intel 汇编格式
以下是一个简单的 C 函数及其对应的汇编代码示例:
int add(int x, int y)
{
return x+y;
}
对应的汇编代码可能如下:
add:
push ebp
mov ebp, esp
mov edx, DWORD PTR [ebp+8]
mov eax, DWORD PTR [ebp+12]
add eax, edx
pop ebp
ret
实际返回表效果:

4,总结
ebp 寄存器在 x86 架构中用于指向当前函数的栈帧基地址。
通过 ebp,程序可以方便地访问栈帧中的函数参数和局部变量。
在函数调用过程中,ebp 的值会被保存和恢复,以维护栈帧的结构。
通过理解 ebp 的作用,可以更好地理解函数调用过程中的栈帧管理和内存布局。

1966

被折叠的 条评论
为什么被折叠?



