Как исправить ошибку «Необработанное исключение» в сборке? - PullRequest
1 голос
/ 07 мая 2019

Я написал функцию, которая определяет, является ли значение простым или не простым. Но когда я возвращаюсь из функции, появляется ошибка.
Сообщение об ошибке

Необработанное исключение в 0x00000001 в Project.exe: 0xC0000005: нарушение прав доступа, местоположение выполнения 0x00000001.

Эта функция должна возвращать eax.

        push ebp
        mov ebp, esp
        mov eax, [ebp+8]                ; store input value
        mov ecx, [ebp+8]                ; store input value in counter
        sub esp, 4                      ; local variable 
        sub ecx, 1                      ; avoid compare with itself
        cmp eax, 3                      ; compare with 1, 2, 3
        jbe Prime

    L1:
        cmp ecx, 3                      ; when count=3 to stop
        je NotP
        mov edx, 0                      ; clear edx to save remainder
        mov [esp-4], eax                ; save input value
        div ecx                         ; divide number
        cmp edx, 0                      ; check remainder
        je NotP                         ; if remainder=0 then not prime
        jmp Prime
        loop L1
    NotP:
        mov eax, 0
        push eax                        ; if delete this ilne still come up error
        pop ebp
        ret
    Prime:
        mov eax, 1                      
        push eax                        ; if delete this ilne still come up error
        pop ebp
        ret
    isPrime  endp

1 Ответ

2 голосов
/ 07 мая 2019
   mov [esp-4], eax                ; save input value

Если вы планируете использовать локальную переменную, для которой вы зарезервировали комнату, вы должны написать:

    mov [esp], eax                ; save input value

или альтернативно написать:

    mov [ebp-4], eax              ; save input value

Правильный пролог / эпилог будет выглядеть так:

    push    ebp
    mov     ebp, esp
    sub     esp, 4                 ; local variable 
    mov     eax, [ebp+8]           ; store input value

    ...

NotP:
    mov     eax, 0
    pop     ebp                    ; remove local variable
    pop     ebp
    ret
Prime:
    mov     eax, 1                      
    pop     ebp                    ; remove local variable
    pop     ebp
    ret
isPrime  endp

    cmp edx, 0                      ; check remainder
    je NotP                         ; if remainder=0 then not prime
    jmp Prime
    loop L1

Найти остаток, отличный от нуля, недостаточно, чтобы сделать вывод, что числопремьер!Нужны дополнительные тесты.Пока эта инструкция loop L1 никогда не выполняется.
Например, чтобы проверить 15, ваше первое деление выполняет 15/14, что дает ненулевой остаток, но 15 не является простым числом.

L1:
    cmp ecx, 3                      ; when count=3 to stop
    je NotP

Вершина цикла также не может быть правильной!Подумайте о проверке числа 7.
Первое деление - 7/6 и имеет остаток, поэтому цикл должен продолжаться
Второе деление - 7/5 и остаток, поэтому цикл должен продолжаться
Третье деление7/4 и имеет остаток, поэтому цикл должен продолжаться
Вы не пробуете больше делений и делаете вывод, что «не простое», но 7 определенно является простым числом.

...