问题在于您的堆栈使用情况。
首先,ABI docs指令
rsp必须 在 a 之前 对齐16个字节
call。
由于a
call会将8字节的返回地址压入堆栈,因此您需要将其
rsp乘以16加上8的倍数进行调整,以返回到16字节对齐。将
16 * n + 8被
包括 任何
push指令或其他更改RSP,而不仅仅是
sub rsp,24。这是段错误的直接原因,因为
printf将使用对齐的
SSE指令,这将对未对齐的地址产生错误。
如果您解决了该问题,则堆栈仍然不平衡,因为您一直在推入值,但从不弹出它们。很难理解您想对堆栈做什么。
通常的方法是在函数的开头(序言)为本地人分配空间,并在函数的结尾(结尾)释放空间。如上所述,此数量(包括任何推送)应为16加8的倍数,因为函数 项
上的RSP (在调用方之后
call)距离16字节边界8字节。
在大多数glibc版本中,
printf当AL!= 0时,它只关心16字节的堆栈对齐。(因为这意味着有FP
args,因此它将所有XMM寄存器转储到堆栈中,以便可以为
%f转换建立索引。)
如果您使用未对齐的堆栈来调用它,即使它在您的系统上正常工作,这仍然是一个错误;将来的glibc版本 可能会 包含依赖16字节堆栈对齐的代码,即使没有FP
args也是如此。例如,
scanf即使
AL=0在大多数GNU / Linux发行版中,也确实在未对齐的堆栈上崩溃。



