我有这个代码(它需要16字节堆栈对齐 - 操作系统:Mac OS X)
global _main
extern _printf
section .data
hw: db 'Hello World!' ,0xA,0
section .text
_main:
; esp is 0
sub esp, 8
; esp is -8
push hw
; esp is -12
; call makes esp -16
call _printf
; esp is now -8, printf popping its argument and ret taking the address put on by call
add esp, 8 ; -8 bytes remove padding
; esp is now 0
; why add an extra 4 bytes???
add esp, 4
; esp is now +4??
mov eax, 99
ret
然而,如果我没有行添加esp,4即使它是不平衡的,它也会出现分段错误(我从不从esp中减去4只有8,然后再重新添加)。
答案 0 :(得分:1)
采用可变数量参数的函数(例如printf
)无法从堆栈中“弹出”它们的参数,调用者必须为它们执行此操作。这是因为ret
指令仅支持常量参数(在英语术语中 immediates ),但参数的数量因每次调用而异。