2016-12-13 54 views
0

我想要打印一个qword(十进制)的宏。打印存储在eax中的qword:ebx x86

show_qd macro nr 
    lea edx,[nr] 
    mov eax,[edx] ;upper 32 bits 
    mov ebx,[edx+4] ;lower 32 bits 

    ;print code here; 

endm 

可悲的是,我无法弄清楚如何与x86指令做...

+2

打印出来 - 如何?十进制,十六进制,二进制?你能想出如何在你选择的符号系统中打印单个字节值吗? – usr2564301

+1

如果是十进制数,那么可以在这里检查一个例程:http://tw.wikipedia.org/wiki/Http://www.stackoverflow.com/a/41086442/4271923(顺便说一句,不要把整个例程放到宏中,它会在机器代码中为每个用法重复=>大二进制=>慢,而是使用'call'和子程序。) – Ped7g

+1

我发现一个非常简单的方法: push ebx;低32位 push eax;高32位 推送偏移格式 call printf add esp,12;清除堆栈 格式为 格式DB“%lld”,0 – Crisan

回答

0

有没有x86指令“打印”的值。显示输出需要操作系统特定的接口。在“经典”x86编程中,您将进行BIOS调用以生成输出到屏幕。在现代保护模式操作系统中,这将不再起作用。相反,您需要调用OS API函数来显示输出,例如,例如添加到与您的流程关联的控制台窗口。

调用该OS API的最简单和最通用的方法是将汇编程序与C标准库链接,以便您可以调用其printf(及类似函数)函数。这只需要一个CALL指令,它将控制权转移给printf函数,执行它,并将控制权返回到代码中的以下指令。

但是,还有一个额外的复杂因素:您必须遵循相应的调用约定您的平台和标准库函数。你的问题没有提供你是否使用Windows,Linux或其他的线索。幸运的是,有关x86调用约定的详细信息可在标记wiki中找到,可访问here。通常,32位调用约定将从右到左传递堆栈中的参数。而C标准库函数实际上总是调用者清理(即使在Windows中,其中被调用者清除约定是常见的),因此您负责在进行调用后清理堆栈。

因此,只是作为一个演示,这里是你会怎么称呼printf打印存储在EAX寄存器中的32位整数:

push eax     ; push 32-bit integer value from EAX onto stack 
push OFFSET strFormat  ; push pointer to format string onto stack 
call printf 
add esp, 8    ; clean up stack 

strFormat必须存储在您的可执行文件的DATA部分的字符串。格式字符串与C相同,因为它的功能完全相同。在这种情况下,它会将指针指向包含"%d"的字符串。

除了您的格式字符串是"%lld"(在C中使用long long类型,在x86-32上是64位)之外,打印64位值的内容大致相同。您需要遵循调用约定的规则,将64位整数参数传递给函数。这很可能只是将两个32位的数据压入堆栈。假设64位值规范地存储在EDX:EAX,代码如下:

lea edx, DWORD PTR [value] 
mov eax, DWORD PTR [edx] 
mov edx, DWORD PTR [edx+4] 

push edx 
push eax 
push OFFSET strFormat64 
call printf 

add esp, 12 

push edx     ; push upper 32 bits of 64-bit integer value onto stack 
push eax     ; push lower 32 bits of 64-bit integer value onto stack 
push OFFSET strFormat64  ; push pointer to format string onto stack 
call printf 
add esp, 12    ; clean up stack 

如果该值是在内存中,然后就可以像你在问题中显示使用代码

请注意,如果您将此实现为宏,它将会触发寄存器。确保这是明确记录的,还是保存并恢复宏内的寄存器 - 否则,当在代码中使用它时,最终会出现难以调试的问题!而且,根据您的调用约定,您可能需要确保堆栈已正确对齐,这在宏中很难做到干净利落。 MASM有一个INVOKE伪指令,可以自动处理为你调用函数。查看您选择的汇编程序是否具有类似功能可能值得一试。