x86汇编(NASM):浮点异常,不除以0?

时间:2015-10-03 21:25:44

标签: assembly nasm

我试图计算表达式A * B + ( A + B ) / ( A - B ),其中A和B是用户输入的整数。我在Linux内核上使用ALong32库。

%include "along32.inc"

section .data
msg1    db      'Enter A: ', 0
msg2    db      'Enter B: ', 0
msg3    db      'Result: ' , 0
err     db      'Error: cannot divide by 0', 0
A       resb    4
B       resb    4

section .text

global main

main:
    mov     edx,    msg1
    call    WriteString
    call    ReadInt
    mov     [A],    eax  ; move the input into A

    mov     edx,    msg2
    call    WriteString
    call    ReadInt      ; move the next number into eax

    cmp     eax,    [A]  ; compare A and eax (B)

    je      error        ; if A and B are equal, error

    mov     [B],    eax  ; move eax into B 

    mov     eax,    [A]
    add     eax,    [B]
    mov     ebx,    eax ; ebx = A + B

    mov     eax,    [A]
    sub     eax,    [B] ; eax = A - B

    div     ebx        

    mov     ebx,    eax ; ebx = (A + B) / (A - B)

    mov     ecx,    [B]
    mov     eax,    [A]
    mul     ecx        
    mov     ecx,    eax ; ecx = A * B

    add     eax,    ecx ; eax = A * B + (A + B) / (A - B)

    mov     edx,    msg3
    call    WriteString
    call    WriteInt

    jmp end

error:
    mov     edx,    err
    call    WriteString
    jmp end

end:
    mov     eax,    1
    int     0x80

我觉得我已经评论过我做得很好,但是如果需要的话,我会解释我在做得更深入的事情。

当我运行此代码时,在输入两个数字后,我得到floating point exception,程序退出。

为什么会这样?我检查除以0。

1 个答案:

答案 0 :(得分:4)

我发现你的程序存在两个问题。

  • div ebx指令使用EDX:EAX作为被除数,但您无法设置它。只需插入xor edx,edx

    即可
    xor   edx, edx ; <--------------------------------- Add this !
    div   ebx        
    mov   ebx, eax ; ebx = (A + B) / (A - B)
    
  • 分割后你将商存储在EBX中,但你再也不会拿起它来显示结果!

    mov   ecx, [B]
    mov   eax, [A]
    mul   ecx
    mov   ecx, eax ; ecx = A * B
    mov   eax, ebx ; <--------------------------------- Add this !
    add   eax, ecx ; eax = A * B + (A + B) / (A - B)
    

第二个问题可以用更短的方式解决:

mov   ecx, [B]
mov   eax, [A]
mul   ecx
add   eax, ebx ; eax = A * B + (A + B) / (A - B)

编辑(迟到了,抱歉)

  

我检查除以0。

     

A * B +(A + B)/(A - B)

您已根据(A - B)对分隔符进行检查,如果A等于B则退出。
正确,但程序代码错误地计算(A - B) / (A + B),因此使用(A + B)作为分隔符!

这是我计算A * B + ( A + B ) / ( A - B )

的版本
mov     ebx, [A]
sub     ebx, [B]    ; EBX = (A - B)
jz      error       ; Guard against division by zero!

mov     eax, [A]
add     eax, [B]    ; EAX = (A + B)

xor     edx, edx    ; EDX:EAX = (A + B)
div     ebx         ; EAX = (A + B) / (A - B)

mov     ebx, [A]
imul    ebx, [B]    ; EBX = A * B

add     eax, ebx    ; EAX = A * B + (A + B) / (A - B)