实验10 编写子程序—2、解决除法溢出的问题

一、公式推导

在编写程序前首先需要理解公式是如何推导的。
在这里插入图片描述
如上图所示,我们首先需要理解除法运算是如何可以推导为该公式。
设一个十进制数:121作为被除数,除数为3,我们获取123/3的商及余数。

121/3=(120+1)/3=(10*12+1)/3=(10*4*3+10*0+1)/3
	 =10*4+(0*10+1)/3

可以发现,商为40,余数为1。
在设一个较为复杂的十进制数:12391,除数为4,我们获取12391/4的商及余数

12391/4=(12390+1)/4=(10*1239+1)/4
		=[10*(1228+11)+1]/4
		=[10*(4*307+11)+1]/4
		=[10*4*307+10*11+1]/4
		=10*307+(10*11+1)/4
		=3070+(111)/4
		=3070+(4*27+3)/4

可以看到,最后的商为3097,余数为3。假设X只右移一位,即进位1,可列出下列公式:

X/N=[10*X1+a]/N
	=[10*(X2+b)+a]/N
	=10*(X2/N)+(10*b+a)/N
	;其中,X1为右移后的最小可被10整除的数,X2为N的整数倍。

十进制中10作为进位,而16进制中,16作为进位,只需要把10改成16,公式依然成立。
我们设一个十六进制数0111,除数为3。右移一位变为011。设{x}为十六进制数的十进制表示。如下所示:

X/N=[16*{X1}+a]/N
	=[16*({X2}+b)+a]/N
	=16*({X2}/N)+(16*b+a)/N
	;其中,X1为右移后的最小可被16整除的数,X2为N的整数倍。
011H=17,17=15+2,故N=3,X1=011H,X2=0FH,b=2H,a=1H。
X/N=16*(0FH/3H)+(16*2H+1H)/3H
	=50H+(20H+1H)/3H
	=50H+(33/3)
	=50H+BH+0H

商为5BH,余数为0H。
当被除数X=a7a6a5a4a3a2a1a0时,右移n位,则乘以16n。由于寄存器ax,dx为16位寄存器,这里我们右移4位,能够保证寄存器不溢出。在这里插入图片描述
X/N=[164{X1}+a]/N
=[164
({X2}+b)+a]/N
=164*({X2}/N)+(164*b+a)/N
;其中,X1为右移4位后的最大可被164整除的数,X2为X1/N后得到的最大整数,b为X1/N的余数。a为低四位。
这里右移四位后实际上就是高4位的值,X2/N等价于int(H/N),a等价于L,b等价于rem(H/N)。

二、寄存器

ax存储商,dx存储余数,寄存器大小为2个字节。
1、首先,我们做高位的除法,此时被除数在2个字节范围内,故而不会发生除法溢出的问题。得到了高位除法运算后的商和余数。
2、再对低4位被除数做除法运算,得到了低位除法运算后的商。
3、现在需要考虑的是如何存储这些数据,并合成为最终结果。

三、思路

1、最终我们需要让dx寄存器存储高位的商,ax寄存器存储低位的商。第一次进行除法运算时,ax中实际存储的是高位的被除数,而商存储在ax中,余数存储在dx中。此时ax的值为int(H/N)
2、根据公式,我们需要让低4位被除数与高位的余数相加,然后与除数相除。此时进行的是32为除法运算,dx为高位,ax为低位。根据附录5的证明,此时并不会发生溢出。
3、运算结束后dx存储余数,ax存储商。
4、第一次存储的商与第二次存储的商相加,得到最终的结果。

四、程序

;关键代码
mov cx,N;(除数)
mov ax,H;(低位)
mov dx,L;(高位)
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax;第一次除法运算的商
pop ax
div cx
mov dx,dx;(余数)
mov dx,bx(第一次除法运算的商)
;此时dx ax为32位的商,cx为余数。

完整代码:

assume cs:code
stack segment
	db 8 dup(0)
stack ends
code segment

start:
	mov ax,stack
	mov ss,ax
	mov sp,16
	mov ax,4240H
	mov dx,000FH
	mov cx,10
	call divw
	mov ax,4c00h
	int 21h
divw:
	push ax	;低位入栈
	mov ax,dx	;16位被除数
	mov dx,0	;高位置为0
	div cx	;第一次除法运算	
	mov bx,ax	;第一次除法运算的商int(X/N)存入bx
	pop ax	;低位出栈
	div cx	;第二次除法运算
	mov cx,dx	;余数rem(X/N)*16^4存入cx,第二次除法运算得到的商存入低位寄存器ax
	mov dx,bx	;由于dx存储高位的商,等价于bx左移4位,即int(X/N)*16^4
	ret	;此时dx ax即为得到的商,cx为余数
	

code ends

end start 

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值