Description
1 Objective
The objective of this lab is to make you comfortable with MIPS function calls.
2 Pre-requisite
Before starting with this lab, you should be familiar with MIPS function calls as well as
MARS.
3 The Stack
As stated in the prelab, there are some situations in which a function does not need to
save any data from registers into memory. When this is not the case, however, the most
logical place to store the data for later use is on the stack.
1
Computer Architecture and Design, Lab 4 2
The stack is a last in, first out (LIFO) data structure. This makes it ideal for function calls
because a function needs only to manage the top of the stack. When another function is
called, that function will push more data on the stack. When a function has completed
and is ready to return control back to its caller, it will pop data off the stack, leaving the
stack in the same form as it was before the function call. This means that functions need
to only manage their own section of the stack and do not need to concern themselves with
how other functions modify the stack.
To use the stack, simply push and pop data from it. The push operation can be done with
the following instructions:
1 addi $sp , $sp , −4 #Decrement t h e s t a c k p o i n t e r by 4 t o make s p ace
2 sw $r3 , 0 ( $sp ) #S t o r e $r3 on t h e s t a c k .
The above code example will push register $r3 onto the stack. The pop operation can be
done with:
1 lw $r3 , 0 ( $sp ) #Get t h e v a l u e from t h e s t a c k and p l a c e i t in $r3
2 addi $sp , $sp , 4 #Incremen t t h e s t a c k p o i n t e r by 4 t o r e l e a s e t h e s p ace
The above code example will pop whatever value is on the stack into register $r3. When
using the stack, you must match your push and pop operations. If you fail to do this, your
function is likely to cause your program to crash.
3.1 Frame Pointer
The Frame Pointer ($fp) is a compliment to the stack pointer. Often, the stack will have
a variable quantity of data pushed onto it during the lifetime of a function call. However
a function may need to access data that was pushed onto the stack when it first began
execution. Keeping track of how much data has been pushed onto the stack can be tedious
so the frame pointer helps manage this. Typically, a frame pointer keeps track of where the
stack pointer was before the function started and does not move throughout the lifetime
of the function. This means that if a function first saves registers to the stack and then
pushes a random amount of data onto the stack, it can use the frame pointer to access its
register data stored on the stack. Figure 1 shows an example of the stack. Naturally, if
you chose to use the frame pointer, you must save its previous value before changing it.
Computer Architecture and Design, Lab 4 3
.
.
.
Previous Procedure
Arguments
Saved Registers
Local Variables
Dynamic Area
$fp
$sp
Fig. 1: MIPS Stack Frame
4 Calling functions within functions
Calling a function within a function is no more complex than calling a function under
normal circumstances. The key is to utilize the stack to keep track of $ra. The calling
function needs to save the $ra register before jumping and linking to the next function
and must restore $ra before returning itself. Typically, if a function needs to call other
functions, it will save the $ra at the start of execution and restore it at the end, making
the management of $ra easier.
Computer Architecture and Design, Lab 4 4
5 Questions
1. Enter the following code into a file named lab4-1.s and run it with MARS. Use it to
answer the questions below:
1 . data
2 msg1 : . a s c i i z ” Enter the f i r s t number\n”
3 msg2 : . a s c i i z ” Enter the sec ond number\n”
4 msg : . a s c i i z ”The p r oduc t i s ”
5 . text
6 . g lob l main
7 . g lob l my mul
8
9 main :
10 addi $sp , $sp , −8 #make room f o r $ra and $f p on t h e s t a c k
11 sw $ra , 4 ( $sp ) #push $ra
12 sw $ fp , 0 ( $sp ) #push $f p
13
14 la $a0 , msg1 #l o a d a d d r e s s o f msg1 i n t o $a0
15 l i $v0 , 4
16 s y s c a l l #p r i n t msg1
17 l i $v0 , 5
18 s y s c a l l #r e a d i n t
19 add, $t0 , $v0 , $0 #pu t in $t 0
20 la $a0 , msg2 #l o a d a d d r e s s o f msg2 i n t o $a0
21 l i $v0 , 4
22 s y s c a l l #p r i n t msg2
23 l i $v0 , 5
24 s y s c a l l #r e a d i n t
25 add $a1 , $v0 , $0 #pu t in $a1
26 add $a0 , $t0 , $0 #pu t f i r s t number in $a0
27 add $ fp , $sp , $0 #s e t f p t o t o p o f s t a c k p r i o r
28 #t o f u n c t i o n c a l l
29 j a l my mul #do mul , r e s u l t i s in $v0
30 add $t0 , $v0 , $0 #s ave t h e r e s u l t in $t 0
31 la $a0 , msg
32 l i $v0 , 4
33 s y s c a l l #p r i n t msg
34 add $a0 , $t0 , $0 #pu t c ompu ta t ion r e s u l t in $a0
35 l i $v0 , 1
36 s y s c a l l #p r i n t r e s u l t number
37
38 lw $ fp , 0 ( $sp ) #r e s t o r e ( pop ) $f p
39 lw $ra , 4 ( $sp ) #r e s t o r e ( pop ) $ra
40 addi $sp , $sp , 8 #a d j u s t $sp
41 j r $ r a #r e t u r n
42
43 my mul : #m u l t i p l y $a0 w i t h $a1
44 #d oe s no t h a n dle n e g a t i v e $a1 !
45 #Note : Th is i s an i n e f f i c i e n t way t o m ul t i py !
Computer Architecture and Design, Lab 4 5
46 addi $sp , $sp , −4 #make room f o r $s0 on t h e s t a c k
47 sw $s0 , 0 ( $sp ) #push $s0
48
49 add $s0 , $a1 , $0 #s e t $s0 e q u a l t o $a1
50 add $v0 , $0 , $0 #s e t $v0 t o 0
51 m ul t l o o p :
52 beq $s0 , $0 , m ul t e ol
53
54 add $v0 , $v0 , $a0
55 addi $s0 , $s0 , −1
56 j m ul t l o o p
57
58 m ul t e ol :
59 lw $s0 , 0 ( $sp ) #pop $s0
60 j r $ r a
Computer Architecture and Design, Lab 4 6
(a) The above code example uses a subroutine to compute a multiplication. It
contains an error; what is it? You may wish to step through the program in
MARS to find it.
(b) After fixing the code, demonstrate its operation to the TA. .
(c) What is the hexadecimal value of $fp before the my mult function call? What is
its value during the my mult function call? What is the $fp after main returns?
2. (a) Write a MIPS program with the following specifications:
• Use the my mul function in question 1 to create a function which computes
factorials: n! = n · (n − 1) · … · 3 · 2 · 1.
• Each function must save all variables it modifies.
• Save your file as ”lab4-2.s”, and make sure you comment the code.
• Demonstrate your progress to the TA; .
(b) Your function uses a sub-routine to multiply two numbers. Does the order of
its arguments affect the speed at which it runs? If so, explain why.
3. Create a program with the same functionality as that of Question 2 but with the
following additional specifications:
Computer Architecture and Design, Lab 4 7
• Contains a function to read an integer from the user into $v0. All other registers
must be the same when it completes. You may use the syscall.
• Contains a function to print a message addressed by $a0. All registers must be
the same when it completes. You may use the syscall.
• Contains a function to present the user with a prompt to enter a number. The
prompt (message) is contained in $a0 and the result should be stored in $v0. All
other registers must be the same when it completes. You may use the previous
two functions.
• Save your file as ”lab4-3.s”, and make sure you comment the code.
• Demonstrate your progress to the TA; .
6 Deliverables
Submit the following:
• A completed copy of this lab.
• All source code files created in this lab (with comments).