汇编语言:实验10 根据材料编程—2.解决除法溢出的问题

问题描述

用div做除法的时候可能产生除法溢出。由于有这样的问题,在进行除法运算的时候要注意除数和被除数的值,比如1000000/10就不能用div指令来计算。那么怎么办?我们用下面的子程序divdw解决

实验效果


实验要求

子程序描述

名称:divdw

功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。

参数:(ax)=dword型数据的低16位

     (dx)=dword型数据的高16位

     (cx)=除数

返回:(dx)=结果的高16位,(ax)=结果的低16位

(cx)=余数

数学公式说明

书上给出提示公式:X/N = int(H/N)*65536+[rem(H/N)*65536+L]/N,到底什么意思呢?刚开始博主也是一脸懵逼。

其实书上说了 int(H/N)表示取H/N的商,商用16位才能包的住,然后 int(H/N)*65536,并不是真正的将商*65536,65536=2^16,刚好表示将商往左移16位,H/N的商为X/N结果的高16位

[rem(H/N)*65536+L]/N 又是什么意思呢?rem(H/N)表示H/N的余数,然后右移16位 将原数据的低16位放到低位,构成32位的被除数!由于int(H/N)*65536铁定是整数且没有余数为X/N结果的高16位,那么结果的低16位和余数就在[rem(H/N)*65536+L]/N 中产生后半部分除法运算的结果作为X/N的低16位,余数作为X/N的余数

实验代码

;实验10 问题2 解决除法溢出的问题
;用div做除法的时候可能产生除法溢出。由于有这样的问题,在进行除法运算的时候要注意除数和被除数的值
;比如1000000/10就不能用div指令来计算。那么怎么办?我们用下面的子程序divdw解决。
assume cs:code

code segment
start:
	mov ax,4240h
	mov dx,000fh
	mov cx,0ah
	
	call divdw
	
	mov ax,4c00h
	int 21h
	;名称:divdw
	;功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
	;参数:(ax)=dword型数据的低16位
	;	(dx)=dword型数据的高16位
	;	(cx)=除数
	;返回:(dx)=结果的高16位,(ax)=结果的低16位
	;(cx)=余数
	;核心公式X/N = INT(H/N)*65536+[REM(H/N)*65536+L]/N
	;X:被除数,N(cx):除数,H(dx):X的高16位,L(ax):X的低16位
	divdw:
		push bx		;寄存器不够用,将bx拿来用
		
		
		push ax		;临时存放低16位(L)
		;计算 INT(H/N)*65536 32位除16位,商16位存放在AX中 是整个X/N结果的高16位,余数16位在DX中 刚好作为 [REM(H/N)*65536+L]的高16位
		mov ax,dx
		mov dx,0
		div cx			
		mov bx,ax	;不能直接放到dx中,后面还要用到dx
		
		
		;计算 [REM(H/N)*65536+L]/N,商16位存放AX中 刚好作为X/N结果的低位,余数16位放DX中-> 放到CX中去
		pop ax		;被除数低16位还原(L),刚好作为 [REM(H/N)*65536+L]的低16位
		div cx
		mov cx,dx	;余数16位放-> CX中去
		mov dx,bx	;将结果高16位放->DX中去
		
		
		pop bx		;还原bx
		ret
code ends
end start



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值