Beruflich Dokumente
Kultur Dokumente
Weve learned all of the important features of the MIPS instruction set
architecture, so now its time for some examples!
First well see a nested function, which calls another function.
Next up is a demonstration of recursion.
Finally well work with some C-style strings.
This weeks sections will discuss how structures and objects can be stored
and manipulated in MIPS. Youll also get some debugging practice, which
will be useful for the assignment that will appear later today.
February 5, 2003
Combinations
Writing a function to compute combinations based on the fact code from
last time will illustrate the implementation of nested functions.
A mathematical definition of combinations is:
n
k
n!
=
k! (nk)!
February 5, 2003
MIPS examples
MIPS examples
Callee-saved registers
To summarize, comb will need to preserve
and restore four registers:
$ra
$s0
$a0
$a1
February 5, 2003
MIPS examples
comb:
sub
sw
sw
$sp, $sp, 8
$ra, 0($sp)
$s0, 4($sp)
$ra, 0($sp)
$s0, 4($sp)
$sp, $sp, 8
$ra
Caller-saved registers
However, comb is the caller in relation to
the fact function.
This means comb must store the callersaved registers $a0 and $a1 before it
calls fact, and restore them afterwards.
Well allocate two additional words on
the stack for $a0 and $a1. Theyll be
restored as necessary in the function.
Is it possible to preserve $a0 and $a1 in any
of the other registers, instead of the stack?
February 5, 2003
MIPS examples
comb:
sub
sw
sw
sw
sw
$sp,
$ra,
$s0,
$a0,
$a1,
$sp, 16
0($sp)
4($sp)
8($sp)
12($sp)
$ra, 0($sp)
$s0, 4($sp)
$sp, $sp, 16
$ra
# fact(n)
jal
fact
move $s0, $v0
For fact(k):
We have to load k from memory, in case
fact(n) overwrote $a1.
$s0 is updated with fact(n) / fact(k).
# fact(k)
lw
$a0, 12($sp)
jal
fact
div
$s0, $s0, $v0
For fact(n-k):
We have to restore both n and k.
The final result of comb ends up in $s0.
# fact(n-k)
lw
$a0, 8($sp)
lw
$a1, 12($sp)
sub
$a0, $a0, $a1
jal
fact
div
$s0, $s0, $v0
February 5, 2003
MIPS examples
February 5, 2003
MIPS examples
comb:
sub
sw
sw
sw
sw
jal
move
lw
jal
div
lw
lw
sub
jal
div
move
lw
lw
addi
jr
$sp,
$ra,
$s0,
$a0,
$a1,
fact
$s0,
$a0,
fact
$s0,
$a0,
$a1,
$a0,
fact
$s0,
$v0,
$ra,
$s0,
$sp,
$ra
$sp, 16
0($sp)
4($sp)
8($sp)
12($sp)
$v0
12($sp)
$s0, $v0
8($sp)
12($sp)
$a0, $a1
$s0, $v0
$s0
0($sp)
4($sp)
$sp, 16
fib(n) =
0
1
fib(n-1) + fib(n-2)
if n=0
if n=1
otherwise
The translation to MIPS is not bad if you understood the first example.
February 5, 2003
MIPS examples
February 5, 2003
MIPS examples
int fib(int n)
{
if (n <= 1)
return n;
else
return fib(n-1) + fib(n-2);
}
fib:
bgt
$a0, 1,recurse
move $v0, $a0
jr
$ra
February 5, 2003
MIPS examples
10
recurse:
sub
$sp, $sp, 12
sw
$ra, 0($sp)
sw
$a0, 4($sp)
addi $a0, $a0, -1
jal
fib
sw
$v0, 8($sp)
lw
$a0, 4($sp)
addi $a0, $a0, -2
jal
fib
lw
add
MIPS examples
$v1, 8($sp)
$v0, $v0, $v1
lw
$ra, 0($sp)
addi $sp, $sp, 12
jr
$ra
11
$a0,
fib
$v0,
$a0,
$a0,
fib
$v1,
$v0,
$a0, -1
8($sp)
4($sp)
$a0, -2
8($sp)
$v0, $v1
lw
$ra, 0($sp)
addi $sp, $sp, 12
jr
$ra
February 5, 2003
MIPS examples
12
Representing strings
A C-style string is represented by an array of bytes.
Elements are one-byte ASCII codes for each character.
A 0 value marks the end of the array.
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
space
!
#
$
%
&
(
)
*
+
,
.
/
February 5, 2003
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
MIPS examples
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
`
a
b
c
d
e
f
g
h
I
j
k
l
m
n
o
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
del
13
String manipulation
For example, Harry Potter can be stored as a 13-byte array.
72
97
32
80
P
0
\0
February 5, 2003
MIPS examples
14
February 5, 2003
MIPS examples
15
Array version
A direct translation of the array version means each iteration of the loop
must re-compute the address of str[i]requiring two additions.
toupper:
li
$t0,
loop:
add $t1,
lb
$t2,
beq $t2,
blt $t2,
bgt $t2,
sub $t2,
sb
$t2,
next:
addi $t0,
j
loop
exit:
jr
$ra
# $t0 = i
$t0, $a0
0($t1)
$0, exit
97, next
122, next
$t2, 32
0($t1)
#
#
#
#
#
#
#
$t0, 1
# i++
$t1 = &str[i]
$t2 = str[i]
$t2 = 0?
$t2 < 97?
$t2 > 122?
convert
and store back
Here we work with bytes, but if the array contained integers, this address
computation would require a multiplication as well.
February 5, 2003
MIPS examples
16
Pointer version
Instead, we could use a register to hold the exact address of the current
element. Each time through the loop, well increment this register to
point to the next element.
toupper:
lb
$t2, 0($a0)
beq $t2, $0, exit
blt $t2, 97, next
bgt $t2, 122, next
sub $t2, $t2, 32
sb
$t2, 0($a0)
next:
addi $a0, $a0, 1
j
toupper
exit:
jr
$ra
#
#
#
#
#
#
$t2 = *s
$t2 = 0?
$t2 < 97?
$t2 > 122?
convert
and store back
# s++
MIPS examples
17
Side by side
toupper:
li
$t0,
loop:
add $t1,
lb
$t2,
beq $t2,
blt $t2,
bgt $t2,
sub $t2,
sb
$t2,
next:
addi $t0,
j
loop
exit:
jr
$ra
toupper:
0
$t0, $a0
0($t1)
$0, exit
97, next
122, next
$t2, 32
0($t1)
lb
beq
blt
bgt
sub
sb
next:
addi
j
exit:
jr
$t0, 1
$t2, 0($a0)
$t2, $0, exit
$t2, 97, next
$t2, 122, next
$t2 $t2, 32
$t2, 0($a0)
$a0, $a0, 1
toupper
$ra
February 5, 2003
MIPS examples
18
Summary
These three examples demonstrate that writing large, modular programs
in assembly language is difficult!
Its hard to figure out how to best use the limited number of registers.
(Register allocation is an important problem in writing compilers.)
We must always follow the MIPS function call conventions regarding
the passing and returning of values and preservation of registers.
There is only one addressing mode that must be used for all memory
accesses, whether to arguments or stack-allocated space.
Youll get some good programming practice on the machine problem.
February 5, 2003
MIPS examples
19