- Intel 32位体系结构(简称IA32)处理器包含8个通用寄存器,如下图所示:
- EIP是指令寄存器,指向处理器下条等待执行的指令地址(代码段内的偏移量),每次执行完相应汇编指令EIP值就会增加。EIP是个特殊寄存器,不能像访问通用寄存器那样访问它,即不可对EIP进行寻址操作。EIP可被jmp、call和ret等指令隐含地改变
- 函数调用栈的典型内存布局如下图所示:
- 函数调用过程中的主要指令:
- 压栈(push):栈顶指针ESP减小4个字节;以字节为单位将寄存器数据(四字节,不足补零)压入堆栈,从高到低按字节依次将数据存入ESP-1、ESP-2、ESP-3、ESP-4指向的地址单元。
- 出栈(pop):栈顶指针ESP指向的栈中数据被取回到寄存器;栈顶指针ESP增加4个字节。
- 调用(call):将当前的指令指针EIP(该指针指向紧接在call指令后的下条指令)压入堆栈,以便返回时能恢复执行下条指令;然后设置EIP指向被调函数代码开始处,以跳转到被调函数的入口地址执行。
- 离开(leave): 恢复主调函数的栈帧以准备返回。
等价于指令序列:
movl %ebp, %esp(恢复原ESP值,指向被调函数栈帧开始处)
popl %ebp(恢复原ebp的值,即主调函数帧基指针)。
- 返回(ret):与call指令配合,用于从函数或过程返回。从栈顶弹出返回地址(之前call指令保存的下条指令地址)到EIP寄存器中,程序转到该地址处继续执行(此时ESP指向进入函数时的第一个参数)。
- 两种压栈方式:
- X86_64体系结构处理器包含16个通用寄存器,如图所示: