This README provides a comprehensive guide for building and running a series of assembly language and C programs. The project consists of multiple tasks, each demonstrating different functionalities, including user input handling, array manipulation, and arithmetic operations.
Task 1 : A simple program that adds two predefined integers and prints the result. task2 (continuation of task1) : A program that prompts the user to input two integers, computes their sum, and then displays the result
Task 2A : A program that prompts the user for their name and a count, then prints a welcome message the specified number of times.
Task 2AA: A program that calculates the total sum of an array of integers from 1 to 100 and allows the user to specify a range to
calculate the sum of that range.
Driver : A C driver file that interfaces with the assembly routines.
Asm_io.asm: Provides input/output routines, such as printing integers and strings, to facilitate basic I/O operations in assembly programs.
Makefile : A build script to compile and link the source files.
In Task 1, we had to implement an assembler program that performs integer addition using x86 assembly language and integrates with a C driver program to output the result. Below is a breakdown of the required steps along with code snippets for each part.
There are multiple files for this task:
- task1.asm : The assembly program that performs the addition.
- asm_io.asm : A utility assembly file for I/O functions.
- driver.c : A C program that serves as the entry point for the executable.
You will need to compile these files on a 64-bit machine but target 32-bit binaries using the -m32 flag. asm_main Function in Assembly:
Your assembly function will load two integers from global memory, add them, and then output the result using a helper function print_int provided in the asm_io.asm.
Assembly Program.
section .data
num1 dd 5 ; First number
num2 dd 10 ; Second numberExplanation: These lines define the two integers that will be added together in the assembly program.
mov eax, [num1] ; Load num1 into EAX
add eax, [num2] ; Add num2 to EAX (result in EAX)
push eax ; Push result onto the stack for print_int
call print_int ; Call the print_int function
add esp, 4 ; Clean up the stackExplanation: This part of the code shows how the program loads the numbers, adds them, and prints the result using an external function.
call print_nl ; Call print_nl to print a newline
mov eax, 0 ; Return 0 (success)
retExplanation: After printing the result, this part calls print_nl to print a newline and returns 0 to indicate success.
nasm -f elf task1.asm -o task1.o
nasm -f elf asm_io.asm -o asm_io.o
gcc -m32 -c driver.c -o driver.o
gcc -m32 driver.o task1.o asm_io.o -o task1
./task1Explanation: These commands assemble the task1.asm and asm_io.asm files, compile the driver.c, link them into an executable, and run the program.
After successfully compiling the files, you should have an executable named task1 in the src directory. You can run it using the command:
./task1This command adds the two integers which in my case the chosen numbers were 5 and 10.
This assembly program prompts the user to input two integers, computes their sum, and then displays the result. The program uses basic I/O functions (print_string, print_int, read_int, and print_nl) from the asm_io.inc library to handle user interaction and output.
task2.asm: The main assembly file containing the program logic. asm_io.asm : A utility assembly file for input/output functions. driver.c : The C program that serves as the entry point for the executable. Makefile : A build script to compile and link the source files.
- Prompt for First Number: The program displays a message asking the user to enter a number and stores the input in memory.
- Prompt for Second Number: After the first number is entered, the program asks for a second number and stores it as well.
- Addition Operation: The program adds the two numbers.
- Display the Result: It prints out the two numbers and their sum in a formatted manner.
segment .bss
integer1 resd 1 ; first integer
integer2 resd 1 ; second integer
result resd 1 ; resultExplanation: This snippet code defines a .bss segment that reserves memory space for two integers (integer1 and integer2) and a variable (result) to store the sum of those integers.
mov eax, msg1 ; note that this is a pointer!
call print_string
call read_int ; read the first integer
mov [integer1], eax ; store it in memory
mov eax, msg1 ; note that this is a pointer!
call print_string
call read_int ; read the second integer
mov [integer2], eax ; store it in memoryExplanation: This snippet of the code prompts the user to enter two integers, displaying a message before each input, and stores the values in memory locations designated for integer1 and integer2.
- The program stores user input in memory using the .bss section.
- It calculates the sum using the add instruction and stores the result in a variable.
- Messages and results are printed using functions from asm_io.inc.
To compile and run the program, use the following commands:
nasm -f elf task2.asm -o task2.o
gcc -m32 -c driver.c -o driver.o
gcc -m32 driver.o task2.o -o task2
./task2
This screenshot shows that once you run the command, you get asked to give two integers (in my case I put the numbers 4 and 5),it then calculates the sum of the numbers based on the given user input (which in my case equals to 9).
Task 2 requires you to do two different things, which requires us to have two different files. I have named them as Task2A and Task2AA.
Task 2A focuses on using loops and conditionals in x86 assembly language. The program prompts the user for their name and a count, validates the count, and prints a welcome message the specified number of times. If the count is less than 50 or greater than 100, an error message is displayed.
Task2A.asm : The assembly program that implements the functionality. asm_io.asm : A utility assembly file for input/output functions. driver.c : The C program that serves as the entry point for the executable. Makefile : A build script to compile and link the source files.
section .data
welcome_message db "Welcome to the program!", 0 ; Null-terminated string
error_message db "Error: The number must be between 50 and 100.", 10, 0 ; Null-terminated string with newline
name_prompt db "Enter your name: ", 0 ; Null-terminated string
count_prompt db "Enter the number of times to print the welcome message: ", 0 ; Null-terminated stringExplanation:These strings are used to prompt the user and display messages based on their input.
section .bss
name resb 100 ; Reserve 100 bytes for the name
count resd 1 ; Reserve space for the count (4 bytes)Explanation: This allocates memory for the user's name and the integer count.
asm_main:
; Ask for name
push name_prompt
call printf
add esp, 4
lea eax, [name] ; Load the address of the name buffer
push eax
push format_string ; Format string for scanf ("%s")
call scanf
add esp, 8
; Ask for count
push count_prompt
call printf
add esp, 4
lea eax, [count]
push eax
push format_integer ; Format string for scanf ("%d")
call scanf
add esp, 8Explanation: This part handles user input for the name and count, using printf and scanf.
mov eax, [count]
cmp eax, 50
jl print_error
cmp eax, 100
jg print_errorExplanation: Validates the user input, ensuring the count is between 50 and 100.
print_loop:
push welcome_message
call printf
add esp, 4
dec eax ; Decrease count
jnz .print_loop ; Loop until count reaches zeroExplanation: If the value is between 50-100, it repeats the welcome message according to the user-defined count.
print_error:
push error_message
call printf
add esp, 4Explanation: If the value is not between 50-100, it prints out an error message.
To compile and run the program, use the following commands:
nasm -f elf Task2A.asm -o Task2A.o
gcc -m32 -c driver.c -o driver.o
gcc -m32 driver.o Task2A.o -o Task2A
./Task2A
Exaplanation: This screenshot asks for the user's name and the number of times the message need sto be printed.
Task2AA.asm : Assembly program that initializes the array and calculates sums. asm_io.asm : Utility assembly file for input/output functions. driver.c : C driver program that interfaces with the assembly routines. Makefile : Build script to compile and link the source files.
Task 2AA is an assembly program designed to handle an array of integers, specifically calculating the total sum of integers from 1 to 100. The program allows the user to specify a range (start and end indices) and computes the sum of that range, while also validating the user's input.
section .data
total_sum_message db "The sum of the array is: %d", 10, 0
range_sum_message db "The sum of the range is: %d", 10, 0
error_message db "Error: Invalid input. Please enter numbers between 1 and 100.", 10, 0
start_index_prompt db "Enter the start index (1-100): ", 0
end_index_prompt db "Enter the end index (1-100): ", 0
format_integer db "%d", 0Explanation: The data section defines messages for user prompts and results, as well as reserves space for the array and indices.It contains formatted strings for output messages and prompts, as well as the format specifier for integers.
Explanation: The BSS section reserves memory for the array and indices. The array will hold the integers from 1 to 100 (containing value), while start_index, end_index, and range_sum store user input and the calculated sums.
The text section contains the main logic for initializing the array, calculating sums, and handling user input. Key functionalities include:
Initializing the Array : Filling the array with values from 1 to 100. Calculating Total Sum : Computing and displaying the total sum of the array. User Input Handling : Prompting for start and end indices, reading input, and validating it. Range Sum Calculation : Calculating and displaying the sum of the specified range if the input is valid.
xor ebx, ebx ; Clear ebx for total sum
mov edi, array ; Reset edi to the start of the array
.calculate_total_sum:
add ebx, [edi] ; Add the current element to total sum
add edi, 4 ; Move to the next integer
cmp edi, array + 400; Check if we reached the end of the array (100 integers)
jl .calculate_total_sum ; If not, continue summingExplanation: This snippet demonstrates how the program adds/calculates all the integers in the array.
; Load indices
mov eax, [start_index]
sub eax, 1 ; Convert to zero-based index
mov ebx, [end_index]
sub ebx, 1 ; Convert to zero-based index
; Check for valid range
cmp eax, 0
jl .invalid_range
cmp ebx, 99 ; Check if end_index is within bounds (0-99)
jg .invalid_range
cmp eax, ebx ; Check if start_index <= end_index
jg .invalid_rangeExplanation: This logic validates user input, ensuring both indices are within the range given and are correctly ordered.
.invalid_range:
push error_message ; Load the error message
call printf ; Print error message
add esp, 4 ; Clean up the stackExplanation: If the input indices are invalid, the program prints an error message.
To compile and run the program, use the following commands:
nasm -f elf Task2AA.asm -o Task2AA.o
gcc -m32 -c driver.c -o driver.o
gcc -m32 driver.o Task2AA.o -o Task2AA
./Task2AAUpon successful execution, the program will display:
- The total sum of the array.
- A prompt for the user to enter start and end indices.
- If valid indices are provided, the range sum will be displayed; otherwise, an error message will appear.
The Makefile is designed to automate the process of compiling and linking assembly and C source files into executable programs for the tasks outlined in this project. It streamlines the build process by defining compiler settings, source and object files, and the necessary rules for building executables.
- Compiler and Assembler Settings
NASM : The assembler used to compile the assembly source files. GCC : The compiler used to compile the C source files. OBJFLAGS: Flags for GCC to create 32-bit object files. ASMFLAGS: Flags for NASM to generate ELF format output.
NASM=nasm
GCC=gcc
OBJFLAGS=-m32 -c
ASMFLAGS=-f elfSource Files : These variables store the names of the source files used in the project.
Object Files : Explanation: These variables represent the compiled object files that will be linked to create the executables.
Executable Targets : The names of the final executable files produced by the build process.
The default rule compiles all executables when the command 'make' is run.
all: $(EXECUTABLE1) $(EXECUTABLE2A) $(EXECUTABLE2AA)Each executable has a corresponding rule that links the necessary object files.
$(EXECUTABLE1): $(DRIVER_OBJ) $(TASK1_OBJ) $(ASM_IO_OBJ)
$(GCC) -m32 $(DRIVER_OBJ) $(TASK1_OBJ) $(ASM_IO_OBJ) -o $(EXECUTABLE1)
$(EXECUTABLE2A): $(DRIVER_OBJ) $(TASK2A_OBJ) $(ASM_IO_OBJ)
$(GCC) -m32 $(DRIVER_OBJ) $(TASK2A_OBJ) $(ASM_IO_OBJ) -o $(EXECUTABLE2A)
$(EXECUTABLE2AA): $(DRIVER_OBJ) $(TASK2AA_OBJ) $(ASM_IO_OBJ)
$(GCC) -m32 $(DRIVER_OBJ) $(TASK2AA_OBJ) $(ASM_IO_OBJ) -o $(EXECUTABLE2AA)Explanation: These rules specify how to link the driver program and assembly object files to create each executable.
Rules are defined for compiling each assembly source file into object files.
$(TASK1_OBJ): $(TASK1_SRC)
$(NASM) $(ASMFLAGS) $(TASK1_SRC) -o $(TASK1_OBJ)
$(TASK2A_OBJ): $(TASK2A_SRC)
$(NASM) $(ASMFLAGS) $(TASK2A_SRC) -o $(TASK2A_OBJ)
$(TASK2AA_OBJ): $(TASK2AA_SRC)
$(NASM) $(ASMFLAGS) $(TASK2AA_SRC) -o $(TASK2AA_OBJ)
$(ASM_IO_OBJ): $(ASM_IO_SRC)
$(NASM) $(ASMFLAGS) $(ASM_IO_SRC) -o $(ASM_IO_OBJ)Explanation: Each of these rules uses NASM to compile the corresponding assembly files into object files.
This rule compiles the C driver source file.
$(DRIVER_OBJ): $(DRIVER_SRC)
$(GCC) $(OBJFLAGS) $(DRIVER_SRC) -o $(DRIVER_OBJ)Explanation: This rule compiles the driver.c file into an object file.
A clean rule is provided to remove all generated files, allowing for a fresh build.
clean:
rm -f $(TASK1_OBJ) $(TASK2A_OBJ) $(TASK2AA_OBJ) $(ASM_IO_OBJ) $(DRIVER_OBJ) $(EXECUTABLE1) $(EXECUTABLE2A) $(EXECUTABLE2AA)Explanation: Running make clean will delete all object files and executables.
Run the command 'make'
Run the command 'make clean'
This project illustrates essential assembly language concepts, which includes user input handling, loops, conditionals, range validation, alongside C integration. The provided Makefile automates the build process, ensuring that the tasks are compiled and linked efficiently.







