我试图清楚地了解谁(调用者或被调用者)负责堆栈对齐.64位汇编的情况相当清楚,它是由调用者.
参考System V AMD64 ABI,第3.2.2节"堆栈帧":
输入参数区域的末尾应在16(32,如果在堆栈上传递__m256)字节边界上对齐.
换句话说,应该可以安全地假设,对于被调用函数的每个入口点:
16 | (%rsp + 8)
保持(额外八个是因为call隐含地在堆栈上推送返回地址).
它在32位世界中的表现(假设是cdecl)?我注意到,使用以下构造gcc将对齐放置在被调用函数内:
and esp, -16
Run Code Online (Sandbox Code Playgroud)
这似乎表明,这是被召唤者的责任.
为了更清楚,请考虑以下代码:
global main
extern printf
extern scanf
section .rodata
s_fmt db "%d %d", 0
s_res db `%d with remainder %d\n`, 0
section .text
main:
start 0, 0
sub esp, 8
mov DWORD [ebp-4], 0 ; dividend
mov DWORD [ebp-8], 0 ; divisor
lea eax, [ebp-8]
push …Run Code Online (Sandbox Code Playgroud)