nasm 64 bit push 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, о которых я просил. Когда перенаправили в выходной файл и посмотрели в шестнадцатеричном формате, я заметил, что он отображает 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-байтовой границе. Также нет инструкции push qword imm64 (см. Примечание).

Я бы посоветовал сохранить строку AAAABBBBCCCC в разделе данных (или .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 говорится, что есть инструкция push imm64. Руководство AMD неверно - эта инструкция фактически подталкивает 32-битную версию немедленно (с расширением знака до 64-битной).

В руководстве Intel такой проблемы нет: https://www.felixcloutier.com/x86/push
Также связано: Сколько байтов команда push помещает в стек, если я не указываю размер операнда? - вы определенно не можете выполнить push dword в 64-битном режиме.

person Brendan    schedule 22.09.2012