(2)解决除法溢出的问题
问题的精髓在于理解
X / N = int(H / N) * 65536 + [rem( H / N) * 65536 + L] / N
H / N 有什么特点?最大的特点就是它的余数不能被N整除。这有什么意义?我们来看看除法的过程。
大家思考一下这个简单的除法,1位高位,20位低位。H / N想要继续除法,必须要借位对吧。也就是说(H % N) * 10 + 20 除以3的结果肯定是两位数可以容纳的。同理,对于十六进制呢?我们可以将32位的被除数,分成上图中的高、低16位。那么便有
X / N = H / N * 65536 + ((H % N) * 65536 + L) / N
X % N = ((H % N) * 65536 + L) % N
那么除法的商为32位
AX = ((H % N) * 65536 + L) / N
DX = H / N
余数
CX = ((H % N) * 65536 + L) % N
最终代码:
assume cs:code
code segment
start:
mov ax,4240h
mov dx,000fh
mov cx,0ah
call divdw
mov ax,4c00h
int 21h
divdw:
push ax ;需要先计算H / N
mov ax,dx
mov dx,0 ;将高位置为0
div cx ;计算H / N, 此时ax存放H / N(高16位商), dx存放 H % N(高16位余数)
mov bx,ax ;保存 H / N(商)
pop ax
div cx ;此时 ax为低16值, dx为高16的商 ,那么就是计算((H % N) * 65536 + L) / N
;计算完成之后将商保存在ax,余数存放在dx
mov cx,dx ;将dx的余数转存cx
mov dx,bx ;将bx中的高16位商存到dx
ret
code ends
end start