《深入理解计算机系统》Machine level programming-III Procedures

主要讲解程序运行的各种过程, 涉及栈,函数调用过程中的数据传输,栈上数据存储.

栈结构:

《深入理解计算机系统》Machine level programming-III Procedures

栈的数据结构特征是后入先出,有一些场景适合用栈数据结构来设计。

%rsp---x86下的16个cpu之中普通的一个,stack pointer。

它的值代表现在栈顶的地址。

每次在栈上分配空间时,都会对%rsp进行自减。

一般会倒着画栈图,为了和linux虚拟地址空间做对应(个人理解)。

注意,栈的弹出,只是移动栈指针,被弹出的地址的数据暂时还在。

实际执行call指令的时候,一共进行了3件事:

1. 将%rsp减少8

2. 将即将要跳转到的指令地址写入此时的%rsp

3. pc值写入目标地址,开始执行

执行ret指令的时候,需要跳转回的地址已经在栈顶

1. 将栈顶数字弹出,即rsp加8

2. pc值写入该值

《深入理解计算机系统》Machine level programming-III Procedures

注:这些参数传递指的是整形数字或指针的传递,浮点数的传递由另外一组其他寄存器负责。

《深入理解计算机系统》Machine level programming-III Procedures

%rbp是一个可选寄存器,通常情况下,这个寄存器用作普通寄存器使用。正常情况下,编译器是知道子函数中分配了多少空间,在子函数执行完后,直接释放这么大的空间即可。

但一些特殊情况,子函数中分配了动态数组,或者不知道分配了多大空间的情况下,编译器就会使用rbp寄存器,用以标识返回时需要释放的空间范围。

为了避免无限嵌套,操作系统限制了栈的最大深度,limux默认8M。

ulimit -s查看

《深入理解计算机系统》Machine level programming-III Procedures

x86-64 linux register usage

两种约定:

caller saved:调用者保存的值,被调用函数在使用时,可以对该值进行任意操作;

callee saved:被调用者保存的值,被调用者需要对该值进行暂时修改时,必须先把原值push到栈上,退出前,把原值pop回寄存器中。

《深入理解计算机系统》Machine level programming-III Procedures

《深入理解计算机系统》Machine level programming-III Procedures