我有以下代码:
[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
等
我想将值移动到“变量”并将其推入堆栈。
编辑:
[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]
“可变偏移量”应为+值,而不是-。
我应该使用
按下QWORD
答案 0 :(得分:3)
代替
PUSH DWORD [r8+(var)]
使用
PUSH QWORD [r8+(var)]
因为压入堆栈的所有单词都是qword。
答案 1 :(得分:2)
NASM语法push DWORD 0xFFFF
是双字的push的双字,当以64位模式进行汇编时,其符号扩展为qword。
IDK为什么NASM和YASM接受它而没有警告;如您所见,我认为他们不应该这样做,因为它会误导人。
只有push strict dword 1
应该起作用,以覆盖立即数的编码(而不是指令的操作数大小)。注意the strict
keyword,它用于覆盖最短编码的常规选择(在这种情况下,即使数字可以用imm8编码,也强制使用imm32)。 push dword 1
不会不会抑制对push imm8
的优化,它只会将操作数设置为dword
。除非没有,否则它将在64位模式下将其设置为qword。超级混乱,可以说是坏了。
在64位模式下push
的唯一合法操作数大小是64和16。
How many bytes does the push instruction push onto the stack when I don't specify the operand size?。 32位push
在64位模式下无法编码。
这适用于带有内存和寄存器操作数的推入,而不仅仅是立即数。这就是push dword [mem]
不可编码的原因;在这种情况下,NASM将其视为实际上需要双字存储操作数。
QWORD推式立即数可以使用8位或32位立即数,两个符号均扩展为64。立即数的宽度与操作数大小(存储到内存的宽度和数量)分开从RSP中减去)。再次,看到链接的问题。