Lec8 MIPS Insts #4
Download
Report
Transcript Lec8 MIPS Insts #4
2010 R&E Computer System Education & Research
Lecture 8. MIPS Instructions #4 – Branch
Instructions #2
Prof. Taeweon Suh
Computer Science Education
Korea University
Procedure (Function)
• Programmers use a procedure (or function) to
structure programs
To make the program modular and easy to understand
To allow code to be re-used
• Procedures allow the programmer to focus on just
one portion of the task at a time
• Parameters (arguments) act as an interface
between the procedure and the rest of the program
2
Korea Univ
Procedure Calls
Definitions
• Caller: calling procedure (in this case, main)
• Callee: called procedure (in this case, sum)
High-level code example
void main()
{
int y;
y = sum(42, 7);
...
}
int sum(int a, int b)
{
return (a + b);
}
3
Korea Univ
MIPS Instructions for Accessing Procedures
•
Procedure call instruction:
jal
ProcedureAddress
#jump and link
# $ra <- pc + 4
# pc <- jump target
Saves PC+4 in register $ra to have a link to the next instruction for the procedure return
Instruction format (J format):
0x03
26-bit address
High-level code
int main() {
simple();
a = b + c;
}
void simple() {
return;
}
MIPS assembly code
PC
compile
0x00400200 main: jal
0x00400204
add
...
simple
$s0, $s1, $s2
PC+4
void means that simple doesn’t return a value.
0x00401020 simple: jr $ra
jal: jumps to simple and saves PC+4 in the return address
register ($ra). In this case, $ra = 0x00400204 after jal executes
4
Korea Univ
MIPS Instructions for Accessing Procedures
• Return instruction:
jr
$ra #return
// pc <- $ra
Instruction format (R format):
0
31
0x08
High-level code
int main() {
simple();
a = b + c;
}
void simple() {
return;
}
MIPS assembly code
compile
0x00400200 main: jal
0x00400204
add
...
simple
$s0, $s1, $s2
0x00401020 simple: jr $ra
$ra contains 0x00400204
jr $ra: jumps to address in $ra, in this case 0x00400204.
5
Korea Univ
Procedure Calls
Procedure calling conventions:
• Caller:
passes arguments to callee.
jumps to the callee
• Callee:
performs the procedure
returns the result to caller
returns to the point of call
Must not overwrite registers or memory needed by the caller
MIPS conventions:
•
•
•
•
Call procedure: jump and link (jal)
Return from procedure: jump register (jr)
Argument values: $a0 - $a3
Return values: $v0, $v1
6
Korea Univ
Input Arguments and Return Values
High-level code
int main()
{
int y;
...
y = diffofsums(2, 3, 4, 5);
...
}
// 4 arguments
int diffofsums(int f, int g, int h, int i)
{
int result;
result = (f + g) - (h + i);
return result;
// return value
}
7
Korea Univ
Input Arguments and Return Values
MIPS assembly code
# $s0 = y
main:
...
addi
addi
addi
addi
jal
add
...
High-level code
$a0, $0, 2
$a1, $0, 3
$a2, $0, 4
$a3, $0, 5
diffofsums
$s0, $v0, $0
# $s0 = result
diffofsums:
add $t0, $a0,
add $t1, $a2,
sub $s0, $t0,
add $v0, $s0,
jr $ra
$a1
$a3
$t1
$0
int main()
{
int y;
...
y = diffofsums(2, 3, 4, 5);
...
}
#
#
#
#
#
#
argument 0 = 2
argument 1 = 3
argument 2 = 4
argument 3 = 5
call procedure
y = returned value
#
#
#
#
#
$t0 = f + g
$t1 = h + i
result = (f + g) - (h + i)
put return value in $v0
return to caller
// 4 arguments
int diffofsums(int f, int g, int h, int i)
{
int result;
result = (f + g) - (h + i);
return result;
// return value
}
8
Korea Univ
Input Arguments and Return Values
MIPS assembly code
# $s0 = result
diffofsums:
add $t0, $a0,
add $t1, $a2,
sub $s0, $t0,
add $v0, $s0,
jr $ra
$a1
$a3
$t1
$0
#
#
#
#
#
$t0 = f + g
$t1 = h + i
result = (f + g) - (h + i)
put return value in $v0
return to caller
• We need a place (called stack) to temporarily store arguments and
registers because …
diffofsums overwrote 3 registers: $t0, $t1, and $s0 , which may be
being used in the main routine
What if the callee (diffofsums) needs to use more registers than
allocated to argument ($a0 - $a3) and return values ($v0, $v1)
9
Korea Univ
The Stack
• Memory used to temporarily
save variables
• Like a stack of dishes, stack
is a data structure for spilling
registers organized as a lastin-first-out (LIFO) queue
10
Korea Univ
The Stack - Spilling Registers
• Stack is a data structure for
spilling registers organized as a
last-in-first-out (LIFO) queue
• One of the general registers,
$sp ($29), is used to point to
the top of the stack
Main Memory
high addr
top of stack
$sp
The stack “grows” from high
address to low address in MIPS
Push: add data onto the stack
• $sp = $sp – 4
• data on stack at new $sp
Pop: remove data from the stack
low addr
• Data from stack at $sp
• $sp = $sp + 4
11
Korea Univ
Stack Pointer (SP)
• Stack pointer ($sp) points to the top of the stack
Main Memory
Main Memory
Address
Data
Address
Data
7FFFFFFC
12345678
7FFFFFFC
12345678
7FFFFFF8
7FFFFFF8
AABBCCDD
7FFFFFF4
7FFFFFF4
11223344
7FFFFFF0
7FFFFFF0
$sp
12
$sp
Korea Univ
How Procedures use the Stack
• Called procedures (callee) must not have any
unintended side effects to the caller
But, diffofsums overwrites 3 registers ($t0, $t1,
$s0) as duplicated below:
# MIPS assembly
# $s0 = result
diffofsums:
add $t0, $a0,
add $t1, $a2,
sub $s0, $t0,
add $v0, $s0,
jr $ra
$a1
$a3
$t1
$0
#
#
#
#
#
$t0 = f + g
$t1 = h + i
result = (f + g) - (h + i)
put return value in $v0
return to caller
13
Korea Univ
Storing Register Values on the Stack
sw
sw
sw
add
add
sub
i)
add
lw
lw
lw
addi
jr
$s0,
$t0,
$t1,
$t0,
$t1,
$s0,
8($sp)
4($sp)
0($sp)
$a0, $a1
$a2, $a3
$t0, $t1
$v0,
$t1,
$t0,
$s0,
$sp,
$ra
$s0, $0
0($sp)
4($sp)
8($sp)
$sp, 12
#
#
#
#
#
#
#
#
make space on stack
to store 3 registers
save $s0 on stack
save $t0 on stack
save $t1 on stack
$t0 = f + g
$t1 = h + i
result = (f + g) - (h +
#
#
#
#
#
#
put return value
restore $t1 from
restore $t0 from
restore $s0 from
deallocate stack
return to caller
“Pop” (restore) the registers
from the stack prior to
returning to the caller
in $v0
stack
stack
stack
space
Address Data
FC
“Push” (back up) the
registers to be used in the
callee to the stack
?
Address Data
$sp
stack frame
# $s0 = result
diffofsums:
addi $sp, $sp, -12
F8
F4
F0
(a)
FC
?
FC
F8
$s0
F8
F4
$t0
F4
F0
$t1
(b)
14
Address Data
$sp
?
$sp
F0
(c)
Korea Univ
Preserved and NonPreserved Registers
•
•
In the previous example, if the calling procedure does not use the
temporary registers ($t0, $t1), the effort to save and restore them is
wasted
To avoid this waste, MIPS divides registers into preserved and
nonpreserved categories
•
•
•
•
•
The preserved registers include $s0 ~ $s7 (saved)
The nonpreserved registers include $t0 ~ $t9 (temporary)
So, a procedure must save and restore any of the preserved registers it wishes to
use, but it can change the nonpreserved registers freely
The callee must save and restore any preserved registers it wishes to use
The callee may change any of the nonpreserved registers
• But, if the caller is holding active data in a nonpreserved register, the
caller needs to save and restore it
Preserved
Nonpreserved
(Callee-Saved)
(Caller-Saved)
$s0 - $s7
$t0 - $t9
$ra
$a0 - $a3
$sp
$v0 - $v1
stack above $sp
stack below $sp
15
Korea Univ
Storing Saved Registers on the Stack
# $s0 = result
diffofsums:
addi $sp, $sp, -4
sw
$s0, 0($sp)
add $t0, $a0, $a1
add $t1, $a2, $a3
sub $s0, $t0, $t1
add $v0, $s0, $0
lw $s0, 0($sp)
addi $sp, $sp, 4
jr $ra
# make space on stack to
# store one register
# save $s0 on stack
# no need to save $t0 or $t1
# $t0 = f + g
# $t1 = h + i
# result = (f + g) - (h + i)
# put return value in $v0
# restore $s0 from stack
# deallocate stack space
# return to caller
16
Korea Univ
Nested Procedure Calls
•
•
•
Procedures that do not call others are called leaf procedures
Life would be simple if all procedures were leaf procedures, but they aren’t
• For example,
• the main program calls procedure A with an argument of 3 (by
placing the value 3 into register $a0 and then using jal A)
• Procedure A calls procedure B via jal B with an argument 7 (also
placed in $a0)
• There is a conflict over the use of register $a0 and $ra
Use stack to preserve registers
• The caller pushes any argument registers ($a0~$a4) or temporary
registers ($t0~$t9) that are needed after the call
proc1:
addi $sp, $sp, -4
sw
$ra, 0($sp)
jal proc2
...
lw
$ra, 0($sp)
addi $sp, $sp, 4
jr $ra
# make space on stack
# save $ra on stack
# restore $s0 from stack
# deallocate stack space
# return to caller
17
Korea Univ
Recursive Procedure Call
• Recursive procedures
invoke “clones” of
themselves
High-level code
int factorial(int n) {
if (n <= 1)
return 1;
else
return (n * factorial(n-1));
}
MIPS assembly code
0x90 factorial:
0x94
0x98
0x9C
0xA0
0xA4
else
0xA8
0xAC
0xB0
0xB4
else:
0xB8
call
0xBC
0xC0
0xC4
0xC8
factorial(n-1)
0xCC
18
addi
sw
sw
addi
slt
beq
$sp,
$a0,
$ra,
$t0,
$t0,
$t0,
$sp, -8
4($sp)
0($sp)
$0, 2
$a0, $t0
$0, else
addi
addi
jr
addi
jal
$v0, $0, 1
$sp, $sp, 8
$ra
$a0, $a0, -1
factorial
#
#
#
#
#
yes: return 1
restore $sp
return
n = n - 1
recursive
lw
lw
addi
mul
$ra,
$a0,
$sp,
$v0,
#
#
#
#
restore $ra
restore $a0
restore $sp
n *
jr
$ra
0($sp)
4($sp)
$sp, 8
$a0, $v0
# make room
# store $a0
# store $ra
# a <= 1 ?
# no: go to
# return
Korea Univ
Stack during Recursive Call
Address Data
FC
Address Data
$sp
Address Data
FC
$sp
FC
F8
F8
$a0 (0x3)
F4
F4
$ra
F0
F0
$a0 (0x2)
EC
EC
$ra (0xBC)
E8
E8
$a0 (0x1)
E4
E4
$ra (0xBC)
E0
E0
E0
DC
DC
DC
$sp
$sp
$sp
19
F8
$a0 (0x3)
F4
$ra
F0
$a0 (0x2)
EC
$ra (0xBC)
E8
$a0 (0x1)
E4
$ra (0xBC)
$sp
$v0 = 6
$sp
$a0 = 3
$v0 = 3 x 2
$sp
$a0 = 2
$v0 = 2 x 1
$sp
$a0 = 1
$v0 = 1 x 1
Korea Univ