AnneBracy
CS3410
ComputerScience
CornellUniversity
The slides are the product of many rounds of teaching CS 3410 by
Professors Weatherspoon, Bala, Bracy, McKee, and Sirer.
register
file
alu
B
D
program
memory
D
A
compute
jump/branch
targets
+4
Instruction
Decode
Instruction
Fetch
IF/ID
ctrl
detect
hazard
ID/EX
M
dout
forward
unit
Execute
EX/MEM
Memory
ctrl
new
pc
din
memory
ctrl
extend
B
control
imm
inst
PC
addr
WriteBack
MEM/WB
2
CPU
MainMemory
(DRAM)
register
file
B
D
alu
D
A
compute
jump/branch
targets
program
memory
+4
IF/ID
ID/EX
din
Memory
dout
M
B
memory
forward
unit
Execute
EX/MEM
ctrl
Instruction
Decode
ctrl
detect
hazard
Instruction
Fetch
SandyBridge Motherboard,2011
http://news.softpedia.com
imm
inst
addr
control
extend
new
pc
ctrl
PC
WriteBack
MEM/WB
3
0xfffffffc
top
systemreserved
0x80000000
0x7ffffffc
stack
“DataMemory”
dynamicdata(heap)
0x10000000
0x00400000
0x00000000
staticdata
code(text)
systemreserved
“ProgramMemory”
bottom
4
Stackcontainsstackframes(aka“activationrecords”)
•
•
•
•
1stackframeperdynamicfunction
Existsonlyforthedurationoffunction
Growsdown,“top”ofstackis$sp,r29
Example:lw $r1,0($sp)putswordattopofstackinto$r1
Eachstackframecontains:
• Localvariables,returnaddress(later),register
backups(later)
int main(…) {
...
myfn(x);
}
int myfn(int n) {
...
myfn();
}
systemreserved
stack
$spà
main stackframe
myfn stackframe
myfn stackframe
heap
staticdata
code
systemreserved
5
Heapholdsdynamicallyallocatedmemory
• Programmustmaintainpointerstoanythingallocated
•
•
Example:if$r3holdsx
lw $r1,0($r3)getsfirstwordxpointsto
• Dataexistsfrommalloc()tofree()
systemreserved
void some_function() {
int *x = malloc(1000);
int *y = malloc(2000);
free(y);
int *z = malloc(3000);
}
x
y
z
stack
3000bytes
2000bytes
heap
staticdata
code
systemreserved
1000bytes
6
Datasegmentcontainsglobalvariables
• Existforalltime,accessibletoallroutines
• Accessedw/globalpointer
•
•
$gp,r28,pointstomiddleofsegment
Example:lw $r1,0($gp)getsmiddle-mostword
(here,max_players)
int max_players = 4;
int main(...) {
...
}
systemreserved
stack
heap
staticdata
code
systemreserved
gpà
4
7
Variables
Visibility
Lifetime
Location
Function-Local
Global
Dynamic
int n = 100;
int main (int argc, char* argv[ ]) {
int i, m = n, sum = 0;
int* A = malloc(4*m + 4);
for (i = 1; i <= m; i++) {
sum += i; A[i] = sum; }
printf ("Sum 1 to %d is %d\n", n, sum);
}
8
Variables
Visibility
Lifetime
Function-Local
w/infunction
function
invocation
Global
program
wholeprogram
execution
Anywherethat b/wmalloc
hasapointer
andfree
i,m,sum,A
Dynamic
n,str
*A
int n = 100;
int main (int argc, char* argv[ ]) {
int i, m = n, sum = 0;
int* A = malloc(4*m + 4);
for (i = 1; i <= m; i++) {
sum += i; A[i] = sum; }
printf ("Sum 1 to %d is %d\n", n, sum);
}
Location
stack
.data
heap
9
Don’teverwritecodelikethis!
Danglingpointers
intofreedheapmem
void some_function() {
int *x = malloc(1000);
int *y = malloc(2000);
free(y);
int *z = malloc(3000);
y[20] = 7;
}
Danglingpointers
intooldstackframes
void f1() {
int *x = f2();
int y = *x + 2;
}
int *f2() {
int a = 3;
return &a;
}
10
Whichofthefollowingistrouble-freecode?
A
C
int *bubble()
{ int a;
…
return &a;
}
int *toil()
{ s = malloc(20);
…
return s;
}
B
char *rubble()
{ char s[20];
gets(s);
return s;
}
D
int *trouble()
{ s = malloc(20);
…
free(s);
…
return s;
}
11
int main (int argc, char* argv[ ]) {
int n = 9;
int result = myfn(n);
}
int myfn(int n) {
int f = 1;
int i = 1;
int j = n – 1;
while(j >= 0) {
f *= i;
i++;
j = n - i;
}
return f;
}
12
TransferControl
• Callerà Routine
• Routineà Caller
PassArgumentstoandfromtheroutine
• fixedlength,variablelength,recursively
• Getreturnvaluebacktothecaller
ManageRegisters
• Alloweachroutinetouseregisters
• Preventroutinesfromclobberingeachothers’data
WhatisaConvention?
Warning: ThereisnoonetrueMIPScallingconvention.
13
lecture!=book!=gcc !=spim !=web
1
main:
3
j myfn
after1:
…
2
add $1,$2,$3
j myfn
after2:
myfn:
4
sub $3,$4,$5
…
j after1 j after2
???Changetarget
onthefly???
Jumpstothecallee
Jumpsback
Whataboutmultiplesites?
14
Firstcall
r31 after1
1
main:
jal myfn
after1:
myfn:
…
2
add $1,$2,$3
jal myfn
…
jr $31
after2:
sub $3,$4,$5
JALsavesthePCinregister$31
Subroutinereturnsbyjumpingto$31
15
Secondcall
r31 after2
1
main:
3
jal myfn
after1:
2
add $1,$2,$3
jal myfn
after2:
myfn:
…
…
jr $31
4
sub $3,$4,$5
JALsavesthePCinregister$31
Subroutinereturnsbyjumpingto$31
Whathappensforrecursiveinvocations?
16
Firstcall
r31 after1
1
main:
myfn:
if (test)
jal myfn
jal myfn
after1:
add $1,$2,$3
after2:
jr $31
Problemswithrecursion:
•
overwritescontentsof$31
17
RecursiveCall
1
main:
2
myfn:
if (test)
jal myfn
jal myfn
after1:
add $1,$2,$3
r31 after2
after2:
jr $31
Problemswithrecursion:
•
overwritescontentsof$31
18
ReturnfromRecursiveCall
1
2
myfn:
main:
if (test)
jal myfn
jal myfn
after1:
add $1,$2,$3
r31 after2
3
after2:
jr $31
Problemswithrecursion:
•
overwritescontentsof$31
19
ReturnfromOriginalCall???
1
2
myfn:
main:
if (test)
jal myfn
jal myfn
after1:
add $1,$2,$3
r31 after2
3
after2:
4
Stuck!
jr $31
Problemswithrecursion:
•
overwritescontentsof$31
20
StackManipulatedbypush/pop operations
Context:after2nd JALtomyfn (frommyfn)
PUSH: ADDIU$sp,$sp,-20//movespdown
SW$31,16($sp)//storeretn
PC1st
Context:2nd myfn isdone(r31==???)
POP: LW$31,16($sp) //restoreretn PCàr31
x2000
ADDIU$sp,$sp,20//movespup
JR$31
//return
r29 x1FD0
x2000
r31 XXXX
after2
x1FD0
mainstackframe
myfn stackframe
after2
myfn stackframe
Fornow:Assumeeachframe=x20bytes
(justtomakethisexampleconcrete) 21
WhydoweneedaJALinstructionforprocedurecalls?
A. TheonlywaytochangethePCofyourprogramis
withaJALinstruction.
B. Thesystemwon’tletyoujumptoaprocedurewith
justaJMPinstruction.
C. IfyouJMPtoafunction,itdoesn’tknowwhereto
returntouponcompletion.
D. Actually,JALonlyworksforthefirstfunctioncall.
Withmultipleactivefunctions,JALisnottheright
instructiontouse.
22
TransferControl
• Callerà Routine
• Routineà Caller
PassArgumentstoandfromtheroutine
• fixedlength,variablelength,recursively
• Getreturnvaluebacktothecaller
ManageRegisters
• Alloweachroutinetouseregisters
• Preventroutinesfromclobberingeachothers’data
23
main() {
int x = myfn(6, 7);
x = x + 2;
}
main:
li $a0, 6
li $a1, 7
jal myfn
addi $r1, $v0, 2
Firstfourarguments:
passedinregisters$4-$7
• aka$a0,$a1,$a2,$a3
Returnedresult:
passedbackinaregister
• Specifically,$2,aka$v0
Note:Thisisnottheentirestoryfor1-4arguments.
PleaseseetheFullStoryslides.
24
main() {
myfn(0,1,2,3,4,5);
…
}
main:
li $a0, 0
li $a1, 1
li $a2, 2
li $a3, 3
addiu $sp,$sp,-8
li $8, 4
sw $8, 0($sp)
li $8, 5
sw $8, 4($sp)
jal myfn
Firstfourarguments:
passedin$4-$7
• aka$a0-$a3
spà
spà
5
4
Subsequentarguments:
”spill”ontothestack
Note:Thisisnottheentirestoryfor5+arguments.
PleaseseetheFullStoryslides.
25
main() {
myfn(0,1,2,3,4,5);
…
}
spà
5
main:
4
li $a0, 0
spacefora3
li $a1, 1
spacefora2
li $a2, 2
li $a3, 3
spacefora1
addiu $sp,$sp,-24 spà spacefora0
li $8, 4
sw $8, 16($sp)
li $8, 5
sw $8, 20($sp)
jal myfn
20($sp)
16($sp)
12($sp)
Arguments1-4:
passedin$4-$7
roomonstack
Arguments5+:
placedonstack
8($sp)
4($sp)
0($sp)
Stackdecrementedby
max(16,#args x4)
Here:max(16,24)=24
26
• Consistentwayofpassingargumentstoand
fromsubroutines
• Createssinglelocationforallarguments
• Callermakesroomfor$a0-$a3onstack
• Callee mustcopyvaluesfrom$a0-$a3tostack
à callee maytreatallargs asanarrayinmemory
•
Particularlyhelpfulforfunctionsw/variablelength
inputs:printf(“Scores: %d %d %d\n”, 1, 2, 3);
• Aside:notabadplacetostoreinputsifcallee
needstocallafunction(yourinputcannotstay
in$a0ifyouneedtocallanotherfunction!)
27
Callowspassingwholestructs
• int dist(struct Point p1, struct Point p2);
• Treatedascollectionofconsecutive32-bitarguments
– Registersforfirst4words,stackforrest
• Better:int dist(struct Point *p1, struct Point *p2);
Wherearetheargumentsto:
void sub(int a, int b, int c, int d, int e);
void isalpha(char c);
void treesort(struct Tree *root);
Wherearethereturnvaluesfrom:
struct Node *createNode();
struct Node mynode();
Manycombinationsofchar,short,int,void*,struct,etc.
• MIPStreatschar,short,int andvoid*identically
28
Whichisatruestatementabouttheargumentstothe
function
void sub(int a, int b, int c, int d, int e);
A. Argumentsa-e areallpassedinregisters.
B. Argumentsa-e areallstoredonthestack.
C. Onlyeisstoredonthestack,butspaceis
allocatedforall5arguments.
D. Onlya-darestoredonthestack,butspaceis
allocatedforall5arguments.
29
Notice
blue’sRetAddr • Pink’sargumentsareonblue’s stack
blue’s
5
• spchangesasfunctionscallother
stack
4
functions, complicatesaccesses
frame spacefora3
à
Convenienttokeeppointerto
spacefora2
bottomofstack==framepointer
spacefora1
$30,aka$fp
spà spacefora0
canbeusedtorestore$sponexit
pink’sRetAddr ß fp
spà
pink’s
stack
frame
blue() {
pink(0,1,2,3,4,5);
}
pink(int a, int b, int c, int d, int e, int f) {
…
}
30
TransferControl
• Callerà Routine
• Routineà Caller
PassArgumentstoandfromtheroutine
• fixedlength,variablelength,recursively
• Getreturnvaluebacktothecaller
ManageRegisters
• Alloweachroutinetouseregisters
• Preventroutinesfromclobberingeachothers’data
31
Functions:
• Arecompiledinisolation
• Makeuseofgeneralpurposeregisters
• Callotherfunctionsinthemiddleoftheirexecution
•
•
Thesefunctionsalsousegeneralpurposeregisters!
Nowaytocoordinatebetweencaller&callee
à Needaconventionforregistermanagement
32
Registersthatthecallercaresabout:$t0…$t9
Abouttocallafunction?
•
•
Needvalueinat-registerafterfunctionreturns?
à saveittothestackbeforefn call
à restoreitfromthestackafterfn returns
Don’tneedvalue?à donothing
Suppose:
$t0holdsx
$t1holdsy
$t2holdsz
Wheredowesaveandrestore?
Functions
• Canfreelyusetheseregisters
• Mustassumethattheircontents
aredestroyedbyotherfunctions
void myfn(int a) {
int x = 10;
int y = max(x, a);
int z = some_fn(y);
return (z + y);
}
33
Registersafunctionintendstouse:$s0…$s9
Abouttouseans-register?YouMUST:
•
•
Savethecurrentvalueonthestackbeforeusing
Restoretheoldvaluefromthestackbeforefn returns
Functions
• Mustsavetheseregistersbefore
usingthem
• Mayassumethattheircontents
arepreservedevenacrossfn calls
Suppose:
$t0holdsx
$s1holdsy
$s2holdsz
Wheredowesaveandrestore?
void myfn(int a) {
int x = 10;
int y = max(x, a);
int z = some_fn(y);
return (z + y);
}
34
main:
…
[use$t0&$t1]
…
addiu $sp,$sp,-8
sw $t1,4($sp)
sw $t0,0($sp)
jal mult
lw $t1,4($sp)
lw $t0,0($sp)
addiu $sp,$sp,8
…
[use$t0&$t1]
Assumetheregistersarefreeforthe
taking,usewithnooverhead
Sincesubroutineswilldothesame,
mustprotectvaluesneededlater:
Savebeforefn call
Restoreafterfn call
Notice:Goodregisterstouseifyou
don’tcalltoomanyfunctionsorifthe
valuesdon’tmatterlateronanyway.
35
main:
addiu $sp,$sp,-32
sw $ra,28($sp)
sw $fp,24($sp)
sw $s1,20($sp)
sw $s0,16($sp)
addiu $fp,$sp,28
…
[use$s0and$s1]
…
lw $ra,28($sp)
lw $fp,24($sp)
lw $s1,20$sp)
lw $s0,16($sp)
addiu $sp,$sp,32
jr $ra
Assumecallerisusingtheregisters
Saveonentry
Restoreonexit
Notice:Goodregisterstouseifyoumakea
lotoffunctioncallsandneedvaluesthat
arepreservedacrossallofthem.
Also,goodifcallerisactuallyusingthe
registers,otherwisethesaveandrestores
arewasted.Buthardtoknowthis.
36
•
•
•
•
firstfourarg wordspassedin$a0-$a3
remainingargs passedinparent’sstackframe
returnvalue(ifany)in$v0,$v1
stackframe($fpto$sp)contains:
•
•
•
•
$fpà
$ra (clobberedonJALs)
localvariables
spacefor4argumentstoCallees
arguments5+toCallees
• callee saveregs:preserved
• callersaveregs:notpreserved
• globaldataaccessedvia$gp
savedra
savedfp
savedregs
($s0...$s7)
locals
$spà
outgoing
args 37
r0
r1
r2
r3
r4
r5
r6
r7
r8
r9
r10
r11
r12
r13
r14
r15
$zero
zero
$at assemblertemp
$v0
function
returnvalues
$v1
$a0
$a1
function
arguments
$a2
$a3
$t0
$t1
$t2
$t3
temps
$t4
(callersave)
$t5
$t6
$t7
r16
r17
r18
r19
r20
r21
r22
r23
r24
r25
r26
r27
r28
r29
r30
r31
$s0
$s1
$s2
$s3
$s4
$s5
$s6
$s7
$t8
$t9
$k0
$k1
$gp
$sp
$fp
$ra
saved
(callee save)
moretemps
(caller save)
reservedfor
kernel
globaldatapointer
stackpointer
framepointer
returnaddress
38
fpà
savedra
savedfp
savedregs
($s0...$s7)
locals
spà
outgoing
args
Assumeafunctionusestwocalleesaveregisters.
Howdoweallocateastackframe?
Howlargeisthestackframe?
Whatshouldbestoredinthestack
frame?
Whereshouldeverythingbe
stored?
39
fpà
savedra
savedfp
savedregs
($s0...$s7)
locals
spà
outgoing
args
ADDIU$sp,$sp,-32
SW$ra,28($sp)
SW$fp,24($sp)
SW$s1,20($sp)
SW$s0,16($sp)
ADDIU$fp,$sp,28
…
BODY
…
LW$s0,16($sp)
LW$s1,20($sp)
LW$fp,24($sp)
LW$ra,28($sp)
ADDIU$sp,$sp,32
JR$ra
#allocateframe
#save$ra
#saveold$fp
#save...
#save...
#setnewframeptr
...
...
#restore…
#restore…
#restoreold$fp
#restore$ra
#dealloc frame
40
blue’s
stack
frame
pink’s
stack
frame
fpà
orange
stack
frame
spà
blue’sra
savedfp
savedregs
args forpink
pink’sra
blue’sfp
savedregs
x
args fororange
orange’sra
pink’sfp
savedregs
buf[100]
blue() {
pink(0,1,2,3,4,5);
}
pink(int a, int b, int c, int d, int e, int f) {
int x;
orange(10,11,12,13,14);
}
orange(int a, int b, int c, int, d, int e) {
char buf[100];
gets(buf);
// no bounds check!
}
Whathappensifmorethan100bytes
iswrittentobuf?
41
Leaffunctiondoesnotinvokeanyotherfunctions
int f(int x, int y) {
return (x+y);
}
$fpà
Optimizations?
Nosavedregs (orlocals)
Nooutgoingargs
Don’tpush$ra
Noframeatall?Possibly…
savedra
savedfp
savedregs
($s0...$s7)
locals
$spà
outgoing
args
42
int test(int a, int b) {
int tmp = (a&b)+(a|b);
int s = sum(tmp,1,2,3,4,5);
int u = sum(s,tmp,b,a,b,a);
return u + a + b;
}
CorrectOrder:
1. BodyFirst
2. Determinestackframesize
3. CompletePrologue/Epilogue
43
int test(int a, int b) {
int tmp = (a&b)+(a|b);
int s = sum(tmp,1,2,3,4,5);
int u = sum(s,tmp,b,a,b,a);
return u + a + b;
}
We’llassumetheyellowinorderto
forceyourhandontherest.
$s0for$a0/a
$s1for$a1/b
$t0fortmp
CanwegetridoftheNOP?
Wewanttodothelw…
test:
Prologue
MOVE$s0,$a0
MOVE$s1,$a1
AND$t0,$a0,$a1
OR$t1,$a0,$a1
ADD$t0,$t0,$t1
MOVE$a0,$t0
LI$a1,1
LI$a2,2
LI$a3,3
LI$t1,4
SW$t116($sp)
LI$t1,5
SW$t1,20($sp)
SW$t0,24($sp)
JALsum
NOP
LW$t0,24($sp) 44
int test(int a, int b) {
int tmp = (a&b)+(a|b);
int s = sum(tmp,1,2,3,4,5);
int u = sum(s,tmp,b,a,b,a);
return u + a + b;
}
MOVE$a0,$v0#s
MOVE$a1,$t0#tmp
MOVE$a2,$s1#b
MOVE$a3,$s0#a
SW$s1,16($sp)#b
SW$s0,20($sp)#a
JALsum
NOP
ADD$v0,$v0,$s0#u+a
ADD$v0,$v0,$s1#+b
Epilogue
45
int test(int a, int b) {
int tmp = (a&b)+(a|b);
int s = sum(tmp,1,2,3,4,5);
int u = sum(s,tmp,b,a,b,a);
return u + a + b;
}
savedra
How many bytes do
savedfp
we need to allocate
savedregs
for the stack frame?
($s0and$s1)
a) 24
b) 36
locals
c) 44
($t0)
d) 48
outgoingargs
e) 52
Minimumstacksizefor spacefora0- a3
th and6th arg
and5
astandardfunction?
46
int test(int a, int b) {
int tmp = (a&b)+(a|b);
int s = sum(tmp,1,2,3,4,5);
int u = sum(s,tmp,b,a,b,a);
return u + a + b;
}
How many bytes do
we need to allocate
for the stack frame?
44
Minimumstacksizefor
astandardfunction?
$ra +$fp+4args =
6x4bytes=24bytes
savedra
savedfp
savedregs
($s0and$s1)
locals
($t0)
outgoingargs
spacefora0- a3
and5th and6th arg
fpà 40
36
32
28
24
20
16
12
8
4
spà 0
savedra
savedfp
savedreg $s1
savedreg $s0
local$t0
outgoing6th arg
outgoing5th arg
spacefor$a3
spacefor$a2
spacefor$a1
spacefor$a0
47
#allocateframe
#save$ra
#saveold$fp
#callee save...
#callee save...
#setnewframeptr
...
...
#restore…
#restore…
#restoreold$fp
#restore$ra
#dealloc frame
48
savedra
savedfp
36
savedreg $s1
32
savedreg $s0
28
24
local$t0
20 outgoing6th arg
16 outgoing5th arg
12
spacefor$a3
8
spacefor$a2
4
spacefor$a1
spà 0 spacefor$a0
fpà 40
ADDIU$sp,$sp,-44
SW$ra,40($sp)
SW $fp,36($sp)
SW$s1,32($sp)
SW$s0,28($sp)
ADDIU$fp,$sp,40
Body
(previousslide,Activity#1)
LW$s0,28($sp)
LW $s1,32($sp)
LW$fp,36($sp)
LW$ra,40($sp)
ADDIU$sp,$sp,44
JR$ra
NOP
#allocateframe
#save$ra
#saveold$fp
#callee save...
#callee save...
#setnewframeptr
...
...
#restore…
#restore…
#restoreold$fp
#restore$ra
#dealloc frame
49
© Copyright 2026 Paperzz