gcc 如何告诉愚者不要将main的堆栈与16字节边界对齐?

ukxgm1gy  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(156)

愚者正在执行一些voodoo操作,它正在对齐我的main的堆栈,将参数的位置保存到ecx

0x08049060      8d4c2404       lea ecx, [arg_4h]                       ; 4 ; [13] -r-x section size 465 named .text
0x08049064      83e4f0         and esp, 0xfffffff0
0x08049067      ff71fc         push dword [ecx - 4]
0x0804906a      55             push ebp
0x0804906b      89e5           mov ebp, esp
0x0804906d      51             push ecx

后来

0x080490a4      8b4dfc         mov ecx, dword [local_4h]
0x080490a7      83c410         add esp, 0x10
0x080490aa      c9             leave
0x080490ab      8d61fc         lea esp, [ecx - 4]
0x080490ae      c3             ret

我相信我理解 * 为什么 * 愚者正在做它正在做的事情(you can read about it here),但是我试图从源代码重建的二进制文件缺少教程中的这些指令,我想生成尽可能接近教程的汇编。
这两个函数都是从file返回的,
stack 0:ELF 32位LSB可执行文件,英特尔80386,版本1(SYSV),动态链接,解释器/lib/ld-linux.so.2,用于GNU/Linux 2.6.18,
我已经在main上尝试了__attribute__ ((packed))#pragma pack,两者都不起作用。

uxhixvfz

uxhixvfz1#

您可以禁用堆栈对齐,方法是告诉愚者对齐到2字节,而不是16字节

-mpreferred-stack-boundary=2

这可能会对性能产生一些影响。
来自Peter Cordes,的警告
这将违反整个程序的ABI,在程序进入时和调用其他函数之前,未保持Linux版本的i386 SysV ABI所保证的16字节对齐。因此,使用SSE指令的编译器生成的代码可能会出现segfault。通过main上的函数属性,可能会告诉它传入的堆栈对齐是正确的。这对于您的用例来说可能不是问题,但这是一个重要的警告。此外,它可能会破坏其他线程引用的_Atomic uint64_t本地变量。

相关问题