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.”
In the .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.
In the .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 stringmesg1
into register$a0
.$a0
is 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
.data
section: It declares a data section namedmesg2
. - In this data section, it stores a single word (4 bytes) with the value
15100900
.
Inside the main
function:
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 locationmesg2
into register$t0
.lw $a0, 0($t0)
: This instruction loads a 4-byte word (integer) from the memory location pointed to by$t0
(which is the address ofmesg2
) into register$a0
.syscall
: This syscall instruction prints the integer stored in$a0
to 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,
Sample Code
(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 N
.
- Data Initialization: In the
.data
section, the code initializes three null-terminated strings for messages:Prompt
(asking the user to inputN
),Result
(for displaying the sum), andBye
(a farewell message). - Main Function: The
main
function 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
N
using 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
N
is less than or equal to zero. If it is, the program branches to theEnd
label, printing the “Goodbye” message and exiting. - If
N
is greater than zero, the code initializes a register$t0
to 0 and enters a loop labeledLoop
. Inside the loop, it calculates the sum of integers from 1 toN
and stores it in$t0
. The code does this by repeatedly adding the current value ofN
to$t0
and decrementingN
in each iteration. The loop continues untilN
becomes zero.
- 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$a0
register.
- Continuation and Program Termination:
- The program then jumps back to the
main
label to process another value ofN
if 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.
Registers $a0
to $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 $v0
.
Registers $s0
to $s7
(saved registers) should be preserved across function calls, and $s0
is often used as a frame pointer to access local variables.
Stack Usage
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 $a0
to $a3
and then uses a jal
(jump and link) instruction to transfer control to the function.
The 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 $sp
.
Function Return
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.
Example Code
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
MIPS Stack
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:
- The
main
function prints a message and then calls thecalculate_sum
function withN = 5
. - The
calculate_sum
function calculates the sum of integers from 1 toN
using a loop. It saves and restores the return address on the stack and uses$v0
to store the sum result. - After returning from
calculate_sum
, themain
function 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.
Related content: