x86 程序集:除以 11 的除法浮点异常
x86 Assembly: Division Floating Point Exception dividing by 11
我试图用 859091
除以 11
以获得商和余数,但我在网上收到浮点异常:
div bx
这是我的 SASM 代码:
%include "io.inc"
section .data
dividend dd 859091
divisor dw 11
section .text
global CMAIN
CMAIN:
push ebp
mov ebp, esp
xor eax, eax
xor ebx, ebx
xor edx, edx
mov ax, word [dividend]
mov dx, word [dividend + 2]
mov bx, word [divisor]
test bx, bx
jz exit
div bx
exit:
leave
ret
除法溢出是因为商不适合 16 位整数。
您可以将被除数分成上半部分和下半部分,以产生最多 32 位的商和 16 位的余数。 dx = 0000 : ax = upper_dividend / divisor
的余数成为第2次被除数的上半部分,所以第2次除法计算dx = remainder : ax = lower_dividend / divisor
,两者都不会溢出,因为余数严格小于除数。这个过程可以扩展到更长的被除数和商数,每个被除数和商的单词一步,每个除法步骤的剩余部分成为下一步的部分被除数的上半部分。
使用 MASM 语法的示例:
dvnd dd 859091
dvsr dw 11
; ...
; bx:ax will end up = quotient of dvnd/dvsr, dx = remainder
mov di,dvsr
xor dx,dx
mov ax,word ptr dvnd+2 ;ax = upr dvnd
div di ;ax = upr quot, dx = rmdr
mov bx,ax ;bx = upr quot
mov ax,word ptr dvnd ;ax = lwr dvnd
div di ;ax = lwr quot, dx = rmdr
四字示例:
dvnd dq 0123456789abcdefh
dvsr dw 012h
quot dq 0
rmdr dw 0
; ...
mov di,dvsr
xor dx,dx ;dx = 1st upr half dvnd = 0
mov ax,word ptr dvnd+6 ;ax = 1st lwr half dvnd
div di ;ax = 1st quot, dx = rmdr = 2nd upr half dvnd
mov word ptr quot+6,ax
mov ax,word ptr dvnd+4 ;ax = 2nd lwr half dvnd
div di ;ax = 2nd quot, dx = rmdr = 3rd upr half dvnd
mov word ptr quot+4,ax
mov ax,word ptr dvnd+2 ;ax = 3rd lwr half dvnd
div di ;ax = 3rd quot, dx = rmdr = 4th upr half dvnd
mov word ptr quot+2,ax
mov ax,word ptr dvnd ;ax = 4th lwr half dvnd
div di ;ax = 4th quot, dx = rmdr
mov word ptr quot,ax
mov rmdr,dx
我试图用 859091
除以 11
以获得商和余数,但我在网上收到浮点异常:
div bx
这是我的 SASM 代码:
%include "io.inc"
section .data
dividend dd 859091
divisor dw 11
section .text
global CMAIN
CMAIN:
push ebp
mov ebp, esp
xor eax, eax
xor ebx, ebx
xor edx, edx
mov ax, word [dividend]
mov dx, word [dividend + 2]
mov bx, word [divisor]
test bx, bx
jz exit
div bx
exit:
leave
ret
除法溢出是因为商不适合 16 位整数。
您可以将被除数分成上半部分和下半部分,以产生最多 32 位的商和 16 位的余数。 dx = 0000 : ax = upper_dividend / divisor
的余数成为第2次被除数的上半部分,所以第2次除法计算dx = remainder : ax = lower_dividend / divisor
,两者都不会溢出,因为余数严格小于除数。这个过程可以扩展到更长的被除数和商数,每个被除数和商的单词一步,每个除法步骤的剩余部分成为下一步的部分被除数的上半部分。
使用 MASM 语法的示例:
dvnd dd 859091
dvsr dw 11
; ...
; bx:ax will end up = quotient of dvnd/dvsr, dx = remainder
mov di,dvsr
xor dx,dx
mov ax,word ptr dvnd+2 ;ax = upr dvnd
div di ;ax = upr quot, dx = rmdr
mov bx,ax ;bx = upr quot
mov ax,word ptr dvnd ;ax = lwr dvnd
div di ;ax = lwr quot, dx = rmdr
四字示例:
dvnd dq 0123456789abcdefh
dvsr dw 012h
quot dq 0
rmdr dw 0
; ...
mov di,dvsr
xor dx,dx ;dx = 1st upr half dvnd = 0
mov ax,word ptr dvnd+6 ;ax = 1st lwr half dvnd
div di ;ax = 1st quot, dx = rmdr = 2nd upr half dvnd
mov word ptr quot+6,ax
mov ax,word ptr dvnd+4 ;ax = 2nd lwr half dvnd
div di ;ax = 2nd quot, dx = rmdr = 3rd upr half dvnd
mov word ptr quot+4,ax
mov ax,word ptr dvnd+2 ;ax = 3rd lwr half dvnd
div di ;ax = 3rd quot, dx = rmdr = 4th upr half dvnd
mov word ptr quot+2,ax
mov ax,word ptr dvnd ;ax = 4th lwr half dvnd
div di ;ax = 4th quot, dx = rmdr
mov word ptr quot,ax
mov rmdr,dx