我看了一些汇编代码的转储,在主函数中有这一部分(在这里和这里都可以找到):
<main+0>: push %ebp
<main+1>: mov %esp, %ebp
<main+3>: sub $0x8, %esp
<main+6>: and $0xfffffff0, %esp
<main+9>: mov $0x0, %eax
<main+14>: add $0xf, %eax
<main+17>: add $0xf, %eax
<main+20>: shr $0x4, %eax
<main+23>: shl $0x4, %eax
<main+26>: sub %eax, %esp
你能解释一下(main+9)到(main+26)是用来做什么的吗?为什么这样做如此"低效"?
所以你想在不自己做任何研究的情况下进行完整的演练?听起来很合法。
main+9:mov$0x0,%eax
用十六进制0(=dec 0)加载寄存器eax
。
main+14:添加$0xf,%eax
将十六进制F(=dec 15)添加到eax
中的零。
main+17:添加$0xf,%eax
再次向eax
添加十六进制F(=dec 15)。这三条指令也可以由完成
movl $0x1e, %eax
但谁在数指令。。。无论如何,此时eax
包含十六进制1E,即dec 30。
main+20:shr$0x4,%eax
将eax
的内容右移四位。
main+23:shl$0x4,%eax
将eax
移回右侧。为什么?因为这会清除最低的四位。现在eax包含十六进制10(=dec 16)
main+26:sub%eax,%esp
从esp
(堆栈指针)减去eax
。自
main+6:和$0xffffff0,%esp
之前清除了esp
中的低四位,根据ABI,新的esp
将是十六字节对齐的。为什么不在main+6
之后简单地使用esp?因为在x86上,堆栈从内存顶部向下增长。简单地屏蔽esp
的低位有可能破坏局部变量。因此,减法将堆栈向下扩展到16字节边界。