6_x86-32过程调用小结

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.