我想要打印一个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指令做...
我想要打印一个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指令做...
有没有x86指令“打印”的值。显示输出需要操作系统特定的接口。在“经典”x86编程中,您将进行BIOS调用以生成输出到屏幕。在现代保护模式操作系统中,这将不再起作用。相反,您需要调用OS API函数来显示输出,例如,例如添加到与您的流程关联的控制台窗口。
调用该OS API的最简单和最通用的方法是将汇编程序与C标准库链接,以便您可以调用其printf
(及类似函数)函数。这只需要一个CALL
指令,它将控制权转移给printf
函数,执行它,并将控制权返回到代码中的以下指令。
但是,还有一个额外的复杂因素:您必须遵循相应的调用约定您的平台和标准库函数。你的问题没有提供你是否使用Windows,Linux或其他的线索。幸运的是,有关x86调用约定的详细信息可在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
伪指令,可以自动处理为你调用函数。查看您选择的汇编程序是否具有类似功能可能值得一试。
打印出来 - 如何?十进制,十六进制,二进制?你能想出如何在你选择的符号系统中打印单个字节值吗? – usr2564301
如果是十进制数,那么可以在这里检查一个例程:http://tw.wikipedia.org/wiki/Http://www.stackoverflow.com/a/41086442/4271923(顺便说一句,不要把整个例程放到宏中,它会在机器代码中为每个用法重复=>大二进制=>慢,而是使用'call'和子程序。) – Ped7g
我发现一个非常简单的方法: push ebx;低32位 push eax;高32位 推送偏移格式 call printf add esp,12;清除堆栈 格式为 格式DB“%lld”,0 – Crisan