Recursion in Assembly Language

Assembly Language doesn’t have built-in support for high-level concepts like recursion, function calls, or printing. However, we can implement a similar concept using jumps and stack operations. This example will be for x86 assembly.

section .data
    fmt db "%d", 10, 0   ; format string for printf

section .text
    global main
    extern printf

main:
    push ebp
    mov ebp, esp
    
    ; Call fact(7)
    push 7
    call fact
    add esp, 4   ; Clean up the stack
    
    ; Print the result
    push eax
    push fmt
    call printf
    add esp, 8   ; Clean up the stack
    
    mov esp, ebp
    pop ebp
    ret

fact:
    push ebp
    mov ebp, esp
    
    mov eax, [ebp+8]  ; Get the parameter n
    cmp eax, 0
    jne recursive
    
    ; Base case: if n == 0, return 1
    mov eax, 1
    jmp done
    
recursive:
    ; Recursive case: return n * fact(n-1)
    dec eax
    push eax
    call fact
    add esp, 4   ; Clean up the stack
    
    ; Multiply the result by n
    imul eax, [ebp+8]
    
done:
    mov esp, ebp
    pop ebp
    ret

This assembly code implements a recursive factorial function similar to the original example. Here’s a breakdown of what it does:

  1. We define a format string for printing the result.

  2. In the main function:

    • We call fact(7).
    • We print the result using the printf function.
  3. The fact function:

    • If the input is 0, it returns 1 (base case).
    • Otherwise, it recursively calls itself with n-1 and multiplies the result by n.

Note that assembly doesn’t have high-level constructs like closures, so we can’t directly translate the Fibonacci closure example. Instead, we focused on the factorial function to demonstrate recursion.

To assemble and link this code (assuming you save it as recursion.asm):

$ nasm -f elf recursion.asm
$ gcc -m32 recursion.o -o recursion
$ ./recursion
5040

This will output 5040, which is 7 factorial, just like in the original example.

Remember that assembly language is low-level and architecture-specific. This example is for x86 assembly and may need adjustments for different architectures or assemblers.