函数调用,是我们平时在写程序的时候最常用到的一种方法了,今天这篇文章就来带大家来看看,函数调用的时候,到底发生了啥
将控制从函数P转移到函数Q的时候,只需要简单的把程序计数器PC设置为Q的代码的起始位置。不过,当稍后从Q返回的时候,处理器必须要记录好它要继续在P中执行的位置。在x86-64机器中,这个信息是使用汇编指令`call Q`来记录的,它会把返回地址压入栈中,并将PC设置为Q的起始地址。当Q的处理逻辑执行完毕,会执行指令`ret`,它会将返回地址从栈中弹出,并将PC设置为该值。
参数传递:如果一个函数有大于6个参数,超出6个的部分就需要通过栈来传递,下图中“参数构造”取的就是参数7--->参数n的部分
局部存储:一般来说,函数通过减小栈顶指针来在栈上分配空间。分配的结果作为栈帧的一部分,标号为“局部变量”
寄存器中的局部存储空间: 按照惯例,寄存器%rbx, rbp 和r12--->r15被划分为“被调用者保存的寄存器”, 当P调用Q时,Q必须保存这些寄存器的值,保证它们的值在Q返回到P的时候,与调用Q的时候是一致的。要么不去修改,要么压入栈中,创建出“被保存的寄存器”区域。剩下的,除了rsp之外的所有寄存器,都被划分为“调用者保存寄存器”
内存对齐原则:任何K字节的基本对象的首地址必须是K的整数倍
阅读(1074) | 评论(0) | 转发(0) |