Search code examples
ubuntuassemblyx86nasmfactorial

Factorial function in x86 NASM assembly goes wrong


I'm learning assembly language using x86 NASM. I wanted to write a simple recursive factorial function to which I am passing one parameter using EAX register. After that, I want to print my result on the screen but nothing happens. After sitting and staring on my computer I don't have any clue what is wrong with my code. Can you guys help newbie with this problem?

I know that the prologue and epilogue of factorial funtion is not required due I'm not using stack but for me code is more readable ;)

Here is my code:

global main
extern printf

section .data
    message db "%03X", 0x10, 0x0

section .text
main:
    mov eax, 5
    call factorial
    push eax
    push message
    call printf
    add esp, 0x8
    mov eax, 1
    mov ebx, 0
    int 0x80

factorial:
    push ebp
    push edx
    mov ebp, esp
    mov edx, eax
    cmp edx, 0
    jne not_equal_zero
    mov eax, 1
    jmp exit
not_equal_zero:
    mov eax, edx
    sub eax, 1
    call factorial
    imul eax, edx
exit:
    mov esp, ebp
    pop edx
    pop ebp
    ret

Solution

  • The C library - I guess you use the one from GCC - doesn't output the result of printf immediately. Rather, it is stored in a separate memory called buffer and outputted by chance. In this case the program will be ended by int 0x80/eax=1 faster than the buffer will be flushed. You can insert a manual flush:

    ...
    extern fflush
    ...
    push 0
    call fflush
    add esp, 4
    ...
    

    The best solution is to use the C exit function. Replace

    mov ebx,0
    mov eax,1
    int 0x80
    

    by

    push 0
    call exit
    

    or replace it simply by

    ret
    

    In this case you don't need to flush the buffer manually. This will exit or ret do for you.

    BTW: LF (line feed) is coded as 10 decimal and 0x0A hexadecimal.