我尝试将16位数除以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
我在变量结果中得零。不确定是否存在划分设计的问题或只是一点点错误。
答案 0 :(得分:4)
使用16位div
指令,您需要将被除数的高16位置于dx
和ax
的低16位。您已为第一个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异常。
答案 1 :(得分:3)
下面的方法类似于铅笔和纸上的长手划分,将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
答案 2 :(得分:1)
答案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;