0x01 寄存器和栈

image-20240409170718620

被调用者保护

%rbp%rbx%r12~15

被调用者保护的寄存器在进入一个函数后会先压入栈来保存原先的值

返回值

%rax

寄存器rax通常存储着一个函数的返回值

调用者保护

除被调用者保护外。

和被调用者保护相反,可以随意修改该寄存器里的值而不需要压入栈来保存

参数

%rdi,%rsi,%rdx,%rcx,%r8,%r9

这里默认有六个参数寄存器,在传入函数时使用,超过的参数将在栈帧上保存

栈指针

%rsp

指示着栈顶的位置,栈往低处生长

0x02 运行时栈

image-20240409171340649

返回地址

在进入一个函数前,先将该call该函数的指令的下一条指令的地址压入栈,当执行ret指令时将该返回地址从栈中弹出,作为%rip的值(下一条执行指令的地址)

被保存的寄存器

对应寄存器中的被调用者保护寄存器,进入函数前先保存。

局部变量

有时,局部数据必须存放在内存中,常见的情况包括:

1、寄存器不足够存放所有的本地数据。

2、对一个局部变量使用地址运算符'&',因此必须能够为它产生一个地址

3、某些局部变量是数组或结构,因此必须能够通过数组或结构引用被访问到

参数构造区

当传入的函数的参数超过六个(对应六个参数寄存器)时,需要在call之前先在栈顶构造参数,存储在栈上,使得调用的函数通过栈指针来读取参数。