6

我研究了 32 位机器,我知道 sub $12, %esp 与 pop %eax 和 mov $0, %eax 上的三次相同。

但我不知道为什么我们在 x86-64 机器上使用 add $18, %rsp with start procedure call 或 sub $18, %rsp start with procedure call。

为什么编译器使用此规则进行过程调用?论证规则?

0x0000000000400df3 <main+191>:  mov    $0x402227,%edi
0x0000000000400df8 <main+196>:  callq  0x400ab8 <puts@plt>
0x0000000000400dfd <main+201>:  callq  0x4014c0 <read_line>
0x0000000000400e02 <main+206>:  mov    %rax,%rdi
0x0000000000400e05 <main+209>:  callq  0x401139 <phase_3>

-----------------------------------------------------------------------
example:

0x0000000000401139 <example+0>: sub    $0x18,%rsp
0x000000000040113d <example+4>: lea    0x8(%rsp),%rcx
0x0000000000401142 <example+9>: lea    0xc(%rsp),%rdx
0x0000000000401147 <example+14>:        mov    $0x40248a,%esi
0x000000000040114c <example+19>:        mov    $0x0,%eax
0x0000000000401151 <example+24>:        callq  0x400ac8 <__isoc99_sscanf@plt>
0x0000000000401156 <example+29>:        cmp    $0x1,%eax
4

1 回答 1

11

“我知道和sub $12, %esp三次一样。” 你知道错了。不会改变,既不是通过弹出也不是通过将 0 移入其中。pop %eaxmov $0, %eaxsub $12, %espeax

使用类似的主要/直接原因sub $12, %esp是在堆栈上保留一些空间。这可以用来给子程序的局部变量一些空间。如果出于性能或其他原因需要,也可以使用它来对齐堆栈指针。

add $18, %rsp反之亦然,它释放先前在堆栈上分配的空间。这可用于释放局部变量或先前已传递给另一个子例程且不再需要在堆栈上的参数占用的空间。

于 2012-09-28T08:03:05.807 回答