代码之家  ›  专栏  ›  技术社区  ›  vandale

x64程序集中的堆栈对齐

  •  10
  • vandale  · 技术社区  · 11 年前

    的价值是多少 28h (十进制40) rsp 计算如下:

        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个 20小时 。那么为什么 28小时 被减去,这是如何导致16字节对齐的?

    另请参阅 Is reserving stack space necessary for functions less than four arguments?

    2 回复  |  直到 2 年前
        1
  •  15
  •   lurker    2 年前

    我相信是因为之前 main 调用时,堆栈对齐。然后在 call ,的行为 呼叫 是将一个8字节的指针(调用方中要返回的地址,即调用指令之后的地址)推送到堆栈上。所以在 主要的 ,它比16字节的对齐方式少了8个字节。因此 20h 你需要 28h ,使实际总数达到 28h + 8h (来自 呼叫 )或 30h .对齐方式:)

        2
  •  1
  •   Sam    9 年前

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

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