x86 Программа получила сигнал SIGSEGV, ошибка сегментации при отладке сборки MASM32 - PullRequest
0 голосов
/ 28 октября 2019

Мне поручено написать мой первый ассемблерный код, который принимает число от 1 до 12, введенное пользователем, и выводит факториал. Мне нужно написать 3 процедуры, одну для ввода, одну для вычисления факториала и одну для печати результата. Я считаю, что я написал это правильно (я не сделал), но после получения ввода от пользователя, программа завершается. Я никогда не вижу результат моей процедуры «Печать». При попытке отладки моего кода я получаю сообщение об ошибке:

Program received signal SIGSEGV, Segmentation fault.

Эта ошибка возникает сразу после первого шага «вызова ввода»

Вот мой полный код:

include c:\asmio\asm32.inc
includelib c:\asmio\asm32.lib
includelib c:\asmio\User32.lib ; SASM files for I/O
includelib c:\asmio\Kernel32.lib ; SASM files for I/O

input proto ; 0 parameters
Factorial proto nvx: dword ; 1 parameter
Print proto nax: dword, nf: dword ; 2 parameters  

; -------------------------------------------------------
.const ; Section to declare and initialize constants
NULL = 0
; -------------------------------------------------------
.data ; Section to declare and initialize variables
       nvx dword ?  
       nfx dword ?  
       nf dword ?  
       ask byte "Enter a number between 1-12: ", NULL
       fin byte "! is ", NULL
; -------------------------------------------------------
.code ; The actual code begins here: Main program

main proc ; Just like C++ this is the main program
start: 

       invoke input 
       mov nvx, eax
       invoke Factorial, nvx 
       mov nfx, eax
       invoke Print, nvx, nfx

 ret 0 ; need this line to return to caller
 main endp ; End of the procedure main
 ; -------------------------------------------------------
  input proc 
        mov   edx, OFFSET ask  
        call  WriteString        
        call  ReadInt    
ret
input endp
 ; -------------------------------------------------------

   Factorial proc USES ECX EBX nv: dword 
        mov ecx, nv ;start loop counter at value given by user because we need to multiply this many times to find the factorial.

        mov ebx, nv ; hold value of nv as divisor

        inc nv ; This is to account for 0! We increment by one and after the loop divide by nv

        mov eax, nv ; stores the largest number for multiplication


    L1:     
        dec nv ; becomes next largest number
        mul nv ; multiplication 
        mov eax, edx ; stores product into eax for next multiplication
        loop L1

        inc ebx
        cdq
        idiv ebx ; divide final product by original number + 1 for the correct factorial


        ret
        Factorial endp


    Print proc nax: dword, na: dword
        mov eax, nvx 
        call WriteString
        mov eax, OFFSET fin
        call WriteString
        mov eax, na
        call WriteString

        ret
        Print endp

end main ; End of the entire program
; -------------------------------------------------------
...