Исключения с плавающей запятой в сборке NASM x86 с использованием инструкции div

У меня есть задание, в котором я должен ввести число и вычислить все простые числа до этого числа, но не превышая его. Например, если я ввел 9 в программу, она должна напечатать 3, 5 и 7.

Мой план определить, является ли число простым или нет, состоит в том, чтобы разделить его на 2 и проверить, равен ли остаток 0. Если остаток равен 0, программа вычитает 1 из делимого и возвращается к вершине, чтобы разделить снова. Если остаток! = 0, он выводит его на экран и снова уменьшает делимое. Это происходит до тех пор, пока дивиденд не станет 0. Только это не то, что происходит, по какой-то причине, когда я использую инструкцию DIV, я всегда получаю исключения с плавающей запятой, и я не могу понять, почему и как это решить. У кого-нибудь есть идеи, как я могу это исправить?

    Code: %INCLUDE      "csci224.inc"

    SEGMENT .data
    prompt:     DD      "Please enter a number: ",0     ; prompt string 
    message:    DD      " is prime.", 0                 ; displays when n is prime
    invalid:    DD      "Invalid entry.", 0
    i:          DD      2                               

    SEGMENT .bss
    input:      RESD    100         ; not really necessary, ignore this

    SEGMENT .text
    main:

    mov     edx, prompt
    call    WriteString

    call    ReadInt

    mov     esi, eax                ; move eax into esi to use as index for loop

    myloop:

    xor     edx, edx                ; clear registers
    xor     ecx, ecx
    xor     eax, eax

    mov     eax, dword 2            ; mov 2 to eax
    div     ecx                     ; ecx/eax | n/2

    dec     esi                     ; decrement loop counter
    dec     ecx                     ; decrement numerator

    cmp     edx, dword 0            ; is remainder zero?
    je      myloop                  ; YES - not prime - jump back to top

    mov     eax, edx                ; NO  - move to eax and print
    call    WriteInt
    call    Crlf

    cmp     esi, 0                  ; is counter zero?
    jz      finished                ; YES - end loop

    jmp     myloop                  ; NO  - loop again

finished:
    ret

person Slavic_Donut    schedule 17.10.2013    source источник


Ответы (1)


В этой части вашего кода:

xor     ecx, ecx                ; Clears ecx (set to 0)
xor     eax, eax                ; Clears eax (set to 0)

mov     eax, dword 2            ; Sets eax to 2
                                ; NOTE: you had just set it to 0 in the prior step)

; PROBLEM; the following code computes eax/ecx, which is 2/0 - the comment is wrong

div     ecx                     ; ecx/eax | n/2
person lurker    schedule 17.10.2013
comment
В качестве дополнения к более чистому способу деления / умножения на степень двойки используются инструкции сдвига. Также более читабельный. - person rAndom69; 14.05.2019
comment
@ rAndom69 согласился. Цель моего ответа состояла в том, чтобы напрямую указать OP на проблему с их конкретным кодом. - person lurker; 14.05.2019