【发布时间】:2014-07-05 17:23:58
【问题描述】:
我不完全理解下面带有注释的那一行。我阅读了一些关于 SO 和 gcc 手册的帖子,并了解到这是用于堆栈地址对齐,但无法理解它是如何做到的。代码如下:
(gdb) disas main
Dump of assembler code for function main:
0x08048414 <+0>: push ebp
0x08048415 <+1>: mov ebp,esp
0x08048417 <+3>: and esp,0xfffffff0 ; why??
0x0804841a <+6>: sub esp,0x10
0x0804841d <+9>: mov DWORD PTR [esp],0x8048510
0x08048424 <+16>: call 0x8048320 <puts@plt>
0x08048429 <+21>: mov DWORD PTR [esp],0x8048520
0x08048430 <+28>: call 0x8048330 <system@plt>
0x08048435 <+33>: leave
0x08048436 <+34>: ret
End of assembler dump.
代码是在 Linux 上使用 gcc(版本 4.6.3)生成的。谢谢。
【问题讨论】:
-
它是通过蛮力对齐的,最低 4 位被重置,因此根据定义它现在至少对齐到 16。
-
它使地址成为 16 的倍数,即针对 128 位处理器进行了优化。
-
@harold 好的。是的。 ESP 的最后 4 位与 0000b 进行“与”运算(因此复位)。但这如何使它 2^4 字节对齐?也许我应该先了解对齐的含义。
-
N字节对齐意味着起始地址是N字节的倍数。如果 N 是 2 的幂,这也意味着存储整个值的所有字节地址都完全相同 除了 最低阶 log2(N) 位。这允许像您发布的代码中那样简单的屏蔽技术,而不是整数模(除法的余数)操作。