I am trying to get a clear picture of who (caller or callee) is reponsible of stack alignment. The case for 64-bit assembly is rather clear, that it is by caller.
Referring to System V AMD64 ABI, section 3.2.2 The Stack Frame:
The end of the input argument area shall be aligned on a 16 (32, if __m256 is passed on stack) byte boundary.
In other words, it should be safe to assume, that for every entry point of called function:
16 | (%rsp + 8)
holds (extra eight is because call
implicitely pushes return address on stack).
How it looks in 32-bit world (assuming cdecl)? I noticed that gcc
places the alignment inside the called function with following construct:
and esp, -16
which seems to indicate, that is callee's responsibility.
To put it clearer, consider following NASM code:
global main
extern printf
extern scanf
section .rodata
s_fmt db "%d %d", 0
s_res db `%d with remainder %d
`, 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 eax
lea eax, [ebp-4]
push eax
push s_fmt
call scanf
add esp, 12
mov eax, [ebp-4]
cdq
idiv DWORD [ebp-8]
push edx
push eax
push s_res
call printf
xor eax, eax
leave
ret
Is it required to align the stack before scanf
is called? If so, then this would require to decrease %esp
by four bytes before pushing these two arguments to scanf
as:
4 bytes (return address)
4 bytes (%ebp of previous stack frame)
8 bytes (for two variables)
12 bytes (three arguments for scanf)
= 28
See Question&Answers more detail:os