【发布时间】:2021-12-16 16:51:54
【问题描述】:
当前 (Linux) 版本的 SysV i386 ABI 需要在调用前进行 16 字节堆栈对齐:
输入参数区域的结尾应在 16(32,如果 __m256 在堆栈上传递)字节边界上对齐。换句话说,当控制转移到函数入口点时,值 (%esp + 4) 始终是 16 (32) 的倍数。
在 GCC 8.1 上,此代码在调用 callee 之前将堆栈与 16 字节边界对齐:(Godbolt)
| source | # bytes |
|---|---|
| call | 4 |
| push ebp | 4 |
| sub esp, 24 | 24 |
| sub esp, 4 | 4 |
| push eax | 4 |
| push eax | 4 |
| push eax | 4 |
| Total | 48 |
在 GCC 8.2 及更高版本的所有版本中,它与 4 字节边界对齐:(Godbolt)
| source | # bytes |
|---|---|
| call | 4 |
| push ebp | 4 |
| sub esp, 16 | 16 |
| push eax | 4 |
| push eax | 4 |
| push eax | 4 |
| Total | 36 |
如果我们shorten 或raise callee 所需的参数数量,则很容易验证。
更改-mprefered-stack-boundary 会奇怪地将操作数更改为子指令,但不会更改实际的堆栈对齐方式:(Godbolt)
那么,呃,什么给了?
【问题讨论】: