nasm 64位推qword?

时间:2012-09-22 15:08:40

标签: assembly 64-bit nasm

我似乎有一个有趣的问题,虽然我可能做了一些明显错误的事情。

我的问题是我试图将AAAABBBBCCCC推入堆栈,然后通过stdout打印它们。但是,似乎在我的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

所以我的问题是,我做错了什么?

1 个答案:

答案 0 :(得分:8)

对于64位代码,堆栈(RSP)始终在8字节边界上对齐。也没有“push qword imm64”指令(见注释)。

我的建议是将字符串“AAAABBBBCCCC”存储在数据部分(或“.rodata”)中,而不是乱码。

保留你的变态的替代方案可能是:

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

注意:AMD的手册说有一个“push imm64”指令。 AMD的手册是错误的 - 该指令实际上推动了32位立即(符号扩展为64位)。