Floating Point Exception (Core Dumped) while doing division in assembly

女生的网名这么多〃 提交于 2020-01-03 06:34:44

问题


I'm trying to add 2 two-digit numbers which are bound to yield a two-digit or three-digit number.

Here's what I have so far, and when I try to print the carry, it says 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

回答1:


First, xor ebx, ebx is shorter and faster than mov ebx, 0

Also, adding two 1-digit numbers results in a maximum carry of 1 (9 + 9 = 18), so no need to divide, just subtracting the number by 10 is enough. Moreover you should generally avoid 16-bit registers, which is both longer (due to the 66h prefix) and slower (because of the partial register update). That means

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

will be much slower than the following

movzx eax, word ptr [numb2]
sub   eax, 10

But after all, why do you use such a complex way when x86 already has BCD instructions for that purpose. Besides, those instructions have AF and CF for BCD math carry so no need to manage it on your own

You can also use binary math directly and just convert them at input/output. Most of the case the cost of converting is negligible




回答2:


Note sure about the "Floating Point Exception", but these lines are likely to cause a division overflow:

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

You're doing a word move from numb2 to ax, which means that you'll get whatever was stored at carry in ah. If we assume that the .bss section is zeroed at startup, the value at carry will be 0xD0 when you load it into ah, since you've done sub byte[carry], 30h.

Hence, you're dividing 0xD0nn by 10, which will result in a quotient too large to fit in al.

You could replace mov ax, [numb2] with movzx ax,byte [numb2].



来源:https://stackoverflow.com/questions/17267472/floating-point-exception-core-dumped-while-doing-division-in-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!