如何用Irvine32库打印汇编中EDX:EAX的乘法结果
32位乘法结果(EDX:EAX)的正确打印与QWORD变量赋值
问题背景
32位无符号乘法(mul指令)的结果会存储在EDX:EAX组合寄存器中,EDX存高32位,EAX存低32位。直接分别打印EDX和EAX的十进制值并拼接,会得到错误结果(如示例中得到2323567587328而非正确的1000000000000),因为这并非数值上的组合,而是简单的字符串拼接。
一、将EDX:EAX赋值给QWORD类型变量full_result
QWORD是8字节(64位)变量,低4字节对应EAX,高4字节对应EDX,直接分两次存储即可:
; 乘法执行后,EDX:EAX存结果 mov dword ptr full_result, eax ; 将低32位存入full_result的低4字节 mov dword ptr full_result+4, edx ; 将高32位存入full_result的高4字节
执行后full_result就完整存储了EDX:EAX表示的64位数值。
二、正确打印EDX:EAX的方法
Irvine32库没有内置的64位无符号十进制打印函数,需要手动实现64位转十进制的逻辑,以下是两种可行方案:
方法1:手动实现64位无符号十进制打印
核心思路是对EDX:EAX表示的64位数值反复除以10,取余数得到每一位数字,最后逆序打印:
.data digit_buffer byte 20 dup(0) ; 存储十进制数字的缓冲区(最多20位) .code PrintEDXEAX proc mov esi, offset digit_buffer mov ecx, 0 ; 计数器,记录数字位数 next_div: ; EDX:EAX 除以 10,商存回EDX:EAX,余数存EDX(实际是DL) mov ebx, 10 div ebx ; div ebx 会把EDX:EAX除以EBX,商在EAX,余数在EDX add dl, '0' ; 余数转ASCII字符 mov [esi], dl inc esi inc ecx ; 判断商是否为0(EDX和EAX都为0时停止) or eax, eax jnz next_div or edx, edx jnz next_div ; 逆序打印缓冲区中的数字 print_digits: dec esi mov al, [esi] call WriteChar loop print_digits ret PrintEDXEAX endp
使用时,在乘法执行后直接调用:
mul num2 call PrintEDXEAX ; 正确打印1000000000000
方法2:通过压缩BCD转换打印
压缩BCD是用每个字节存储两位十进制数字的格式,步骤如下:
- 将EDX:EAX的二进制值转换为压缩BCD格式(需通过
mul指令配合BCD调整指令实现,需额外处理64位数值的拆分逻辑) - 从高位到低位逐字节提取BCD数字,转换为ASCII后打印。
不过这种方法实现复杂度高于手动除法,对于无符号64位数值,手动除法的方式更直观易用。
内容的提问来源于stack exchange,提问作者Justin k
相关产品推荐
相关产品推荐

