nasm 64 bit push qword?

Изглежда, че имам интересен проблем, въпреки че вероятно правя нещо явно нередно.

Проблемът ми е, че се опитвам да избутам AAAABBBBCCCCC в стека, след което да ги отпечатам чрез 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.

Та въпросът ми е какво правя грешно?


person Patrick S    schedule 22.09.2012    source източник
comment
@DCoder: Според псевдо кода на операцията в инструкцията push вие сте прав, тъй като операндът ще бъде с разширен знак. --- хммм... току-що премахна коментара си?   -  person IdiotFromOutOfNowhere    schedule 22.09.2012


Отговори (1)


За 64-битов код стекът (RSP) винаги е подравнен на граница от 8 байта. Също така няма инструкция за натискане на qword imm64 (вижте бележката).

Моят съвет би бил да съхранявате низа AAAABBBBCCCCC в секцията с данни (или .rodata), където му е мястото, вместо да се забърквате в стека. Или в шелкод,

push   'CCCC'                  ; push qword, including 4 bytes of zeros
mov    rax, 'AAAABBBB'         ; mov reg, imm64; pick any register
push   rax                     ; push qword

Алтернатива, която запазва вашата перверзия, може да бъде:

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

Забележка: Ръководството на AMD казва, че има инструкция за натискане на imm64. Ръководството на AMD е грешно - тази инструкция всъщност избутва 32-битов незабавен (с разширение на знака до 64-бита).

Ръководството на Intel няма този проблем: https://www.felixcloutier.com/x86/push
Също свързано: Колко байта изпраща инструкцията за насочване към стека, когато не посочвам размера на операнда? - определено не можете да направите натискане на dword в 64-битов режим.

person Brendan    schedule 22.09.2012