CSAPP——函数过程调用
函数调用三阶段
- 调用前:参数准备
- 调用时:call指令调用
- 函数调用时:开辟栈空间,执行指令
- 函数返回:leav指令和pop指令
(1)参数准备
- 从右到左处理参数列表,右边的参数先处理,与esp的距离越远
- 如果是指针或者引用类型的参数,将会保存参数的地址
(2)call指令调用函数
- call 指令调用函数,保存返回地址:
- push %eip
(3)开辟栈空间,执行指令
一般都是如下三条指令,首先将ebp保存在栈顶,然后将ebp指向新的栈底,然后esp减去一个值以开辟栈空间
- push %ebp
- mov %esp, %ebp
- sub $0x10, %esp
push %ebp
mov %esp, %ebp
sub $0x10, %esp
- 执行阶段一般是从参数列表左边处理到右边(但是过程/函数内部的变量 存放顺序与编译器有关)
(4)函数返回
函数返回时,用于恢复帧栈的位置,一般用leav指令和ret指令完成
- leave =
mov %ebp,%esp
pop %ebp - ret = pop %eip
- leave =
mov %ebp,%esp
pop %ebp![]()
swap函数的帧栈
- 对于swap函数首先他并没有开辟栈空间,而是直接pushl %ebx
- 其返回的形式也相应改变,用两个popl指令完成,其帧栈如下: