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

问题描述 投票:0回答:2

我正在尝试添加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
linux exception assembly x86 integer-division
2个回答
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用于此目的时,你会使用这种复杂的方式。此外,这些指令具有用于BCD数学运算的AF和CF,因此无需自行管理

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


0
投票

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

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]

© www.soinside.com 2019 - 2024. All rights reserved.