x86 程序集 (NASM):浮点异常,不能除以 0?

Tet*_*ure 4 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

Sep*_*and 5

我看到你的程序有两个问题。

  • div ebx指令使用 EDX:EAX 作为被除数,您设置失败。只需插入一个xor edx,edx

    xor   edx, edx ; <--------------------------------- Add this !
    div   ebx        
    mov   ebx, eax ; ebx = (A + B) / (A - B)
    
    Run Code Online (Sandbox Code Playgroud)
  • 除法后,您将商存储在 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)
    
    Run Code Online (Sandbox Code Playgroud)

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

mov   ecx, [B]
mov   eax, [A]
mul   ecx
add   eax, ebx ; eax = A * B + (A + B) / (A - B)
Run Code Online (Sandbox Code Playgroud)

编辑(迟到,抱歉)

我检查除以 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)
Run Code Online (Sandbox Code Playgroud)