2012-09-22 58 views
3

我似乎有一個有趣的問題,雖然我可能做了一些公然錯誤的事情。nasm 64位推qword?

我的問題是,我試圖將AAAABBBBCCCC推入堆棧,然後通過標準輸出打印它們。但是,似乎在我的x86_64環境中,push 0x41414141推動4141414100000000

所以下面的代碼塊:

global _start 
    section .text 
    _start: 
    push 0x43434343 ; CCCC 
    push 0x42424242 ; BBBB 
    push 0x41414141 ; AAAA 
    xor rax,rax  ; Zero RAX 
    mov byte al,0x1 ; 1 for sys_write 
    mov rdi,rax  ; 1 for stdout 
    mov rsi,rsp  ; RSP for source 
    mov byte dl,0xC ; 12 
    syscall   

    xor rax,rax  ; Zero RAX 
    mov al, 0x3C  ; 60 for sys_edxit 
    cdq    ; 0 for clean exit. 
    syscall 

輸出AAAABBBB中,我認爲是隻有8個字節,竟是12我問。當輸入到輸出文件並以hexedit查看時,我注意到它正在顯示414141410000000042424242

我認爲push指令推動了dword的值。到一個qword大小的堆棧?我是否認爲這是正確的?

這可以通過考慮額外的字節並將我的長度更改爲20來避免。但這會導致諸如sys_open之類的問題。

所以我的問題是,我做錯了什麼?

+0

@DCoder:根據'push'指令上的操作僞代碼,你是對的,因爲操作數會被符號擴展。 ---嗯......他只是刪除了他的評論? – IdiotFromOutOfNowhere

回答

7

對於64位代碼,堆棧(RSP)始終與8字節邊界對齊。也沒有「推qword imm64」指令(見注)。

我的建議是將字符串「AAAABBBBCCCC」存儲在它所屬的數據部分(或「.rodata」)中,而不是與堆棧混淆。

,保留你的變態可能是一種替代方案:

sub rsp,16 
mov [rsp],'AAAA' 
mov [rsp+4],'BBBB' 
mov [rsp+8],'CCCC' 
.... 
add rsp,16 

注:AMD手冊說,有一個「推imm64」指令。 AMD的手冊是錯誤的 - 該指令實際上推送了32位立即數(符號擴展到64位)。

+0

堆棧是__not__總是qword對齊!我同意其他一切...... – IdiotFromOutOfNowhere