Experiment 10: X86 Assembly
Language Program to Find the
Factorial of a Given Integer Using
Recursion
Aim
To write an X86 assembly language program that calculates the factorial of a
given integer number provided via command line arguments using
recursion and explicit stack manipulation.
Apparatus Required
1. Computer System: A computer with a 32-bit or 64-bit processor.
2. Assembler: An assembler like NASM (Netwide Assembler) for X86
architecture.
3. Debugger: A debugger such as GDB (GNU Debugger) for debugging
the assembly code.
4. Text Editor: Any text editor (e.g., Notepad++, Visual Studio Code) for
writing the assembly code.
5. Operating System: A compatible operating system (Linux or Windows
with WSL).
Theory
The factorial of a non-negative integer ( n ) is the product of all positive
integers less than or equal to ( n ). It is denoted as ( n! ) and is defined as:
( n! = n \times (n-1)! ) for ( n > 0 )
( 0! = 1 )
In this lab, we will implement a recursive function to calculate the factorial
of a number. The program will accept the integer as a command-line
argument, and we will use explicit stack manipulation to manage the
function calls.
Key Concepts:
Recursion: A function that calls itself to solve a problem.
Stack Manipulation: Using the stack to save the state of registers and
local variables during function calls.
Procedure
1. Setup the Environment: Install NASM and a suitable text editor.
2. Write the Assembly Code: Create a new file with a .asm extension and
write the assembly code.
3. Assemble the Code: Use NASM to assemble the code into an object
file.
4. Link the Object File: Link the object file to create an executable.
5. Run the Program: Execute the program with a command-line argument
and observe the output.
6. Record the Results: Verify that the factorial is calculated correctly.
Assembly Code
Below is the assembly code that implements the factorial calculation using
recursion and explicit stack manipulation.
section .data
msg db "Factorial: ", 0
result db 10 dup(0) ; Buffer for the result string
section .bss
num resb 4 ; Buffer for the input number
section .text
global _start
_start:
; Get command line argument
mov eax, [esp + 4] ; argc
cmp eax, 2 ; Check if there is at least one argument
jl exit ; If not, exit
mov eax, [esp + 8] ; argv[1]
call atoi ; Convert string to integer
mov ebx, eax ; Store the number in ebx
; Calculate factorial
call factorial ; Call factorial function
mov ebx, eax ; Store the result in ebx
; Convert result to string
call itoa ; Convert integer to string
; Print result
mov eax, 4 ; syscall: write
mov ebx, 1 ; file descriptor: stdout
mov ecx, msg ; message
mov edx, 10 ; length of message
int 0x80 ; call kernel
mov eax, 4 ; syscall: write
mov ebx, 1 ; file descriptor: stdout
mov ecx, result ; result string
mov edx, 10 ; length of result
int 0x80 ; call kernel
exit:
mov eax, 1 ; syscall: exit
xor ebx, ebx ; status: 0
int 0x80 ; call kernel
; Function to calculate factorial
factorial:
; Push the current value of ebx onto the stack
push ebx
; Base case: if n == 0, return 1
cmp ebx, 0
je .base_case
; Recursive case: n * factorial(n - 1)
dec ebx ; Decrement n
call factorial ; Recursive call
pop eax ; Pop the previous value of n
imul eax, ebx ; Multiply n with the result of factorial(n
ret
.base_case:
mov eax, 1 ; Return 1 for factorial(0)
pop ebx ; Restore the previous value of n
ret
; Function to convert integer to string
itoa:
mov ecx, 10 ; Base 10
xor edx, edx ; Clear edx for division
mov ebx, result ; Point to the result buffer
add ebx, 10 ; Move to the end of the buffer
mov byte [ebx], 0 ; Null-terminate the string
.convert_loop:
dec ebx ; Move back in the buffer
xor edx, edx ; Clear edx before division
div ecx ; Divide eax by 10
add dl, '0' ; Convert remainder to ASCII
mov [ebx], dl ; Store ASCII character in buffer
test eax, eax ; Check if quotient is zero
jnz .convert_loop ; Repeat if not zero
mov eax, ebx ; Set eax to the start of the string
ret
Observation
Upon executing the program with a valid integer command-line argument,
the output displays the calculated factorial of the given number. The
program successfully utilizes recursion and explicit stack manipulation to
compute the factorial.
Result
The assembly program effectively calculates the factorial of a given integer
using recursion, demonstrating the ability to manipulate the stack and
manage function calls in assembly language. The output correctly reflects
the factorial of the input number.
Conclusion
This lab exercise illustrates the principles of recursion and stack
manipulation in assembly language programming. The successful
implementation of the factorial function showcases the practical application
of these concepts in solving mathematical problems.