目录 Table of Contents
x86-32 过程调用小结
程序栈
- 各个过程运行实例的私有空间
不同实例间避免相互干扰
过程本地变量与参数存于栈内 (采用相对于基址寄存器 %ebp 的寻址模式)
- 符合栈基本工作规律
过程返回顺序与过程调用的顺序相反
相关指令与寄存器使用惯例
-
call
/ret
指令 -
寄存器使用惯例
调用者/ 被调用者 保存%ebp / %esp 两个特殊寄存器
-
栈帧的存储内容
文字填空题
下面给出了一个 C 函数, 并由 gcc 编译成相关的汇编代码 (AT&T 语法格式), 请补全这段代码里面的空白.
int arith(int x, int y, int z)
{
int t1 = x * y;
int t2 = z - t1;
int t3 = x + 40;
int t4 = y * 2;
int t5 = t3 >> t4; // t3 右移 t4 位
int rval = t2 * t5;
return rval;
}
pushl %ebp # Setup
movl ___, %ebp # Setup
movl ___(%ebp), %edx # edx = x
movl ___(%ebp), %ecx # ecx = y
pushl %ebx # save ebx
movl 16(%ebp), %eax # eax = z
movl %edx, %ebx # ebx = edx = x
addl $40, %edx # edx + 40, t3 = x + 40
imull ____, %ebx # ebx = x * y = t1
addl %ecx, ____ # ecx += y (ecx = 2 * y = t4)
sarl %cl, %edx # edx >> cl (cl = t4, edx = t5)
subl %ebx, %eax # eax -= ebx (eax = z - t1 = t2)
imull ___, %eax # eax *= edx (eax = t2 * t5 = rval)
popl ____ # reset ebx
popl %ebp # reset ebp
ret
ebp + 4 为返回地址, ebp + 8 为第一个参数
压栈是先压 y 再压 x, 函数内部取出来的时候就是先取 x 再取 y.