当在汇编中对32位数字进行乘法时,结果将被放入EDX:EAX组合中。结果的上半部分进入EDX,下半部分进入EAX。如果EDX和EAX都有结果的两部分,我如何使用Irvine32位库将这些值打印到屏幕上?请参阅示例代码和注解:
.386
.model flat, stdcall
.stack 4096
ExitProcess proto, dwExitCode:dword
include Irvine32.inc
.data
num1 dword 1000000
num2 dword 1000000
temp dword ?
full_result qword ?
.code
main proc
mov eax, num1
mul num2 ;Result will be put in EDX:EAX (Upper half of number and Lower half of number)
;EDX has the value 232 in decimal. 000000E8 in hex
;EAX has the value 3567587328 in decimal. D4A51000 in hex
;When you put these numbers togather, you get 000000E8D4A51000 in hex.
;When you convert these numbers back to its decimal representation, we get the correct value of 1000000000000
;How to display the result into the screen using Irvine32 library (not 64)
mov temp, eax
mov eax, edx ;Put the upper half of result in eax
call WriteDec ;Write the value in eax
mov eax, temp ;Put the lower half of result in eax
call WriteDec
;This will prints out 2323567587328 instead of 1000000000000
invoke ExitProcess, 0
main endp
end main
有没有办法把这个数字2323567587328转换成不同的形式,这样我就可以正确地显示上半部分和下半部分?(打包BCD等。)
如果无法将这个数字格式化为1000000000000,那么请告诉我如何将这个值赋给full_result
qword类型变量。
1条答案
按热度按时间iyfjxgzm1#
此
mul
指令在EDX:EAX中生成一个 * 无符号 * 64位乘积。下面的代码将EDX:EAX中的 unsigned 64位数字转换为十进制表示。然后可以使用Irvine的
WriteString
函数输出字符串。转换EDX:EAX中的 unsigned 64位数
在x86上,需要2个除法的级联来将EDX:EAX中的64位值除以10。
第一次除法除以高被除数(用0扩展)得到一个高商。第二次除法除以低被除数(用第一次除法的余数扩展)得到一个低商。我们将第二次除法的余数保存在堆栈中。
为了检查EDX:EAX中的qword是否为零,我在临时寄存器中对两个半部分进行了OR运算。
我选择在堆栈上放置一个sentinel,而不是计数数字,因为这个sentinel得到一个值(10),没有数字可以得到([0,9]),它很好地允许确定存储循环何时必须停止。
转换EDX:EAX中的 * 有符号 * 64位数
程序如下:
首先通过测试符号位来确定有符号数是否为负。
如果是,则对数字求反并输出一个“-”字符。
代码段的其余部分与无符号数相同。
上面的代码片段基于我的16位Q/A Displaying numbers with DOS。你也可以阅读一些额外的解释...
当你不关心字符串总是从相同的已知地址开始时的替代方法
这个版本更短更快。