公式 X/N = int(H/N) * 65536 + [rem(H/N) * 65536 + L]/N 的运用
王爽老师《汇编语言》第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
总结:此题关键是乘法左移