x86-x64寄存器及CallStack调用栈

心不动则不痛 提交于 2019-12-01 10:16:07
  • Intel 32位体系结构(简称IA32)处理器包含8个通用寄存器,如下图所示:

    

  • EIP是指令寄存器,指向处理器下条等待执行的指令地址(代码段内的偏移量),每次执行完相应汇编指令EIP值就会增加。EIP是个特殊寄存器,不能像访问通用寄存器那样访问它,即不可对EIP进行寻址操作。EIP可被jmp、call和ret等指令隐含地改变
  • 函数调用栈的典型内存布局如下图所示:

 

  • 函数调用过程中的主要指令:
  1. 压栈(push):栈顶指针ESP减小4个字节;以字节为单位将寄存器数据(四字节,不足补零)压入堆栈,从高到低按字节依次将数据存入ESP-1、ESP-2、ESP-3、ESP-4指向的地址单元。
  2. 出栈(pop):栈顶指针ESP指向的栈中数据被取回到寄存器;栈顶指针ESP增加4个字节。
  3. 调用(call):将当前的指令指针EIP(该指针指向紧接在call指令后的下条指令)压入堆栈,以便返回时能恢复执行下条指令;然后设置EIP指向被调函数代码开始处,以跳转到被调函数的入口地址执行。
  4. 离开(leave): 恢复主调函数的栈帧以准备返回。

等价于指令序列:

movl %ebp, %esp(恢复原ESP值,指向被调函数栈帧开始处)

popl %ebp(恢复原ebp的值,即主调函数帧基指针)。

  1. 返回(ret):与call指令配合,用于从函数或过程返回。从栈顶弹出返回地址(之前call指令保存的下条指令地址)到EIP寄存器中,程序转到该地址处继续执行(此时ESP指向进入函数时的第一个参数)。
  • 两种压栈方式:

   

 

 

 

  • X86_64体系结构处理器包含16个通用寄存器,如图所示:

   

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!