【问题标题】:Assembler 8086 divide 32 bit number in 16 bit number汇编器 8086 将 32 位数除以 16 位数
【发布时间】:2017-10-02 02:18:47
【问题描述】:

我尝试将 32 位数除以 16 位数。 例如 10000000h 除以 2000h。根据我尝试做的设计,我除以 右边的 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 

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

【问题讨论】:

  • 您期望结果的大小是多少?你想要一个 32 位的结果(打包到,例如dx:ax)?或者只是一个容易溢出的 16 位结果?
  • 32 位结果。我没有注意到结果只有 16 位我想给结果 16 位,其余的另一个 16 位参数
  • benz,您的问题有两个答案,您应该通过单击灰色复选标记✔(在答案的左上角)来接受答案。
  • @benz - 您需要先除左 4 位(高 16 位),然后再除右 4 位(低 16 位)。我在回答中解释了这一点。

标签: assembly x86 division x86-16


【解决方案1】:

使用 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 异常。

【讨论】:

  • 对不起,我不清楚我想得到余数,结果可能大于 16 位。
  • @benz - 余数为
  • 如果结果不合适,div 会引发 #DE 执行。 div 的手册说:“CF、OF、SF、ZF、AF 和 PF 标志未定义”在 div 之后(无论是否引发异常)。无法禁用异常并获得包装 32b/16b => 16b 商 & 余数。 (这与除数 = 0 的行为完全相同。)
【解决方案2】:

下面的方法类似于铅笔和纸上的长手除法,将 2 位数的分子除以一位数的除数。例如 99/4:

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

从 dx = 0 和 ax = 分子的高阶开始。在第一个 div 指令之后,dx 中的余数是用于第二个除法的分子高位的剩余部分。只要除数是 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

【讨论】:

  • 如果没有解释代码的作用和作用,代码转储不是有用的答案。
  • @CodyGray - 当我试图包含 cmets 时,论坛卡住了。现已修复。
【解决方案3】:

答案 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2011-08-06
    • 2017-03-11
    • 2014-01-09
    • 2012-11-07
    • 2019-08-24
    相关资源
    最近更新 更多