如何基于现有X8086汇编代码实现大数字的乘除运算?
8086汇编:五位输入数字的乘除运算实现
先修正输入代码的溢出问题
原代码中num1、num2定义为dw(16位),但五位数字最大值99999超过16位寄存器上限65535,会导致输入时溢出错误。需将变量改为dd(32位),并调整输入逻辑使用32位运算:
;TITLE Multiply/Divide 5-digit numbers .model small .stack 100 .data msg1 DB 13,10,"First input = $" ;提示输入第一个数 msg2 DB 13,10,"Second input = $" ;提示输入第二个数 msg3 DB 13,10,"Result = $" ;提示结果 num1 dd ? ;32位变量存储第一个五位数字 num2 dd ? ;32位变量存储第二个五位数字 a dw 10000 b dw 1000 c db 100 d db 10 .code main proc mov ax, @data mov ds, ax ; 输入第一个五位数字到num1 mov ah, 9h lea dx, msg1 int 21h xor bx, bx ; bx清零,临时存储低16位结果 xor dx, dx ; dx清零,临时存储高16位结果 mov ah, 1h int 21h sub al, 30h mov cl, al mov ax, a ; ax=10000 mul cl ; ax=数字*10000 mov bx, ax ; 暂存低16位 mov ah, 1h int 21h sub al, 30h mov cl, al mov ax, b ; ax=1000 mul cl ; ax=数字*1000 add bx, ax ; 累加到低16位 adc dx, 0 ; 处理进位到高16位 mov ah, 1h int 21h sub al, 30h mov cl, al mov al, c ; al=100 mul cl ; ax=数字*100 add bx, ax adc dx, 0 mov ah, 1h int 21h sub al, 30h mov cl, al mov al, d ; al=10 mul cl ; ax=数字*10 add bx, ax adc dx, 0 mov ah, 1h int 21h sub al, 30h add bl, al adc bh, 0 adc dx, 0 mov word ptr num1, bx ; 存储低16位 mov word ptr num1+2, dx ; 存储高16位 ; 复制上述代码可输入第二个数到num2 ; ...
一、无符号乘法实现
两个五位数字相乘的最大结果为99999×99999=9999800001,需用64位存储(拆分为两个32位变量result_high和result_low)。利用8086的mul指令分步计算:
.data result_high dd ? result_low dd ? .code ; 拆分num1为高、低16位 mov ax, word ptr num1 mov dx, word ptr num1+2 ; 拆分num2为高、低16位 mov bx, word ptr num2 mov cx, word ptr num2+2 ; 低16位×低16位 → dx:ax mul bx mov word ptr result_low, ax mov word ptr result_low+2, dx ; 低16位×高16位 → dx:ax mov ax, word ptr num1 mul cx add word ptr result_low+2, ax adc word ptr result_high, dx ; 高16位×低16位 → dx:ax mov ax, word ptr num1+2 mul bx add word ptr result_low+2, ax adc word ptr result_high, dx ; 高16位×高16位 → dx:ax mov ax, word ptr num1+2 mul cx add word ptr result_high, ax adc word ptr result_high+2, dx
二、无符号除法实现
以num1 ÷ num2为例,被除数和除数均为32位,需通过逐位比较减法实现多字节除法:
.data quotient dd ? remainder dd ? .code mov cx, 32 ; 循环32次处理32位数据 xor ax, ax xor dx, dx ; dx:ax作为临时余数寄存器 mov bx, word ptr num2 mov si, word ptr num2+2 ; bx:si=除数num2 mov di, word ptr num1 mov bp, word ptr num1+2 ; di:bp=被除数num1 div_loop: shl di, 1 rcl bp, 1 rcl ax, 1 rcl dx, 1 ; 被除数左移一位,移入余数寄存器 ; 比较余数dx:ax与除数bx:si cmp dx, si jb skip_sub je check_low ja do_sub check_low: cmp ax, bx jb skip_sub do_sub: sub ax, bx sbb dx, si ; 余数减去除数 inc di ; 商的对应位设为1 skip_sub: loop div_loop mov word ptr quotient, di mov word ptr quotient+2, bp mov word ptr remainder, ax mov word ptr remainder+2, dx
内容的提问来源于stack exchange,提问作者Niloofar Nazemi
相关产品推荐
相关产品推荐

