ebp 函数堆栈esp_读懂操作系统(x64)之堆栈帧(过程调用)

上一节内容我们对在32位操作系统下堆栈帧进行了详细的分析,本节我们继续来看看在64位操作系统下对于过程调用在处理机制上是否会有所不同呢?

堆栈帧

我们给出如下示例代码方便对照汇编代码看,和上一节有所不同的是函数调用多了几个参数。
#include 
int main(){
    int a = 1,b = 2, c = 3, d = 4, e = 5,f = 6, g = 7,h = 8;
    int func(int a, int b,int c,int d,int e,int f ,int g,int h);
    func(a,b,c,d,e,f,g,h);
}

int func(int a, int b,int c,int d,int e,int f ,int g,int h){
    int i = 30;
    return a + b + c + d + e + f + g + h + i;
}
接下来我们将上述代码转换为intel语法汇编代码,如下:
gcc -S -masm=intel -m64 1.c
x86仅提供8个通用寄存器(eax,ebx,ecx,edx,ebp,esp,esi,edi),而x64将它们扩展到64位(前缀为“r”而不是“e”),并添加了另外8个(r8,r9,r10,r11,r12,r13,r14,r15)。由于x86的某些寄存器具有特殊的隐含含义,并且并未真正用作通用寄存器(最著名的是ebp和esp),因此有效的增加甚至更大。根据《深入理解计算机系统》这本书介绍,函数的前6个整数或指针参数在寄存器中传递,第一个放在rdi中,第二个放在rsi中,第三个放在rdx中,然后是rcx,r8和r9寄存器中,仅第7个参数及后续参数在堆栈上传递(如下图所示)

fce78df08d5e15f8f9c09e3bedef89db.png

关于以上代码就不一一进行图解了,这里我用一张图解进行最终解释,如下:

b1245446c95c6e5f2724d371277dace1.png

由如上可知,前6个参数通过寄存器传递,而最后最后2个参数也就是g和h通过堆栈传递,但是除此和x86区别之外,还有个酒红色的区域,该空间不得由信号或中断处理程序修改,因此,函数可以使用此区域存储跨函数调用不需要的临时数据。尤其是,子函数可以在整个堆栈框架中使用此区域,而不是在序言和结语中调整堆栈指针,该区域称为红色区域(简而言之,保留该区域是一种优化)。

比如在上述函数中调用子函数并将对应参数传递到子函数中去,此时会将子函数中的局部变量存储在该保留区域,这样一来就无需通过rsp减去堆栈地址为局部变量分配空间,从而达到优化目的。以上对于x86-64的堆

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值