0

我有这个代码(它确实需要 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

但是,如果我没有行 add esp, 4 it 分段错误,即使它是不平衡的(我从不从 esp 只有 8 中减去 4,然后再添加)。

4

1 回答 1

1

采用可变数量参数的函数,例如printf,不能将它们的参数从堆栈中“弹出”,调用者必须为它们执行此操作。这是因为该ret指令仅支持常量参数(英特尔术语中的立即数),但参数的数量因每次调用而异。

请参阅Wikipedia: Calling conventions with caller cleanup

于 2013-09-06T15:02:51.940 回答