; 子程序:divdw
; 要求:进行不会除法溢出的除法运算,被除数为dword,除数为word,结果为dword
; 参数:(ax) = 被除数dword型的低16位
; (dx) = 被除数dword型的高16位
; (cx) = 除数
;
; 返回:(dx) = 结果的高16位
; (ax) = 结果的低16位
; (cx) = 余数
;
; 测试例子:1000000/10 (F4240h/0ah)
; mov ax, 4240h
; mov dx, 000Fh
; mov cx, 0ah
; call divdw
;
; 结果为:(dx) = 0001h, (ax) = 86a0h, (cx) = 0
;
; 公式:X/N = int(H/N) *65536 + [rem(H/N) *65536 + L ]/N
; int 为求整,rem为求余
;
; 公式的真正意思:
; 1、原来那个32位数的高16位除以除数(N),把得到的商做为最后结果商的高16位 int(H/N)*10000H ( 65536 = 2^16 )
; 2、把上面除法得到的余数左移16位再加上原来32位数的低16位([rem(H/N)*10000H+L])构成了一个新的32位然后用它再除以除数(N),会得到一个新的商和一个余数(均为16位的),
; 把余数作为结果的余数存入cx中,把商作为最后结果商的低16位存入ax中
assume cs:code, ds:data, ss:stack
data segment
db 16 dup(0)
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, stack
mov ss, ax
mov sp, 16
mov ax, data
mov ds, ax
mov ax, 4240h
mov dx, 000Fh
mov cx, 0ah
call divdw
mov ax, 4c00h
int 21h
divdw:
mov bx, ax ; 缓存ax——被除数的低16位
mov ax, dx ; ax = H, 被除数的高16位
mov dx, 0
div cx ; ax 为商,dx为余数 = rem(H/N) * 65536
push ax ; 结果的商,也就是最后要放在dx中的
mov ax, bx ; dx为 rem(H/N) * 65536, 为高16位,ax为低16位,再进行一次除法运算
div cx ; ax 为商——最后结果的低16位,dx为余数——为最后结果,应赋给cx
mov cx, dx
pop dx
ret
code ends
end start