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

求基于Intel 8086的64位双操作数四则运算完整程序

8086汇编实现64位四则运算完整程序

在8086这类16位处理器上,64位操作数需要拆分为4个连续的16位字(小端序存储:低地址存低16位,高地址存高16位)。以下是实现64位加、减、乘、除的完整汇编程序,包含测试逻辑。

核心运算子程序

1. 64位加法(带进位)

从低到高依次对每个16位字执行带进位相加,最终进位标志CF表示是否溢出。

; 输入:SI指向第一个64位操作数的低16位地址,DI指向第二个64位操作数的低16位地址
; 输出:结果覆盖第一个操作数的内存,CF=1表示加法溢出
add64:
    push ax
    push bx
    push cx

    mov cx, 4           ; 循环处理4个16位字
    clc                 ; 初始化进位标志为0
add_loop:
    mov ax, [di]
    adc [si], ax        ; 带进位相加
    inc si
    inc di
    loop add_loop

    pop cx
    pop bx
    pop ax
    ret

2. 64位减法(带借位)

从低到高依次对每个16位字执行带借位相减,CF标志表示结果是否为负(需取补码还原)。

; 输入:SI指向被减数低16位地址,DI指向减数低16位地址
; 输出:结果覆盖被减数内存,CF=1表示不够减(结果为负)
sub64:
    push ax
    push bx
    push cx

    mov cx, 4
    clc                 ; 初始化借位标志为0
sub_loop:
    mov ax, [di]
    sbb [si], ax        ; 带借位相减
    inc si
    inc di
    loop sub_loop

    pop cx
    pop bx
    pop ax
    ret

3. 64位乘法(结果为128位)

通过拆分64位操作数为4个16位字,模拟竖式乘法累加,最终得到128位结果。

; 输入:SI指向第一个64位操作数低16位,DI指向第二个64位操作数低16位,BX指向128位结果的低16位地址
; 输出:128位结果存入BX指向的内存区域
si_base dw 0
di_base dw 0
mul64:
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push bp

    mov bp, bx          ; 保存结果起始地址
    ; 初始化结果为0
    mov cx, 8
    mov bx, bp
init_res:
    mov word ptr [bx], 0
    add bx, 2
    loop init_res

    mov cx, 4           ; 遍历第一个数的4个16位部分
    mov si_base, si
x_loop:
    mov ax, [si]
    cmp ax, 0
    je x_next           ; 当前部分为0,跳过乘法
    mov di_base, di
    mov dx, 4           ; 遍历第二个数的4个16位部分
y_loop:
    mov bx, [di]
    mul bx              ; 16位乘法,结果存于DX:AX
    ; 计算结果的偏移位置
    mov bx, 8
    sub bx, cx
    sub bx, dx
    shl bx, 1
    add bx, bp
    ; 累加结果到对应位置,处理进位
    add [bx], ax
    adc [bx+2], dx
    adc [bx+4], 0
    adc [bx+6], 0
    adc [bx+8], 0
    adc [bx+10], 0
    adc [bx+12], 0
    adc [bx+14], 0

    add di, 2
    dec dx
    jnz y_loop
x_next:
    add si, 2
    dec cx
    jnz x_loop

    pop bp
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret

4. 64位除法(64位被除数÷64位除数)

通过循环左移余数并尝试减去除数的方式,模拟长除法,最终得到64位商和余数。

; 输入:SI指向被除数低16位,DI指向除数低16位,BX指向商的低16位地址,BP指向余数的低16位地址
; 输出:商存入BX指向内存,余数存入BP指向内存
di_divisor dw 0
div64:
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push bp

    ; 复制被除数到余数区域(初始余数=被除数)
    mov cx, 4
    mov si, offset num1
    mov di, offset remainder
copy_dividend:
    mov ax, [si]
    mov [di], ax
    add si, 2
    add di, 2
    loop copy_dividend

    ; 初始化商为0
    mov cx, 4
    mov di, offset quotient
init_quotient:
    mov word ptr [di], 0
    add di, 2
    loop init_quotient

    mov cx, 64          ; 循环处理64位
div_loop:
    ; 余数左移1位
    push cx
    mov cx, 4
    clc
    mov bp, offset remainder
shift_remainder:
    mov ax, [bp]
    rcl ax, 1
    mov [bp], ax
    add bp, 2
    loop shift_remainder
    pop cx

    ; 尝试减去除数
    push si
    push di
    mov si, offset remainder
    mov di, offset num2
    call sub64
    pop di
    pop si

    jnc set_bit         ; 无借位表示余数≥除数,商的当前位置1
    ; 有借位则恢复余数(加回除数)
    push si
    push di
    mov si, offset remainder
    mov di, offset num2
    call add64
    pop di
    pop si
    jmp next_bit
set_bit:
    mov di, offset quotient
    mov ax, [di]
    or ax, 1
    mov [di], ax
next_bit:
    ; 商左移1位
    push cx
    mov cx, 4
    clc
    mov bx, offset quotient
shift_quotient:
    mov ax, [bx]
    rcl ax, 1
    mov [bx], ax
    add bx, 2
    loop shift_quotient
    pop cx

    dec cx
    jnz div_loop

    pop bp
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret

完整测试程序

stack   segment stack
        dw 100h dup(?)
stack   ends

data    segment
; 测试数据:num1=0x0000000000000001,num2=0x0000000000000002
num1    dw 1, 0, 0, 0       ; 低16位到高16位依次存储
num2    dw 2, 0, 0, 0
result  dw 8 dup(0)         ; 128位乘法结果存储区
quotient dw 4 dup(0)        ; 除法商存储区
remainder dw 4 dup(0)       ; 除法余数存储区
msg_add db '64位加法完成', 0dh, 0ah, '$'
msg_sub db '64位减法完成', 0dh, 0ah, '$'
msg_mul db '64位乘法完成', 0dh, 0ah, '$'
msg_div db '64位除法完成', 0dh, 0ah, '$'
data    ends

code    segment
assume cs:code, ds:data, ss:stack

start:
    mov ax, data
    mov ds, ax

    ; 测试加法:num1 = num1 + num2
    mov si, offset num1
    mov di, offset num2
    call add64
    mov dx, offset msg_add
    mov ah, 09h
    int 21h

    ; 测试减法:num1 = num1 - num2(此时num1为3,减2得1)
    mov si, offset num1
    mov di, offset num2
    call sub64
    mov dx, offset msg_sub
    mov ah, 09h
    int 21h

    ; 测试乘法:num1 * num2 = 2,结果存入result
    mov si, offset num1
    mov di, offset num2
    mov bx, offset result
    call mul64
    mov dx, offset msg_mul
    mov ah, 09h
    int 21h

    ; 测试除法:num1(1)÷ num2(2),商0,余数1
    mov si, offset num1
    mov di, offset num2
    mov bx, offset quotient
    mov bp, offset remainder
    mov di_divisor, di
    call div64
    mov dx, offset msg_div
    mov ah, 09h
    int 21h

    ; 程序退出
    mov ah, 4ch
    int 21h

; 插入上述所有子程序
add64:
    push ax
    push bx
    push cx

    mov cx, 4           
    clc                 
add_loop:
    mov ax, [di]
    adc [si], ax        
    inc si
    inc di
    loop add_loop

    pop cx
    pop bx
    pop ax
    ret

sub64:
    push ax
    push bx
    push cx

    mov cx, 4
    clc
sub_loop:
    mov ax, [di]
    sbb [si], ax        
    inc si
    inc di
    loop sub_loop

    pop cx
    pop bx
    pop ax
    ret

si_base dw 0
di_base dw 0
mul64:
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push bp

    mov bp, bx          
    mov cx, 8
    mov bx, bp
init_res:
    mov word ptr [bx], 0
    add bx, 2
    loop init_res

    mov cx, 4           
    mov si_base, si
x_loop:
    mov ax, [si]
    cmp ax, 0
    je x_next           
    mov di_base, di
    mov dx, 4           
y_loop:
    mov bx, [di]
    mul bx              
    mov bx, 8
    sub bx, cx
    sub bx, dx
    shl bx, 1
    add bx, bp
    add [bx], ax
    adc [bx+2], dx
    adc [bx+4], 0
    adc [bx+6], 0
    adc [bx+8], 0
    adc [bx+10], 0
    adc [bx+12], 0
    adc [bx+14], 0

    add di, 2
    dec dx
    jnz y_loop
x_next:
    add si, 2
    dec cx
    jnz x_loop

    pop bp
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret

di_divisor dw 0
div64:
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push bp

    mov cx, 4
    mov si, offset num1
    mov di, offset remainder
copy_dividend:
    mov ax, [si]
    mov [di], ax
    add si, 2
    add di, 2
    loop copy_dividend

    mov cx, 4
    mov di, offset quotient
init_quotient:
    mov word ptr [di], 0
    add di, 2
    loop init_quotient

    mov cx, 64          
div_loop:
    push cx
    mov cx, 4
    clc
    mov bp, offset remainder
shift_remainder:
    mov ax, [bp]
    rcl ax, 1
    mov [bp], ax
    add bp, 2
    loop shift_remainder
    pop cx

    push si
    push di
    mov si, offset remainder
    mov di, offset num2
    call sub64
    pop di
    pop si

    jnc set_bit         
    push si
    push di
    mov si, offset remainder
    mov di, offset num2
    call add64
    pop di
    pop si
    jmp next_bit
set_bit:
    mov di, offset quotient
    mov ax, [di]
    or ax, 1
    mov [di], ax
next_bit:
    push cx
    mov cx, 4
    clc
    mov bx, offset quotient
shift_quotient:
    mov ax, [bx]
    rcl ax, 1
    mov [bx], ax
    add bx, 2
    loop shift_quotient
    pop cx

    dec cx
    jnz div_loop

    pop bp
    pop di
    pop si
    pop dx
    pop cx
    pop bx
    pop ax
    ret

code    ends
end start

注意事项

  • 上述程序默认处理无符号数,若需处理有符号数:减法后若CF=1,需对结果取补码;乘法/除法需先记录操作数符号,最终为结果添加对应符号。
  • 程序采用MASM语法,可通过MASM/TASM编译,在DOSBox或8086模拟器中运行。
  • 乘法结果为128位,需预留8个16位字的内存空间;除法的商和余数均为64位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:09:55