SYSTEM CALLS in MIPS: A system call is used to communicate with the system for reading from the keyboard or writing to the screen. A system call requires some parameters to be passed in a particular register and a request/function number (or service code) to be passed in register $v0.
Steps for using System Calls
- Load the service code into register $v0. The codes (the values to be loaded in $v0) and their respective functions are given in the table below.
- Load the arguments (if any) into registers such as $a0, $a1 according to the table.
- Use the “syscall” instruction.
- The results are returned in registers such as $v0 according to the table.
- All programs should terminate with $v0 = 10 and a “syscall” instruction to exit. This helps in running very long programs (which are run using the GO option in the simulation menu in PCSPIM).
MIPS System Calls Examples
In this section, we will learn to use MIPS system calls by using different examples.
Exercise 1: Printing your Name using SYSCALL
This MIPS assembly code prints the message “my name is bilal malik” (or any other name) to the output screen using system calls.
Use the following code to print your name on an output screen. .data mesg1: .asciiz “my name is bilal malik“ # fill the blank with your name .text .globl main main: li $v0, 4 # Load immediate $v0 with value 4 la $a0, mesg1 # $a0 points to base address of string array mesg1 syscall li $v0, 10 # prepare to exit syscall # Exit to OS
Run this program by pressing GO (F5). Check the execution of your program and see how system calls are used to get input from the user and display anything on the PCSPIM console. What do you see in the CONSOLE window? I see my name because I have printed “My name is Bilal Malik.”
.data section, a null-terminated string (an ASCII message) is defined with the message you want to display. You should replace
"bilal malik" with your name inside the double quotes.
.text section, the
main label is defined as the entry point for the program.
li $v0, 4: This instruction loads the value 4 into register
$v0, indicating that we are about to perform a system call to print a string.
la $a0, mesg1: This instruction loads the base address of the string
$a0is the argument register that is used to pass the address of the string to be printed to the system call.
syscall: This instruction executes the system call, which will print the string pointed to by
$a0(in this case, your name) to the output screen.
li $v0, 10: This instruction loads the value 10 into register
$v0, indicating that we are about to perform a system call to exit the program.
syscall: This instruction executes the system call to terminate the program and return control to the operating system.
When you run this code, it will display the message “my name is [your name]” on the output screen and then exit the program.
Exercise 2: Printing an Integer using SYSCALL
.data mesg2: .word 15100900 .text .globl main main: li $v0, 1 #Place 1 in $v0 in order to print an integer la $t0, mesg2 #Put address of the memory location in $t0 lw $a0, 0($t0) #Load the integer from memory into $a0 syscall #syscall to print the integer li $v0, 10 #Prepare to exit by placing 10 in $v0 syscall #Exit to OS
- In the
.datasection: It declares a data section named
- In this data section, it stores a single word (4 bytes) with the value
li $v0, 1: This instruction loads the value 1 into register
$v0, indicating that we are going to use system call code 1, which is used to print an integer.
la $t0, mesg2: This instruction loads the address of the memory location
lw $a0, 0($t0): This instruction loads a 4-byte word (integer) from the memory location pointed to by
$t0(which is the address of
mesg2) into register
syscall: This syscall instruction prints the integer stored in
$a0to the console.
li $v0, 10: This instruction loads the value 10 into
$v0, which is the system call code for program exit.
syscall: This syscall instruction exits the program and returns control to the operating system.
In summary, the code loads the integer
15100900 from memory and prints it to the console before exiting the program.
Exercise 3: Sum of Integers Using System Calls Using PCSpim
Write a code that asks the user to enter a positive integer N and returns the Sum of all integers less than or equal to N. The sample code is given on the next page. Note that, now you can run for N = 100, N= 200, N= 1000 by pressing GO, watching the console window, entering the value and hitting the Enter key. What is the answer in each case?
For N=100, Sum: 5050, For N=200, Sum: 20100, For N=1000, Sum: 500500,
(Taken from the book: “MIPS Assembly Language Programming” by Robert L. Britton)
####################################################################### # Cross References: # v0: N, t0: Sum ####################################################################### .data Prompt: .asciiz "\n Please Input a value for N = (-1 to end): " Result: .asciiz "\n The sum of the integers from 1 to N is: " Bye: .asciiz "\n **** Good bye – Have a good day****" .text .globl main main: # Print the prompt message li $v0, 4 # System call code for print string la $a0, Prompt # Load address of string Prompt into $a0 syscall # Print the prompt message # Read the value of N li $v0, 5 # System call code for Read Integer syscall # Read the value of N into $v0 # Branch to end if N <= 0 ble $v0, $zero, End # Initialize register $t0 to 0 li $t0, 0 Loop: # Sum of integers in register $t0 add $t0, $t0, $v0 # Summing integers in reverse order addi $v0, $v0, -1 # Branch to loop if $v0 is not equal to 0 bne $v0, $zero, Loop # Print the result message li $v0, 4 # System call code for Print String la $a0, Result # Load address of string Result into $a0 syscall # Print the string # Print the sum of integers li $v0, 1 # System call code for Print Integer move $a0, $t0 # Move value to be printed to $a0 syscall # Print the sum of integers # Go for the next number j main End: # Print the "Goodbye" message li $v0, 4 # System call code for Print String la $a0, Bye # Load address of string Bye into $a0 syscall # Print the string # Exit the program li $v0, 10 # System call code for exit syscall # Terminate the program and return control
How this Code Work?
This MIPS assembly code is a program that calculates and prints the sum of integers from 1 to a user-provided value
- Data Initialization: In the
.datasection, the code initializes three null-terminated strings for messages:
Prompt(asking the user to input
Result(for displaying the sum), and
Bye(a farewell message).
- Main Function: The
mainfunction is the entry point of the program and contains the main logic.
- User Input and Calculation:
- The code starts by printing the prompt message, asking the user to input a value for
Nusing system call code 4 (
li $v0, 4) and then reading the input integer using system call code 5 (
li $v0, 5).
- It checks if the value of
Nis less than or equal to zero. If it is, the program branches to the
Endlabel, printing the “Goodbye” message and exiting.
Nis greater than zero, the code initializes a register
$t0to 0 and enters a loop labeled
Loop. Inside the loop, it calculates the sum of integers from 1 to
Nand stores it in
$t0. The code does this by repeatedly adding the current value of
Nin each iteration. The loop continues until
- The code starts by printing the prompt message, asking the user to input a value for
- Printing the Result:
- After the loop, the code prints the result message “The sum of the integers from 1 to N is:” using system call code 4.
- It then prints the actual sum, which is stored in
$t0, using system call code 1 (
li $v0, 1) and the
- Continuation and Program Termination:
- The program then jumps back to the
mainlabel to process another value of
Nif the user desires to continue.
- When the user decides to exit (inputs a non-positive value), the program prints the “Goodbye” message and terminates with system call code 10 (
li $v0, 10) to return control to the operating system.
- The program then jumps back to the
Overall, this MIPS assembly program provides a simple interactive way to calculate and display the sum of integers from 1 to a user-provided value, and it gracefully exits upon user input.
MIPS Procedure Calls
MIPS (Microprocessor without Interlocked Pipeline Stages) procedure calls refer to the mechanism by which the MIPS architecture manages the execution of functions or procedures in a program. In MIPS assembly language, procedures are typically implemented using a combination of function calls, parameter passing, and return values. Here are some key aspects of MIPS procedure calls:
Procedure Call Convention
MIPS follows a specific procedure call convention that defines how parameters, return values, and registers are used during function calls.
$a3 (also known as argument registers) are used to pass up to four function arguments.
The return value of a function is typically stored in register
$s7 (saved registers) should be preserved across function calls, and
$s0 is often used as a frame pointer to access local variables.
The stack is used to store the return address (the address to jump back to after the function call), saved registers, and local variables.
The stack pointer register
$sp points to the top of the stack.
To reserve space on the stack for local variables, the
$sp register is decremented (to allocate space) and incremented (to deallocate space) accordingly.
Function Call Flow
To call a function, the caller typically places function arguments in
$a3 and then uses a
jal (jump and link) instruction to transfer control to the function.
jal instruction stores the return address in
$ra (return address register) and jumps to the function’s entry point.
Inside the function,
$ra is often preserved before making any function calls, and local variables are typically accessed using the stack pointer
When a function is ready to return, it uses the
jr (jump register) instruction to jump back to the address stored in
$ra, effectively returning control to the caller.
The function may place its return value in
$v0 before returning.
Nested Function Calls
MIPS supports nested function calls, where one function can call another.
The return address for each nested call is saved on the stack, allowing the program to return to the correct caller when a function completes.
MIPS procedure calls provide a structured way to organize code, facilitate code reuse, and manage program flow when dealing with functions or procedures in assembly language programs. The adherence to conventions ensures that function calls and returns work reliably and predictably across different parts of a program.
Here’s an example of MIPS assembly code that demonstrates a simple procedure call:
.data message: .asciiz "Hello from the main function!\n" result: .asciiz "The result is: " .text .globl main # Main function main: # Print a message from the main function li $v0, 4 la $a0, message syscall # Call the add_numbers function li $a0, 5 # Argument 1 li $a1, 7 # Argument 2 jal add_numbers # Print the result li $v0, 4 la $a0, result syscall # Print the return value stored in $v0 li $v0, 1 move $a0, $v0 syscall # Exit the program li $v0, 10 syscall # Add two numbers and return the result add_numbers: # Save return address sw $ra, 0($sp) addiu $sp, $sp, -4 # Perform addition add $v0, $a0, $a1 # Restore return address and return lw $ra, 4($sp) addiu $sp, $sp, 4 jr $ra
Here’s an example of MIPS assembly code that demonstrates how the stack is used to manage function calls and local variables:
.data message: .asciiz "Stack Example\n" result: .asciiz "The result is: " .text .globl main # Main function main: # Print a message from the main function li $v0, 4 la $a0, message syscall # Call the calculate_sum function li $a0, 5 # Argument 1: N jal calculate_sum # Print the result li $v0, 4 la $a0, result syscall # Print the return value stored in $v0 li $v0, 1 move $a0, $v0 syscall # Exit the program li $v0, 10 syscall # Calculate the sum of integers from 1 to N # Input: $a0 (N), Output: $v0 (Sum) calculate_sum: # Save return address sw $ra, 0($sp) addiu $sp, $sp, -4 # Initialize sum to 0 li $v0, 0 # Loop to calculate the sum loop: add $v0, $v0, $a0 # Add N to the sum addi $a0, $a0, -1 # Decrement N bnez $a0, loop # Continue looping if N is not zero # Restore return address and return lw $ra, 4($sp) addiu $sp, $sp, 4 jr $ra
In this MIPS assembly code:
mainfunction prints a message and then calls the
N = 5.
calculate_sumfunction calculates the sum of integers from 1 to
Nusing a loop. It saves and restores the return address on the stack and uses
$v0to store the sum result.
- After returning from
mainfunction prints the result and exits the program.
This example demonstrates how the stack is used to manage the return address during function calls and how local variables (in this case, the sum) are stored and manipulated within a function.