assembly - x86 程序集 (NASM) : Floating Point Exception, 未除以 0?

标签 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。

最佳答案

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

  • 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)
    

    编辑 (晚了,抱歉)

    I check for division by 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)
    

    关于assembly - x86 程序集 (NASM) : Floating Point Exception, 未除以 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32927651/

    相关文章:

    assembly - 计算偏移量

    assembly - 当您写入标签时,Assembly 是否会创建内存位置?

    c - 哪种机制知道程序的入口点是main()

    assembly - 如何从汇编中的地址加载单个字节

    assembly - 使用 nasm 将 64 位指令组装成原始机器码

    assembly - 使用自己的键盘中断 `int 09h` 处理程序时代码的奇怪行为(损坏的绘制)

    assembly - bx lr在ARM汇编语言中做什么?

    c - 为什么 gcc 为我展开的循环结语生成的代码看起来过于复杂?

    linux - 使用 NASM 将数字写入文件

    c - 如何在 Debian 上编译 DOS 程序?