You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EMU8086中16位乘法32位结果的正确输出方法咨询

问题:EMU 8086中16位乘法结果的高低字合并输出错误

以下是我在EMU 8086中用于两个16位数字相乘的代码:

mov ax, [integerOp1]
mul [integerOp2]

mov resultHi, dx
mov resultLo, ax

;Integer -> ASCII

mov cx, 0       ; Count for digits in result
@IterateMulLo:       
cwd             ; Preventing Division Overflow
mov bx, 10

div bx          ; Dividing by 10 to get the digits of result as remainder

mov dh, 00h     ; Clearing dh so dx conatins just the digit

add dl, 30h     ; Converting digit in dl to ASCII

push dx         ; Pushing the ASCII to stack

inc cx          ; Increment digit count 

cmp ax, 0       ; Repeating process until quoteint reaches 0. i.e: no more digits left
jg @IterateMulLo

mov digitCount, cx  

mov ax, resultHi
@IterateMulHi:       
cwd             ; Preventing Division Overflow
mov bx, 10

div bx          ; Dividing by 10 to get the digits of result as remainder

mov dh, 00h     ; Clearing dh so dx conatins just the digit

add dl, 30h     ; Converting digit in dl to ASCII

push dx         ; Pushing the ASCII to stack

inc cx          ; Increment digit count 

cmp ax, 0       ; Repeating process until quoteint reaches 0. i.e: no more digits left
jg @IterateMulHi

mov digitCount, cx

jmp @Result

乘法指令mul [integerOp2]会将结果存储在DX(高字)和AX(低字)中。以十进制1234*1234为例,DX中的值为0017(十六进制),AX中的值为3C44(十六进制),合并后得到00173C44(十六进制)=1522756(十进制),这是正确结果。但我分别将这两个值入栈再弹出显示时,得到的结果是2315428(即DX的十进制值23加上AX的十进制值15428),结果错误。请问如何合并高低字以输出正确的结果?


解决方案

问题根源

你当前的代码是将低字(AX)和高字(DX)作为两个独立的16位整数分别转换为十进制,再将结果拼接,这相当于把高字的十进制数值直接放在低字的十进制数值前面,而非将DX:AX视为一个完整的32位整数处理,因此得到错误结果。

修正代码(适用于商≤16位的场景)

需要将DX:AX(或存储后的resultHi:resultLo)作为一个完整的32位无符号数来转换为ASCII,以下是修正后的转换部分代码:

; 乘法完成后,先保存32位结果到变量(可选)
mov resultHi, dx
mov resultLo, ax

; 32位整数转ASCII,结果入栈,CX为数字个数
mov cx, 0
mov bx, 10          ; 除数设为10
; 加载完整32位结果到DX:AX
mov ax, resultLo
mov dx, resultHi

@IterateWholeResult:
    div bx          ; DX:AX / 10,商存AX,余数存DX
    add dl, 30h     ; 余数转ASCII字符
    push dx         ; 入栈保存字符
    inc cx          ; 数字计数+1
    mov dx, 0       ; 清零DX,准备处理下一轮的商(AX为商的低16位)
    cmp ax, 0       ; 判断商是否为0
    jg @IterateWholeResult

mov digitCount, cx
jmp @Result

兼容超大数值的方案(避免除法溢出)

如果需要处理商超过16位的超大数值(如65535*65535的结果),上述直接使用div的方法会触发除法溢出,此时需要模拟32位除法:

; 乘法完成后保存结果
mov resultHi, dx
mov resultLo, ax

mov cx, 0
mov bx, 10

@IterateBigResult:
    push ax
    ; 先处理高16位
    mov ax, resultHi
    xor dx, dx
    div bx
    mov resultHi, ax ; 保存高16位的商
    mov ax, dx       ; 取高16位的余数
    shl ax, 16       ; 余数左移16位,和低16位合并
    pop ax
    add ax, resultLo ; 合并余数与原低16位
    div bx           ; 计算最终余数和低16位的商
    push dx          ; 余数转ASCII后入栈
    add dl, 30h
    inc cx
    mov resultLo, ax ; 更新低16位的商
    ; 判断整个32位商是否为0
    mov ax, resultHi
    or ax, resultLo
    jnz @IterateBigResult

mov digitCount, cx
jmp @Result

验证逻辑

以你的示例1234*1234=1522756为例,修正后的代码会将0017h:3C44h作为整体处理:

  1. 第一次除以10,余数6(ASCII '6')入栈,商为152275;
  2. 重复除以10,依次得到余数5、7、2、2、5、1,分别入栈;
  3. 最终弹出栈的顺序为1、5、2、2、7、5、6,组合后就是正确结果1522756。

内容的提问来源于stack exchange,提问作者MUHAMMAD AWAIS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:12:03