王爽老师《汇编语言》第3版,第10章的实验10 编写子程序,第2个子程序---解决除法溢出的问题:
名称:divdw
功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
参数:(ax)=dword 型数据的低16位
(dw)=dword型数据的高16位
(cx)=除数
返回:(dx)结果高16位,(ax)结果低16位
(cx)=余数
给出公式:
X/N = int(H/N) * 65536 + [rem(H/N) * 65536 + L]/N
X: 被除数 dword, [0, FFFFFFFF]
N:除数 word, [0, FFFF]
H:X的高16位 word, [0, FFFF]
L:X的低16位 word, [0, FFFF]
int(H/N): H/N的商
rem(H/N): H/N的余数
分析:
1、H/N 商为 (AX), 余数为(DX),则 int(H/N) = (AX), rem(H/N) = (DX)
2、因为 2的16次方 = 65536 --> int(H/N) * 65536 为int(H/N)往左移动16位二进制位,即往左移动一个word
而int(H/N) = (AX), 所以,int(H/N) * 65536 = (AX) 00H ;同理,可以得出 rem(H/N) * 65536 = (DX) 00H
3、rem(H/N) * 65536 + L = (DX) 00H + L = (DX) L 那么, [rem(H/N) * 65536 + L)/N 相当于 (DX) L / N
只要 AX <-- L, 做除法div即可,结果 商为(AX),余数为(DX)送入CX 作为整个表达式的余数
4、整个表达式的加法就转变成 (DX) 00H + (AX) = (DX)(AX) 了
根据以上分析写出程序:
1 assume cs:codesg
2
3 codesg segment
4 start: mov ax, 4240H
5 mov dx, 000FH
6 mov cx, 0AH
7 call divdw
8
9 mov ax, 4c00H
10 int 21H
11
12 ;(dx, ax)/cx
13 ;@param dx-H, ax-L, cx-N
14 ;@return dx-hi, ax-lo, cx-
15 divdw: push bx
16 ;H/N
17 mov bx, ax ;L
18 mov ax, dx
19 mov dx, 0
20 div cx ;shang-int(H/N)-ax, yu-rem(H/N)-dx
21 push ax ;int(H/N)
22
23 ;int(H/N)*65536
24 ;ax00
25
26 ;[rem(H/N)*65536+L]/N
27 ;dx bx
28 mov ax, bx
29 div cx
30 mov cx, dx ;yu
31
32 ;int(H/N)*65536 + [rem(H/N)*65536+L]/N
33 ;dx00 + ax = dxax
34 pop dx
35 pop bx
36 ret
37
38 codesg ends
39 end start
总结:此题关键是乘法左移