汇编器 8086 将 32 位数除以 16 位数

Assembler 8086 divide 32 bit number in 16 bit number

我试着把32位数除以16位数。 例如 10000000h 除以 2000h.According 我尝试做的设计除以 4 个右边的数字是除数,然后是 4 个左边的数字是除数。

这是我的代码:

.DATA 
num dd 10000000h
divisor dw 2000h 

result dd ? 
remainder dw ? 

.CODE
main:

mov ax,@DATA    
mov ds,ax 

xor dx,dx
mov cx ,word ptr divisor
mov bx,offset num
mov ax,[bx]
div cx

mov bx,offset result 
mov [bx],ax 
mov bx,offset num
mov ax,[bx+2]


mov ax,[bx+2]
div cx 
mov bx,offset result 
mov [bx+2],ax 

我的可变结果为零。不知道是分界线设计的问题还是小错。

使用16位div指令,需要将被除数的高16位放入dx,低16位放入ax。您已经为第一个 div 完成了后者,但是您将 dx 设置为 0,因此您最终计算出 0h/2000h,即 0.

相反,你想要这样的东西:

mov bx, offset num
mov ax, [bx]
mov dx, [bx+2]
mov cx, word ptr divisor
div cx

当然,这仅在结果适合 16 位时有效——如果不适合,div 指令将引发 #DE 异常。

下面的方法类似于在铅笔和纸上手写 division,div将 2 位分子乘以一位 divisor。例如 99/4:

    2 4    (quotient)
  -----
4 | 9 9
    8
    -
    1 9
    1 6
      -
      3    (remainder)

从 dx = 0 和 ax = 分子的高阶开始。在第一个 div 指令之后,dx 中的余数是第二个 divide 的分子高阶的剩余部分。只要 divisor 是 16 位值,就可以增强此方法以处理任何大小的分子和商。

num     dd      10000000h
dvsr    dw      2000h 
quot    dd      ?
rmdr    dw      ?
;       ...
        mov     cx,dvsr                ;cx = dvsr
        xor     dx,dx                  ;dx = 0
        mov     ax,word ptr [num+2]    ;ax = high order numerator
        div     cx                     ;dx = rem, ax = high order quotient
        mov     word ptr [quot+2],ax   ;store high order quotient
        mov     ax,word ptr [num]      ;ax = low  order numerator
        div     cx                     ;dx = rem, ax = low  order quotient
        mov     word ptr [quot],ax     ;store low  order quotient
        mov     word ptr [rmdr],dx     ;store remainder

答案1中写的代码是唯一准确的。我写了类似的代码,将 D1 除以 D2:

Function Div32Bit(D1:LongInt;D2:Word):LongInt; Assembler;

Asm
 LEA   SI,D1
 Mov   CX,[SS:SI]
 Mov   AX,[SS:SI+2]
{AX:CX contains number to divide by}
 Mov   BX,D2
{BX contains number that divide}
 XOr   DX,DX
 Div   BX
 XChg  AX,CX
 Div   BX
{CX:AX contains the result of division}
{DX contains the rest of division}
 Mov   DX,CX
{DX:AX contains the result of division and is the function's result}
End;

但是这种方法不能有效地划分两个有符号数。 要划分两个有符号数:

Function IDiv32Bit(D1:LongInt;D2:Integer):LongInt; Assembler;

Asm
 LEA   SI,D1
 Mov   CX,[SS:SI]
 Mov   AX,[SS:SI+2]
{AX:CX contains number to divide by}
 Cmp   AX,32768
 CmC
 SbB   SI,SI
 XOr   CX,SI
 XOr   AX,SI
 Sub   CX,SI
 SbB   AX,SI
{AX:CX contains the absolute value of the number to divide by}
 Mov   BX,D2
{BX contains number that divide}
 Cmp   BX,32768
 CmC
 SbB   DX,DX
 XOr   BX,DX
 Sub   BX,DX
{BX contains the absolute value of the number that divide}
 XOr   SI,DX
{SI contains the sign of division}
 XOr   DX,DX
 Div   BX
 XChg  AX,CX
 Div   BX
{CX:AX contains the absolute value of the result of division}
{DX contains the absolute value of the rest of division}
 XOr   AX,SI
 XOr   CX,SI
 Sub   AX,SI
 SbB   CX,SI
{CX:AX contains the result of division}
 Mov   DX,CX
{DX:AX contains the result of division and is the function's result}
End;