0
    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


           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 EAX 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
    ; -------------------------------------------------------

Hi everyone, I am tasked with writing my first assembly code which takes a number between 1-12 entered by the user and outputs the factorial. I need to write 3 procedures one for the input, one to calculate factorial and one to print the result. I believe I have written it correctly (I didn't) but after getting the input from the user, the program terminates. I never see the result of my "Print" procedure. When trying to debug my code I get the error:

Entry point was not found! Entry point should have label "main" (if gcc linker is used) or "start" (otherwise).

But I'm not sure how to fix that. Any idea? Thanks so much to everyone helping me out today on stack!!!

Google Z
  • 5
  • 3
  • 1
    Still not your problem, but now the `USES EAX` will instruct the assembler to preserve `eax` for you, so you can't use it as return value ;) – Jester Oct 27 '19 at 20:19
  • @Jester you, my friend, are using your head much more than me... – Google Z Oct 27 '19 at 20:55
  • Most debuggers can set breakpoints on a numeric address. Or recent GDB has a `starti` command that runs but stops before the first user-space instruction, whatever address that is. – Peter Cordes Oct 27 '19 at 21:29
  • @PeterCordes Thanks for the reply! I see the option so set breakpoints on lines but I'm not sure how to set up these points to get the debugger to work – Google Z Oct 27 '19 at 21:40
  • "points"? You mean breakpoints? You set them and then run the program. Execution pauses when it hits one, then you can examine memory / registers, and single-step or continue until the next breakpoint. Using a debugger is *essential*, you're wasting your own time (and everyone else's) trying to figure out what happened just from the program outputs and crashing or not. Take the time to google how to use get debugging to work in whatever dev environment / combination of build and debug tools you're using. – Peter Cordes Oct 27 '19 at 21:46
  • 1
    I'm not very familiarized with MASM32 but it looks like it compiles fine and reaches the entry point since you said it asks for input. When and what throws this error? The error itself seems to suggest you need a ``main:``(GCC) or ``start:`` (Other) label just before ``proc main`` but I'm a litle confused on how it got executed while simultaneously throwing an error that it was unable to find main entry point of execution. I also see that you include Windows libraries, does MASM32 have an option to use the Windows linker? If so, you should be using it. – Pickle Rick Oct 27 '19 at 22:22
  • I appreciate the reply and I love @PickleRick . Adding the line "start: " seems to make the debugger work! Now i see during compilation I get an error right after "invoke input" that states "Program received signal SIGSEGV, Segmentation fault." – Google Z Oct 28 '19 at 02:03

0 Answers0