;;; Defining recursive factorial for Linux ;;; To assemble, link and run under Linux ELF (ssh.itu.dk) ;;; nasm -f elf tryfac.asm -o try.o ;;; gcc try.o -o try ;;; ./try global main ; Define entry point for this code extern printf ; Refer to C library function SECTION code ;;; Compute and print fac(10) main: push ebp mov ebp, esp push dword 10 ; Push 10 and compute fac(10) call fac add esp, byte 4 push eax ; ... then print the result call printi add esp, byte 4 mov esp, ebp pop ebp ret ;;; Function fac computes n! in register eax fac: push ebp ; Save ebp on stack mov ebp, esp ; Save stack pointer in ebp mov eax, [ebp+8] ; Get argument n cmp eax, 0 je .false ; If n==0 return 1 dec eax ; Else push n-1 ... push eax call fac ; ... and compute fac(n-1) add esp, byte 4 mul dword [ebp+8] ; ... then multiply eax by n jmp .end .false: mov eax, 1 .end: mov esp, ebp pop ebp ret ;;; The printi and printc routines are called like this: ;;; push ;;; call printi ;;; add esp, byte 4 ;;; They preserve the contents of all registers, for use in debugging. printi: ; Print decimal integer push ebp ; Save ebp on stack mov ebp, esp ; Save stack pointer in ebp pushad ; Save all registers push dword [ebp+8] ; Push (integer) argument, 2nd printf arg push dword printistr ; Push format string, 1st printf arg call printf ; Print using C library printf add esp, byte 8 ; Pop printf's arguments popad ; Restore all registers mov esp, ebp ; Restore stack pointer pop ebp ; Restore ebp ret ; Return printc: ; Print ASCII character push ebp ; Save ebp on stack mov ebp, esp ; Save stack pointer in ebp pushad ; Save all registers push dword [ebp+8] ; Push (char) argument, 2nd printf arg push dword printcstr ; Push format string, 1st printf arg call printf ; Print using C library printf add esp, byte 8 ; Pop printf's arguments popad ; Restore all registers mov esp, ebp ; Restore stack pointer pop ebp ; Restore ebp ret ; Return segment DATA printistr db '%d ', 0 printcstr db '%c', 0