浮点异常(Core Dumped)在汇编时进行除法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浮点异常(Core Dumped)在汇编时进行除法相关的知识,希望对你有一定的参考价值。

我正在尝试添加2个两位数的数字,这些数字必然会产生两位数或三位数。

这是我到目前为止所做的,当我尝试打印进位时,它表示浮点异常(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
答案

首先,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用于此目的时,你会使用这种复杂的方式。此外,这些指令具有用于BCD数学运算的AF和CF,因此无需自行管理

您也可以直接使用二进制数学,只需在输入/输出处转换它们。大多数情况下,转换成本可以忽略不计

另一答案

请注意“浮点异常”,但这些行可能会导致除法溢出:

mov ax, [numb2]
mov byte[carry], 10
div byte[carry]

你正在做一个从numb2ax的单词,这意味着你将获得carry中存储在ah的任何东西。如果我们假设.bss部分在启动时归零,那么当你加载到carry0xD0的值将是ah,因为你已经完成了sub byte[carry], 30h

因此,你将0xD0nn除以10,这将导致商数太大而无法适应al

你可以用mov ax, [numb2]替换movzx ax,byte [numb2]

以上是关于浮点异常(Core Dumped)在汇编时进行除法的主要内容,如果未能解决你的问题,请参考以下文章

汇编 - 收到浮点异常

core dumped问题查找以及使用gdbQT下gdbserver使用

Linux程序Segmentation fault (core dumped)

Segmentation Fault(core dumped) 使用链表进行队列操作

什么是 core dump ? 以及 core dumped 的调试

C+11编译调用PCL库时出现segmentation fault(core dumped)错误