x64汇编中的堆栈对齐

时间:2013-10-02 00:45:29

标签: assembly

如何从28h中减去rsp(十进制40)的值,计算如下:

    option casemap:none

    includelib kernel32.lib
    includelib user32.lib

externdef MessageBoxA : near
externdef ExitProcess : near

    .data

text    db 'Hello world!', 0
caption db 'Hello x86-64', 0

    .code

main proc
    sub rsp, 28h        ; space for 4 arguments + 16byte aligned stack
    xor r9d, r9d        ; 4. argument: r9d = uType = 0
    lea r8, [caption]   ; 3. argument: r8  = caption
    lea rdx, [text]     ; 2. argument: edx = window text
    xor rcx, rcx        ; 1. argument: rcx = hWnd = NULL
    call MessageBoxA
    xor ecx, ecx        ; ecx = exit code
    call ExitProcess
main endp

    end

来自:http://www.japheth.de/JWasm/Win64_1.html

根据我的理解,我只需要减去20h,因为我使用的每个值占用8个字节到4是20h。那么为什么要减去28h,这又如何导致16字节对齐?

另见Is reserving stack space necessary for functions less than four arguments?

2 个答案:

答案 0 :(得分:9)

我相信这是因为在调用main之前,堆栈是对齐的。然后在call之后,call的动作是将一个8字节的指针(调用者的地址)推入堆栈。所以在main的开头,它是16字节对齐的8字节。因此,您需要20h而不是28h,而是将实际总数设为28h + 8h(来自call)或30h。对准。 :)

答案 1 :(得分:1)

我偶然发现了同样的情况。尝试潜伏者回答,很好。后来添加了一些代码(顺便说一句,我正在使用自己的编译器)并遇到问题。

问题是影子空间地址在堆栈上以8结尾。当影子空间地址以0结尾时(“堆栈在16字节上对齐”),调用正常。 在我的最后一种情况下,添加8个字节会使应用程序崩溃。