试图将“变量”推入堆栈

时间:2018-08-28 12:53:42

标签: windows variables assembly stack x86-64

我有以下代码:

[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

2 个答案:

答案 0 :(得分:3)

代替

PUSH DWORD [r8+(var)]

使用

PUSH QWORD [r8+(var)]

因为压入堆栈的所有单词都是qword。

答案 1 :(得分:2)

NASM语法push DWORD 0xFFFF是双字的push的双字,当以64位模式进行汇编时,其符号扩展为qword。

IDK为什么NA​​SM和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中减去)。再次,看到链接的问题。