0

So I'm trying to write a non-recursive of factorial procedure uses loop instruction, that parameter is passed through runtime stack.

I also need sequence of instruction in main PROC to invoke factorial procedure. Anybody want help me with this part, this what I have so far.

.IF eax == 0 || eax == 1  ;special cases
          mov eax, 1              ;factorial == 1
          jmp L2              ;quit procedure
        .ELSEIF eax > 12      ;n is too large
          mov edx, OFFSET msgError
          call Crlf
          call WriteString
          jmp L2              ;quit procedure
        .ENDIF

        mov ecx, eax              ;ecx = counter

            L1:
        dec ecx                   ;ecx = n - 1
        mul ecx                   ;eax = n * (n - 1)

        cmp ecx, 1            ;is counter > 1?
        ja L1                     ;true? then continue

        L2:
        ret

    nonRecurFact ENDP
Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • 1
    Could you elaborate on, *parameter passed through runtime stack*? Is that using CDECL conventions? And what help do you need on the sequence of instructions? Can you describe what's not working currently? – lurker Mar 17 '15 at 20:02
  • You're using assembly directives (`.IF`, etc) to check register values. Those only work while your program is being assembled. You need to use x86 instructions if you expect it to work at all. – lurker Mar 18 '15 at 00:32
  • Hey, Betty, did you try my answer? If you still need help, just let me know! – Jose Manuel Abarca Rodríguez Mar 18 '15 at 14:18

1 Answers1

0

I made a non recursive factorial procedure that uses LOOP instruction. The parameter is sent through the stack, but you can remove the stack and use the global variable my_factor. This little program runs in EMU8086 :

.stack 100h
.data
my_factor dw 5
.code          
;INITIATE DATA SEGMENT.
  mov  ax,@data
  mov  ds,ax

  push my_factor  
  call non_recursive_factorial

;FINISH.  
  mov  ax,4c00h
  int  21h           

proc non_recursive_factorial
  pop  ax ;RETRIEVE ADDRESS TO RETURN TO CALL.
  pop  my_factor  ;RETRIEVE PARAMETER.
  push ax ;PUT BACK ADDRESS TO RETURN TO CALL.
  mov  ax,my_factor
  mov  cx,my_factor
  dec  cx            
while:                                  
  mul  cx ;AX*CX = DX:AX.
  loop while
  ret
endp

At the end of the procedure, the result is in AX. Then you may display it or something else.

  • 1
    Using `pop` and `push` this way is a very ill-advised way to obtain arguments from the stack frame. If arguments are pushed onto the stack before the call, then the called function should set up a frame pointer in the `bp` register and access the arguments as an offset from `bp`. Look up "x86 stack frame" for details. – lurker Mar 18 '15 at 00:30