пытаясь вставить «переменную» в стек - PullRequest
0 голосов
/ 28 августа 2018

У меня есть следующий код:

[bits 64]
%define msg db "%i\n", 0xa, 0
%define var -4
mov r8, rsp
mov [r8+(var)], WORD 0xFFFF
push WORD [r8+(var)] ; not works
; if trying to push DWORD its shows error instruction not supported in 64 bit asm
push DWORD 0xFFFF ; works
call tCtAKBWomJ
msg
tCtAKBWomJ:
call [rbx+3*8]
add rsp, 8
push 0
call [rbx]

вызов [rbx + x * 8]

это вызов asmloader api

x = 0, выход

x = 3, printf

и т.д.

Я хочу переместить значение в «переменную» и поместить его в стек.

EDIT:

[bits 64]

; const
%define msg db "%i", 0xa, 0

; vars offsets
%define var 8
; vars address
mov r8, rsp

; set var to 0xFFFF
mov DWORD [r8+(var)], 0xFFFF
; push var
push QWORD [r8+(var)]
; push const string msg
call tCtAKBWomJ
msg
tCtAKBWomJ:
; call printf
call [rbx+3*8]
add rsp, 8
; exit
push 0
call [rbx]

«переменное смещение» должно быть + значение, а не -.

и я должен использовать

push QWORD

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Синтаксис NASM push DWORD 0xFFFF - это push немедленного dword, расширенного до qword, при сборке в 64-битном режиме.

ИДК, почему NASM и YASM принимают это без предупреждения; Я бы сказал, что они не должны, потому что это вводит в заблуждение, как вы обнаружили.

Должен работать только push strict dword 1, чтобы переопределить непосредственное кодирование (а не размер операнда инструкции). Примечание ключевое слово strict , которое используется для переопределения нормального выбора кратчайшего кодирования (и в этом случае принудительного использования imm32, даже если число может быть закодировано в imm8). push dword 1 не не запрещает оптимизацию до push imm8, он только устанавливает операнд на dword. За исключением того, что это не так, он устанавливает его на qword в 64-битном режиме. Супер запутанный и возможно сломанный.

Единственными допустимыми размерами операндов для push в 64-битном режиме являются 64 и 16. Сколько байтов команда push помещает в стек, если я не указываю размер операнда? . 32-битный push не кодируется в 64-битном режиме.

Это относится к толчкам с памятью и операндам регистров, а не только к немедленным. Именно поэтому push dword [mem] не кодируется; в этом случае NASM рассматривает его как фактически требующий операнд памяти dword.


QWORD push-немедленный может использовать 8-битный или 32-битный немедленный, оба знака расширены до 64. Ширина непосредственного отделяется от размера операнда (ширина хранилища в памяти и количество вычитается из RSP). Снова, посмотрите на этот связанный вопрос.

0 голосов
/ 28 августа 2018

вместо

PUSH DWORD [r8+(var)]

использование

PUSH QWORD [r8+(var)]

так как все слова, помещенные в стек, являются qwords.

...