公式 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

总结:此题关键是乘法左移

原文地址:https://www.cnblogs.com/vsignsoft/p/8550112.html