由公式X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N(H为X的高十六位)(L为X的低十六位)可知:
int(H/N)*65536 为X/N的结果的高十六位
[rem(H/N)*65536+L]/N 为X/N的结果的低十六位及余数
如何实现int(H/N)*65536
H/N 为十六位除法
故可通过下面的程序段实现(被除数为H即X的高十六位)
push ax ;将ax中的值保存起来,其作用在下个程序段中说明
mov ax,dx
mov dx,0 ;dx与ax分别存储H的高十六位与低十六位
div cx ;cx中存放除数N
mov bx,ax
上述程序的结果: (AX)=int(H/N)
(DX)=rem(H/N)
如何实现[rem(H/N)*65536+L]/N
这里被除数为[rem(H/N)*65536+L],我们可以用dx与
ax分别存储其高十六位与低十六位,除数N存放在cx
中
故可通过下面的程序段实现
pop ax
div cx
为什么这里没有看到将[rem(H/N)*65536+L]的高十六位
放到DX中(rem(H/N)*65536为其高十六位,L为其低十
六位)哪:
由于在上一个程序段中rem(H/N)*65536已在DX中,所以
只需确定被除数的低十六位即L,而低十六位应存放在AX
中,所以会有这样一条命令即pop ax,这也就解释了第一
个程序段中push ax的作用
通过上面的程序段即可得到X/N的商与余数
但商的高十六位与低十六位并未在DX与AX中
余数也不在CX中
所以下面的程序就是将相应的数据放到相应的
寄存器中
mov cx,dx ;将X/N的余数放入CX中
mov dx,bx ;将X/N的结果的高十六位放入DX中
下面是该子程序的完整实现
divdw: push bx
push ax;将ax中的值保存起来,其作用在下个程序段中说明
mov ax,dx
mov dx,0 ;dx与ax分别存储H的高十六位与低十六位
div cx ;cx中存放除数N
mov bx,ax
pop ax
div cx
mov cx,dx ;将X/N的余数放入CX中
mov dx,bx ;将X/N的结果的高十六位放入DX中
pop bx
ret
下面是调用该子程序的实现
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,10H
mov ax,4241H
mov dx,000fH
mov cx,0AH
call divdw
mov ax,4c00H
int 21H
divdw: push bx
push ax;将ax中的值保存起来,其作用在下个程序段中说明
mov ax,dx
mov dx,0 ;dx与ax分别存储H的高十六位与低十六位
div cx ;cx中存放除数N
mov bx,ax
pop ax
div cx
mov cx,dx ;将X/N的余数放入CX中
mov dx,bx ;将X/N的结果的高十六位放入DX中
pop bx
ret
code ends
end start