2013-10-02 21 views
8

thế nào là giá trị của 28h (thập phân 40) được trừ vào rsp tính như sau:alignment Stack trong lắp ráp x64

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 

từ: http://www.japheth.de/JWasm/Win64_1.html

Bằng sự hiểu biết của tôi, tôi sẽ phải chỉ trừ 20h vì mỗi giá trị tôi đang sử dụng mất 8 byte thành 4 là 20h. vậy tại sao là 28h bị trừ và cách đó dẫn đến căn chỉnh 16 byte?

xem thêm Is reserving stack space necessary for functions less than four arguments?

+0

@mbratch thanks :). xin vui lòng gửi như câu trả lời. – vandale

+0

Điều chắc chắn. Cảm ơn. :) – lurker

Trả lời

9

Tôi tin rằng đó là bởi vì trước khi main được gọi, ngăn xếp thẳng hàng. Sau đó, sau call, hành động của call là để đẩy một con trỏ 8-byte (địa chỉ của người gọi) vào ngăn xếp. Vì vậy, ở đầu của main, đó là 8 byte tắt của sự liên kết 16-byte. Do đó, thay vì 20h bạn cần 28h, nâng tổng số thực tế lên 28h + 8h (từ call) hoặc 30h. Căn chỉnh. :)

1

Tôi đã tình cờ gặp trường hợp tương tự. Đã cố gắng trả lời lurker và đã được sử dụng tốt. Sau đó thêm một số mã (bằng cách này, tôi đang sử dụng trình biên dịch của riêng tôi) và có vấn đề.

Vấn đề là địa chỉ không gian bóng đã kết thúc bằng 8 trên ngăn xếp. Khi địa chỉ không gian bóng tối kết thúc bằng 0 ("Stack align on 16 bytes"), cuộc gọi là OK. Việc thêm 8 byte sẽ làm hỏng ứng dụng trong trường hợp cuối cùng của tôi.