Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1875787
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: IT业界

2020-05-22 15:13:35

函数调用,是我们平时在写程序的时候最常用到的一种方法了,今天这篇文章就来带大家来看看,函数调用的时候,到底发生了啥

将控制从函数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的整数倍
阅读(1076) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~