在汇编中进行除法时出现浮点异常(核心转储)
Posted
技术标签:
【中文标题】在汇编中进行除法时出现浮点异常(核心转储)【英文标题】:Floating Point Exception (Core Dumped) while doing division in assembly 【发布时间】:2013-06-24 03:05:35 【问题描述】:我正在尝试添加 2 个两位数,这必然会产生一个两位数或三位数。
这是我目前所拥有的,当我尝试打印进位时,它显示 Floating Point Exception (Core Dumped)
section .data
msg db "Enter 2 numbers: "
msgLen equ $-msg
section .bss
numa1 resb 1
numa2 resb 1
numb1 resb 1
numb2 resb 1
carry resb 1
section .text
global _start
_start:
;print message
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msgLen
int 80h
;accept first number (1st digit)
mov eax, 3
mov ebx, 0
mov ecx, numa1
mov edx, 1
int 80h
;accept first number (2nd digit)
mov eax, 3
mov ebx, 0
mov ecx, numa2
mov edx, 2
int 80h
;accept second number (1st digit)
mov eax, 3
mov ebx, 0
mov ecx, numb1
mov edx, 1
int 80h
;accept second number (2nd digit)
mov eax, 3
mov ebx, 0
mov ecx, numb2
mov edx, 2
int 80h
;character to number conversion
sub byte[numa1], 30h
sub byte[numa2], 30h
sub byte[numb1], 30h
sub byte[numb2], 30h
sub byte[carry], 30h
;;;;;;;;;;;;;;;;;;;;;;;;;;
;add ones digit
mov al, [numa2]
add byte[numb2], al
add byte[numb2], 30h
;get carry of sum of ones digit
mov ax, [numb2]
mov byte[carry], 10
div byte[carry]
mov eax, 4
mov ebx, 1
mov ecx, carry
mov edx, 1
int 80h
mov eax, 1
mov ebx, 0
int 80h
carry
numa1 numa2
+ numb2 numb2
---------------
numb2
where numb2 = numb2 % 10
carry = numb2 / 10
【问题讨论】:
这是什么操作系统? Linux? 是的,我忘了说对不起。 32位Linux 哪一行产生异常?引发异常的指令的参数是什么?请注意,某些指令有隐含的参数。 可能是On which platforms does integer divide by zero trigger a floating point exception? 和/或8086 assembly on DOSBox: Bug with idiv instruction? 的副本。 DIV 溢出 -> SIGFPE 【参考方案1】:首先,xor ebx, ebx
is shorter and faster than mov ebx, 0
另外,两个 1 位数字相加的最大进位为 1 (9 + 9 = 18),因此无需除法,只需将数字减去 10 即可。此外,您通常应该避免使用 16 位寄存器,因为它更长(由于 66h 前缀)和更慢(由于部分寄存器更新)。这意味着
mov ax, [numb2]
mov byte[carry], 10
div byte[carry]
会比下面慢很多
movzx eax, word ptr [numb2]
sub eax, 10
但毕竟,当 x86 已经有 BCD instructions 用于此目的时,为什么还要使用如此复杂的方式。此外,这些指令有 AF 和 CF 用于 BCD 数学进位,所以不需要你自己管理它
您也可以直接使用二进制数学,然后在输入/输出中进行转换。大多数情况下,转换成本可以忽略不计
【讨论】:
【参考方案2】:请注意“浮点异常”,但这些行可能会导致除法溢出:
mov ax, [numb2]
mov byte[carry], 10
div byte[carry]
您正在从numb2
移动到ax
,这意味着您将在ah
中获得存储在carry
的任何内容。如果我们假设.bss
部分在启动时为零,那么当您将carry
加载到ah
时,其值将是0xD0
,因为您已经完成了sub byte[carry], 30h
。
因此,您将 0xD0nn
除以 10,这将导致商太大而无法放入 al
。
您可以将mov ax, [numb2]
替换为movzx ax,byte [numb2]
。
【讨论】:
当然,sub byte[carry], 30h
本身是有问题的,应该是 mov byte[carry], 0
... 依靠 carry
进行零初始化通常是可以的,除非它不是' t,结果被扯头发,咬牙切齿……以上是关于在汇编中进行除法时出现浮点异常(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章