汇编器 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;
我试着把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;