X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。 刚刚说到,寄存器集成在CPU上,存取速度比存储器快好几个数量级,寄存器多了,GCC就可以更多的使用寄存器,替换之前的存储器堆栈使用,从而大大提升性能。
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式(在第3章有详细介绍),为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。[1] 段寄存器 段寄存器...
X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。 刚刚说到,寄存器集成在CPU上,存取速度比存储器快好几个数量级,寄存器多了,GCC就可以更多的使用寄存器,替换之前的存储器堆栈使用,从而大大提升性能。 让寄存器为己所用,就得了解它们的用...
如果是Caller Save寄存器,在进行子函数调用之前,需要由调用者提前保存寄存器中的值(入栈),然后在子函数中可以向这些寄存器中写入任何数据;在完成调用后,恢复寄存器原来的值(出栈)。如果是Callee Save寄存器,父函数在进行子函数调用前不会保存寄存器中的值,在调用子函数后,子函数会首先保存寄存器中的值(入栈);子函数...
在x86_64体系架构中,总共有16个64位通用寄存器,各寄存器及用途如下所示: 对上图中的寄存器做简单说明: %rax :通常存储函数调用的返回结果,也被用在idiv (除法)和imul(乘法)命令中。 %rsp :堆栈指针寄存器,指向栈顶位置。pop操作通过增大rsp的值实现出栈,push操作通过减小rsp的值实现入栈。
函数运行阶段在调用栈上占用的这段空间就叫做栈帧,是编译原理运行时空间组织中活动记录(activation record)的一种实现 栈帧主要通过 ebp、esp 两个寄存器维护,ebp 始终指向栈底,esp 始终指向栈顶 每个函数被调用时执行下面两条命令 pushl %ebp ; ebp入栈,保存调用者的栈帧基址,以便返回 ...
让寄存器为己所用,就得了解它们的用途,这些用途都涉及函数调用,X86-64有16个64位寄存器,分别是:%rax,%rbx,%rcx,%rdx,%esi,%edi,%rbp,%rsp,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15。其中: %rax 作为函数返回值使用。 %rsp 栈指针寄存器,指向栈顶 %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数...
在这里,我们需要关注x86_64下的一些通用64位寄存器,可以参考该文章的一张图: %rsp(堆栈指针寄存器) : 当执行汇编指令pop,push的时候,会改变该寄存器的值,从而实现堆栈的删除元素/添加元素操作 %rbp(栈帧指针) : 指向当前栈帧的起始位置 上面提出了一些概念,我们可以从下图来了解,下图有一些细节,这里详细说明: ...
而test2函数由于是叶子函数直接使用ebp/esp(此时它们两个相等),其参数和局部变量直接使用red zone空间存储,test2函数的栈帧空间布局如下: yezi2 x86-64.png 关于ebp基地址指针的使用(原标题:节约通用寄存器) 其实很多时候,我们发现ebp指针并没有使用,而仅仅使用esp指针就可以定位,并且DWARF(Debugging With Attributed ...
此时进入函数,rsp存栈(push),置rbp为rsp,改rsp的值为新栈顶,存入局部变量(mov)。rsp只在函数调用开始时扩展,结束前恢复,其他的“存栈”操作为mov %eax,-8(%rbp)之类的操作。这就是栈帧。栈帧不是所有函数都需要,小的函数只用寄存器就够的不需要创建栈帧。