Anne Bracy CS 3410 Computer Science Cornell University

Similar documents
See P&H 2.8 and 2.12, and A.5-6. Prof. Hakim Weatherspoon CS 3410, Spring 2015 Computer Science Cornell University

Hakim Weatherspoon CS 3410 Computer Science Cornell University

Prof. Kavita Bala and Prof. Hakim Weatherspoon CS 3410, Spring 2014 Computer Science Cornell University. See P&H 2.8 and 2.12, and A.

Anne Bracy CS 3410 Computer Science Cornell University

Calling Conventions. Hakim Weatherspoon CS 3410, Spring 2012 Computer Science Cornell University. See P&H 2.8 and 2.12

Anne Bracy CS 3410 Computer Science Cornell University

Calling Conventions. See P&H 2.8 and Hakim Weatherspoon CS 3410, Spring 2013 Computer Science Cornell University

Lec 10: Assembler. Announcements

Calling Conventions! Hakim Weatherspoon CS 3410, Spring 2011 Computer Science Cornell University. See P&H 2.8 and 2.12

CS 316: Procedure Calls/Pipelining

Do-While Example. In C++ In assembly language. do { z--; while (a == b); z = b; loop: addi $s2, $s2, -1 beq $s0, $s1, loop or $s2, $s1, $zero

6.1. CS356 Unit 6. x86 Procedures Basic Stack Frames

CSE Lecture In Class Example Handout

Implementing Procedure Calls

CS153: Compilers Lecture 8: Compiling Calls

Memory Usage 0x7fffffff. stack. dynamic data. static data 0x Code Reserved 0x x A software convention

COMP 303 Computer Architecture Lecture 3. Comp 303 Computer Architecture

CS 61C: Great Ideas in Computer Architecture More MIPS, MIPS Functions

Lectures 5. Announcements: Today: Oops in Strings/pointers (example from last time) Functions in MIPS

Procedure Call and Return Procedure call

Syscalls, exceptions, and interrupts, oh my!

CS 61c: Great Ideas in Computer Architecture

We can emit stack-machine-style code for expressions via recursion

MIPS Functions and Instruction Formats

ECE260: Fundamentals of Computer Engineering

MIPS Functions and the Runtime Stack

Course Administration

Code Generation. Lecture 12

EN164: Design of Computing Systems Lecture 11: Processor / ISA 4

MIPS Procedure Calls. Lecture 6 CS301

ECE232: Hardware Organization and Design

Mark Redekopp, All rights reserved. EE 352 Unit 6. Stack Frames Recursive Routines

Code Generation. The Main Idea of Today s Lecture. We can emit stack-machine-style code for expressions via recursion. Lecture Outline.

Functions in MIPS. Functions in MIPS 1

CS 110 Computer Architecture Lecture 6: More MIPS, MIPS Functions

Lecture 7: Procedures and Program Execution Preview

Compiling Code, Procedures and Stacks

Hakim Weatherspoon CS 3410 Computer Science Cornell University

Today. Putting it all together

Arguments and Return Values. EE 109 Unit 16 Stack Frames. Assembly & HLL s. Arguments and Return Values

CS 61C: Great Ideas in Computer Architecture More RISC-V Instructions and How to Implement Functions

Lecture Outline. Topic 1: Basic Code Generation. Code Generation. Lecture 12. Topic 2: Code Generation for Objects. Simulating a Stack Machine

Code Generation. Lecture 19

Review of Activation Frames. FP of caller Y X Return value A B C

Systems Architecture I

Lecture 5. Announcements: Today: Finish up functions in MIPS

Stacks and Procedures

Prof. Kavita Bala and Prof. Hakim Weatherspoon CS 3410, Spring 2014 Computer Science Cornell University. P&H Chapter 4.9, pages , appendix A.

MIPS Programming. A basic rule is: try to be mechanical (that is, don't be "tricky") when you translate high-level code into assembler code.

EE 109 Unit 15 Subroutines and Stacks

UCB CS61C : Machine Structures

CA Compiler Construction

Control Instructions. Computer Organization Architectures for Embedded Computing. Thursday, 26 September Summary

Control Instructions

Lecture 5: Procedure Calls

Lecture 7: Procedures

Subroutines. int main() { int i, j; i = 5; j = celtokel(i); i = j; return 0;}

Lecture 5: Procedure Calls

Language of the Machine Recursive functions

CS 61C: Great Ideas in Computer Architecture. More MIPS, MIPS Functions

Procedures and Stacks

Assembly labs start this week. Don t forget to submit your code at the end of your lab section. Download MARS4_5.jar to your lab PC or laptop.

CSE Lecture In Class Example Handout

Chapter 2. Computer Abstractions and Technology. Lesson 4: MIPS (cont )

CS429: Computer Organization and Architecture

Branch Addressing. Jump Addressing. Target Addressing Example. The University of Adelaide, School of Computer Science 28 September 2015

Stacks and Procedures

CENG3420 Lecture 03 Review

Compilers and computer architecture: A realistic compiler to MIPS

Instruction Set Architectures (4)

CS61C : Machine Structures

2/16/2018. Procedures, the basic idea. MIPS Procedure convention. Example: compute multiplication. Re-write it as a MIPS procedure

Lecture 2. Instructions: Language of the Computer (Chapter 2 of the textbook)

Procedure Calls. Young W. Lim Mon. Young W. Lim Procedure Calls Mon 1 / 29

More C functions and Big Picture [MIPSc Notes]

143A: Principles of Operating Systems. Lecture 5: Calling conventions. Anton Burtsev January, 2017

Function Calling Conventions 1 CS 64: Computer Organization and Design Logic Lecture #9

238P: Operating Systems. Lecture 3: Calling conventions. Anton Burtsev October, 2018

Lecture 6: Assembly Programs

CSC 2400: Computing Systems. X86 Assembly: Function Calls

ECE260: Fundamentals of Computer Engineering. Supporting Procedures in Computer Hardware

The Activation Record (AR)

The plot thickens. Some MIPS instructions you can write cannot be translated to a 32-bit number

CSC 2400: Computing Systems. X86 Assembly: Function Calls"

Instruction Set Architecture part 1 (Introduction) Mehran Rezaei

SPIM Procedure Calls

CSC258: Computer Organization. Functions and the Compiler Tool Chain

Assembly Language: Function Calls" Goals of this Lecture"

CS 61C: Great Ideas in Computer Architecture (Machine Structures) More MIPS Machine Language

Computer Science 2500 Computer Organization Rensselaer Polytechnic Institute Spring Topic Notes: MIPS Programming

143A: Principles of Operating Systems. Lecture 4: Calling conventions. Anton Burtsev October, 2017

The plot thickens. Some MIPS instructions you can write cannot be translated to a 32-bit number

CS61C : Machine Structures

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

Run-time Environment

Assembly Language: Function Calls" Goals of this Lecture"

Agenda. Strings: C vs. Java. Loading, Storing bytes. Support for Characters and Strings 6/29/2011

Assembly Language: Function Calls

Procedure Calls. Young W. Lim Sat. Young W. Lim Procedure Calls Sat 1 / 27

Computer Architecture. Chapter 2-2. Instructions: Language of the Computer

Transcription:

Anne Bracy CS 3410 Computer Science Cornell University The slides are the product of many rounds of teaching CS 3410 by Professors Weatherspoon, Bala, Bracy, McKee, and Sirer. See P&H 2.8 and 2.12, and A.5-6

first four arg words passed in $a0, $a1, $a2, $a3 remaining arg words passed in parent s stack frame return value (if any) in $v0, $v1 stack frame at $sp contains $ra (clobbered on JAL to sub-functions) $fp à contains local vars (possibly clobbered by sub-functions) contains extra arguments to sub-functions contains space for first 4 arguments to sub-functions callee save regs: preserved caller save regs: not preserved Global data accessed via $gp $sp à saved ra saved fp saved regs ($s0... $s7) locals outgoing args

Return address: $31 (ra) Stack pointer: $29 (sp) Frame pointer: $30 (fp) First four arguments: $4-$7 (a0-a3) Return result: $2-$3 (v0-v1) Callee-save free regs: $16-$23 (s0-s7) Caller-save free regs: $8-$15,$24,$25 (t0-t9) Reserved: $26, $27 Global pointer: $28 (gp) Assembler temporary: $1 (at)

r0 $zero zero r1 $at assembler temp r2 $v0 function r3 $v1 return values r4 $a0 r5 $a1 r6 $a2 r7 $a3 r8 $t0 r9 $t1 r10 $t2 r11 $t3 r12 $t4 r13 $t5 r14 $t6 r15 $t7 function arguments temps (caller save) r16 $s0 r17 $s1 r18 $s2 r19 $s3 saved r20 $s4 (callee save) r21 $s5 r22 $s6 r23 $s7 r24 $t8 more temps r25 $t9 (caller save) r26 $k0 reserved for r27 $k1 kernel r28 $gp global data pointer r29 $sp stack pointer r30 $fp frame pointer r31 $ra return address

int main (int argc, char* argv[ ]) { int n = 9; int result = multi(n); } int multi(int n) { int f = 1; int i = 1; int j = n 1; while(j >= 0) { f *= i; i++; j = n - i; } return f; }

Calling Convention for Procedure Calls Enable code to be reused by allowing code snippets to be invoked Will need a way to call the routine (i.e. transfer control to procedure) pass arguments fixed length, variable length, recursively return to the caller Putting results in a place where caller can find them Manage registers Warning: There is no one true MIPS calling convention. lecture!= book!= gcc!= spim!= web

main: j mult Lafter1: add $1,$2,$3 j mult Lafter2: sub $3,$4,$5 mult: j Lafter1 j Lafter2 Not correct. How do We know what location to return to? Jumps and branches can transfer control to the callee (called procedure) Jumps and branches can transfer control back What happens when there are multiple calls from different call sites?

JAL (Jump And Link) instruction moves a new value into the PC, and simultaneously saves the old value in register $31 (aka $ra or return address) Thus, can get back from the subroutine to the instruction immediately following the jump by transferring control back to PC in register $31

main: jal mult Lafter1: add $1,$2,$3 jal mult Lafter2: sub $3,$4,$5 mult: jr $31 JAL saves the PC in register $31 Subroutine returns by jumping to $31 What happens for recursive invocations?

int main (int argc, char* argv[ ]) { int n = 9; int result = multi(n); } int multi(int n) { int f = 1; int i = 1; int j = n 1; while(j >= 0) { f *= i; i++; j = n - i; } return f; }

int main (int argc, char* argv[ ]) { int n = 9; int result = multi(n); } What happens for recursive invocations? int multi(int n) { } if(n == 0) { return 1; } else { return n * multi(n - 1); }

main: jal mult Lafter1: add $1,$2,$3 jal mult Lafter2: sub $3,$4,$5 mult: beq $4, $0, Lout... jal mult Linside: Lout: jr $31 What happens for recursive invocations? Recursion overwrites contents of $31 Need to save and restore the register contents

$29 Call stack contains activation records (aka stack frames) high mem $31 Linside Each activation record contains return address for that invocation local variables for procedure (later) A stack pointer (sp) keeps track of the top of the stack dedicated register ($29) on the MIPS Manipulated by push/pop operations push: move sp down, store pop: load, move sp up sp sp low mem RA = RA = Lafter1 Linside Push: ADDIU $sp, $sp, -4 SW $31, 0 ($sp)

$29 Call stack contains activation records (aka stack frames) high mem $31 Linside xxxx Each activation record contains return address for that invocation local variables for procedure (later) A stack pointer (sp) keeps track of the top of the stack dedicated register ($29) on the MIPS Manipulated by push/pop operations push: move sp down, store pop: load, move sp up sp sp RA = RA = Lafter1 Linside Push: ADDIU $sp, $sp, -4 SW $31, 0 ($sp) Pop: LW $31, 0 ($sp) ADDIU $sp, $sp, 4 low mem JR $31

(Call) Stacks start at a high address in memory Stacks grow down as frames are pushed on Note: data region starts at a low address and grows up The growth potential of stacks and data region are not artificially limited

0xfffffffc 0x80000000 0x7ffffffc system reserved stack top 0x10000000 0x00400000 0x00000000 dynamic data (heap) static data code (text) system reserved bottom.data.text

compute jump/branch targets memory PC +4 new pc Instruction Fetch inst register file $29 ($sp) $31 ($ra) control extend detect hazard Instruction Decode imm B A ctrl alu forward unit Execute d in addr d out memory Memory Write- Back IF/ID ID/EX EX/MEM MEM/WB B D ctrl Stack, Data, Code Stored in Memory D M ctrl

JAL (Jump And Link) instruction moves a new value into the PC, and simultaneously saves the old value in register $31 (aka $ra or return address) Thus, can get back from the subroutine to the instruction immediately following the jump by transferring control back to PC in register $31 Need a Call Stack to return to correct calling procedure. To maintain a stack, need to store an activation record (aka a stack frame ) in memory. Stacks keep track of the correct return address by storing the contents of $31 in memory (the stack).

high mem main: jal mult Lafter1: add $1,$2,$3 jal mult Lafter2: sub $3,$4,$5 mult: addiu $sp,$sp,-4 sw $31, 0($sp) beq $4, $0, Lout... jal mult Linside: Lout: lw $31, 0($sp) addiu $sp,$sp,4 jr $31 sp sp sp Lafter1 Linside Linside Linside Stack used to save and restore contents of $31 How about arguments? low mem

Why do we need a JAL instruction for procedure calls? A. The only way to change the PC of your program is with a JAL instruction. B. The system won t let you jump to a procedure with just a JMP instruction. C. If you JMP to a function, it doesn t know where to return to upon completion. D. Actually, JAL only works for the first function call. With multiple active functions, JAL is not the right instruction to use. 22

Calling Convention for Procedure Calls Enable code to be reused by allowing code snippets to be invoked Will need a way to call the routine (i.e. transfer control to procedure) pass arguments fixed length, variable length, recursively return to the caller Putting results in a place where caller can find them Manage registers

Need consistent way of passing arguments and getting the result of a subroutine invocation

main: li $a0, 6 li $a1, 7 jal min // result in $v0 First four arguments are passed in registers Specifically, $4, $5, $6 and $7, aka $a0, $a1, $a2, $a3 The returned result is passed back in a register Specifically, $2, aka $v0

args passed in $a0, $a1, $a2, $a3 return value (if any) in $v0, $v1 stack frame at $sp contains $ra (clobbered on JAL to sub-functions) Q: What about argument lists?

main: li $a0, 0 li $a1, 1 li $a2, 2 li $a3, 3 jal subf // result in $v0 What if there are more than 4 arguments?

main: li $a0, 0 li $a1, 1 li $a2, 2 li $a3, 3 li $8, 4 addiu $sp,$sp,-4 sw $8, 0($sp) jal subf // result in $v0 sp 4 What if there are more than 4 arguments? Use the stack for the additional arguments spill

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 subf // result in $v0 sp 5 4 What if there are more than 4 arguments? Use the stack for the additional arguments spill

Pointers are 32-bits, treat just like ints Pointers to structs are pointers C allows passing whole structs $a0, $a1 $a2, $a3 int distance(struct Point p1, struct Point p2) Treat like a collection of consecutive 32-bit arguments, use registers for first 4 words, stack for rest Of course, Inefficient and to be avoided, better to use int distance(struct Point *p1, struct Point *p2) in all cases $a0 $a1

Need consistent way of passing arguments and getting the result of a subroutine invocation Given a procedure signature, need to know where arguments should be placed void min(int a, int b); $a0, $a1 void sub(int a, int b, int c, int d, int e); void isalpha(char c); stack void treesort(struct Tree *root); $a0 struct Node *createnode(); $v0 struct Node mynode(); $v0, $v1 Too many combinations of char, short, int, void *, struct, etc. MIPS treats char, short, intand void * identically

printf( Coordinates are: %d %d %d\n, 1, 2, 3); Could use regular calling convention: place first 4 arguments in registers, spill the rest onto the stack Callee requires special-case code if(argno == 1) use a0, else if (argno == 4) use a3, else use stack offset Better approach (though initially confusing): Pass the first four arguments in registers, as usual Pass the rest on the stack Reserve space on the stack for all arguments, including the first four Simplifies functions that use variable-length arguments Store a0-a3 on the slots allocated on the stack, refer to all argumen through the stack

main: li $a0, 0 li $a1, 1 li $a2, 2 li $a3, 3 addiu $sp,$sp,-24 li $8, 4 sw $8, 16($sp) li $8, 5 sw $8, 20($sp) jal subf // result in$ v0 sp 5 4 space for $a3 space for $a2 space for $a1 space for $a0 20($sp) 16($sp) 12($sp) 8($sp) 4($sp) 0($sp) First four arguments are in registers The rest are on the stack There is room on the stack for the first four arguments, just in case

sp sp return address 5 4 space for $a3 space for $a2 space for $a1 space for $a0 blue() { pink(0,1,2,3,4,5); }

return address 5 4 space for $a3 space for $a2 space for $a1 blue() { pink(0,1,2,3,4,5); } pink(int a, int b, int c, int d, int e, int f) { } sp sp space for $a0 return address

blue sp return address 5 4 space for $a3 space for $a2 space for $a1 space for $a0 return address blue() { pink(0,1,2,3,4,5); } pink(int a, int b, int c, int d, int e, int f) { } pink

first four arg words passed in $a0, $a1, $a2, $a3 remaining arg words passed on the stack return value (if any) in $v0, $v1 stack frame at $sp contains $ra (clobbered on JAL to sub-functions) contains extra arguments to sub-functions contains space for first 4 arguments to sub-functions

r0 $zero zero r1 $at assembler temp r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 $v0 $v1 $a0 $a1 $a2 $a3 function return values function arguments r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 $k0 reserved Pseudo-Instructions e.g. BLZ SLT $at BNE $at, 0, L r27 $k1 for OS kernel r28 r29 r30 r31 $ra return address

Global variables in data segment Exist for all time, accessible to all routines Dynamic variables in heap segment Exist between malloc() and free() Local variables in stack frame Exist solely for the duration of the stack frame Dangling pointers into freed heap mem are bad Dangling pointers into old stack frames are bad C lets you create these, Java does not E.g. int *foo() { int a; return &a; }

How does a function load global data? global variables are just above 0x10000000 Convention: global pointer $28 is $gp (pointer into middle of global data section) $gp = 0x10008000 Access most global data using LW at $gp +/- offset LW $v0, 0x8000($gp) LW $v1, 0x7FFF($gp)

0xfffffffc 0x80000000 0x7ffffffc system reserved stack top $gp 0x10000000 dynamic data (heap) static data 0x00400000 0x00000000 code (text) system reserved bottom

It is often cumbersome to keep track of location of data on the stack The offsets change as new values are pushed onto and popped off of the stack Keep a pointer to the bottom of the top stack frame Simplifies the task of referring to items on the stack A frame pointer, $30, aka $fp Value of $sp upon procedure entry Can be used to restore $sp on exit

first four arg words passed in $a0, $a1, $a2, $a3 remaining arg words passed in parent s stack frame return value (if any) in $v0, $v1 stack frame at $sp contains $ra (clobbered on JAL to sub-functions) contains extra arguments to sub-functions contains space for first 4 arguments to sub-functions

Calling Convention for Procedure Calls Enable code to be reused by allowing code snippets to be invoked Will need a way to call the routine (i.e. transfer control to procedure) pass arguments fixed length, variable length, recursively return to the caller Putting results in a place where caller can find them Manage registers

What convention should we use to share use of registers across procedure calls?

Suppose a routine would like to store a value in a register Caller-save register: Assume that a caller can clobber contents of register àsave the previous contents of the register before proc call Restore after the call E.g. $a0-a3, $v0-$v1, $t0-$t9 Callee-save register: Assume register not changed across procedure call à Save the previous contents of the register on procedure entry, restore just before procedure return E.g. $ra, $fp, $s0-s7, $gp, $sp MIPS calling convention supports both

Caller-save: If you care about the value ($t0.. $t9) Save: Only if Caller wants to use the value in the reg. after a call before calling anything Now callee function can use caller-saved registers Restore after it returns MIPS ($t0-$t9), x86 (eax, ecx, and edx) are caller-save a function can freely modify these registers but must assume that their contents have been destroyed if it in turns calls a function.

Callee-save: save if you intend to use ($s0.. $s7) Save: Not optional before modifying the values in these registers Now you can use the register Restore before returning Caller assumes that these registers will be restored MIPS ($s0 - $s8), x86 (ebx, esi, edi, ebp, esp) are callee-save A function may call another function and know that the calleesave registers have not been modified However, if it modifies these registers itself, it must restore them to their original values before returning.

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] Assume the registers are free for the taking, clobber them But since other subroutines will do the same, must protect values that will be used later By saving and restoring them before and after subroutine invocations Pays off if a routine makes few calls to other routines with values that need to be preserved

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 $s0 and $s1] lw $ra,28($sp) lw $fp,24($sp) lw $s1, 20$sp) lw $s0, 16($sp) addiu $sp,$sp,32 jr $ra Assume caller is using the registers Save on entry, restore on exit Pays off if caller is actually using the registers, else the save and restore are wasted

Return address: $31 (ra) Stack pointer: $29 (sp) Frame pointer: $30 (fp) First four arguments: $4-$7 (a0-a3) Return result: $2-$3 (v0-v1) Callee-save free regs: $16-$23 (s0-s7) Caller-save free regs: $8-$15,$24,$25 (t0-t9) Reserved: $26, $27 Global pointer: $28 (gp) Assembler temporary: $1 (at)

r0 $zero zero r1 $at assembler temp r2 $v0 function r3 $v1 return values r4 $a0 r5 $a1 r6 $a2 r7 $a3 r8 $t0 r9 $t1 r10 $t2 r11 $t3 r12 $t4 r13 $t5 r14 $t6 r15 $t7 function arguments temps (caller save) r16 $s0 r17 $s1 r18 $s2 r19 $s3 saved r20 $s4 (callee save) r21 $s5 r22 $s6 r23 $s7 r24 $t8 more temps r25 $t9 (caller save) r26 $k0 reserved for r27 $k1 kernel r28 $gp global data pointer r29 $sp stack pointer r30 $fp frame pointer r31 $ra return address

first four arg words passed in $a0, $a1, $a2, $a3 remaining arg words passed in parent s stack frame return value (if any) in $v0, $v1 Bottom of current stack frame at $sp stack frame contains $ra (clobbered on JAL to sub-functions) contains $fp $fp à contains local vars (possibly clobbered by sub-functions) contains extra arguments to sub-functions (i.e. argument spilling) contains space for first 4 arguments to sub-functions callee save regs are preserved caller save regs are not Global data accessed via $gp Top of the stack $sp à saved ra saved fp saved regs ($s0... $s7) locals outgoing args

fp sp saved ra saved fp saved regs ($s0... $s7) locals outgoing args Assume a function uses two calleesave registers. How do we allocate a stack frame? How large is the stack frame? What should be stored in the stack frame? Where should everything be stored?

fp sp saved ra saved fp saved regs ($s0... $s7) locals outgoing args ADDIU $sp, $sp, -32 # allocate frame SW $ra, 28($sp) # save $ra SW $fp, 24($sp) # save old $fp SW $s1, 20($sp) # save... SW $s0, 16($sp) # save... ADDIU $fp, $sp, 28 # set new frame ptr... BODY... LW $s0, 16($sp) # restore LW $s1, 20($sp) # restore LW $fp, 24($sp) # restore old $fp LW $ra, 28($sp) # restore $ra ADDIU $sp,$sp, 32 # dealloc frame JR $ra

fp blue sp saved ra saved fp saved regs arguments blue() { pink(0,1,2,3,4,5); }

blue fp pink sp saved ra saved fp saved regs arguments saved ra saved fp saved regs local variables arguments blue() { pink(0,1,2,3,4,5); } pink(int a, int b, int c, int d, int e, int f) { orange(10,11,12,13,14); }

blue pink fp orange sp saved ra saved fp saved regs arguments saved ra saved fp saved regs local variables arguments saved ra saved fp local variables blue() { pink(0,1,2,3,4,5); } pink(int a, int b, int c, int d, int e, int f) { orange(10,11,12,13,14); } orange(int a, int b, int c, int, d, int e) { char buf[100]; gets(buf); // read string, no check! } buf[100]

fp sp saved ra saved fp saved regs arguments saved ra saved fp saved regs local variables arguments saved ra saved fp local variables blue() { pink(0,1,2,3,4,5); } pink(int a, int b, int c, int d, int e, int f) { orange(10,11,12,13,14); } orange(int a, int b, int c, int, d, int e) { char buf[100]; gets(buf); // read string, no check! } buf[100] What happens if more than 100 bytes is written to buf?

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; }

# allocate frame # save $ra # save old $fp # callee save... # callee save... # set new frame ptr...... # restore # restore # restore old $fp # restore $ra # dealloc frame

Can we optimize the assembly code at all?

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 can we optimize the assembly code?

24 bytes = 6x 4 bytes ($ra + $fp + 4 args) $fp à saved ra saved fp saved regs ($s0... $s7) locals $sp à outgoing args

Leaf function does not invoke any other functions int f(int x, int y) { return (x+y); } Optimizations? No saved regs (or locals) No outgoing args Don t push $ra No frame at all? Maybe. $fp à $sp à saved ra saved fp saved regs ($s0... $s7) locals outgoing args

Given a running program (a process), how do we know what is going on (what function is executing, what arguments were passed to where, where is the stack and current stack frame, where is the code and data, etc)?

0xfffffffc 0x80000000 0x7ffffffc system reserved stack top dynamic data (heap) 0x10000000 static data.data 0x00400000 0x00000000 code (text) system reserved bottom.text PC

init(): 0x400000 printf(s, ): 0x4002B4 vnorm(a,b): 0x40107C main(a,b): 0x4010A0 pi: 0x10000000 str1: 0x10000004 What func is running? Who called it? Has it called anything? Will it? Args? Stack depth? Call trace? CPU: $pc=0x004003c0 $sp=0x7fffffac $ra=0x00401090 0x7FFFFFB0 0x00000000 0x0040010c 0x7FFFFFF4 0x00000000 0x00000000 0x00000000 0x00000000 0x004010c4 0x7FFFFFDC 0x00000000 0x00000000 0x00000015 0x10000004 0x00401090

How to write and Debug a MIPS program using calling convention first four arg words passed in $a0, $a1, $a2, $a3 remaining arg words passed in parent s stack frame return value (if any) in $v0, $v1 stack frame at $sp contains $ra (clobbered on JAL to sub-functions) contains $fp contains local vars (possibly clobbered by sub-functions) contains extra arguments to sub-functions (i.e. argument spilling) contains space for first 4 arguments to sub-functions callee save regs are preserved caller save regs are not Global data accessed via $gp $fp à $sp à saved ra saved fp saved regs ($s0... $s7) locals outgoing args

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; } $fp à 40 36 32 28 24 20 16 12 8 4 0 $sp à saved ra saved fp saved reg $s1 saved reg $s0 local $t0 outgoing 6 th arg outgoing 5 th arg space for $a3 space for $a2 space for $a1 space for $a0 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 $t1 16($sp) LI $t1, 5 SW $t1, 20($sp) SW $t0, 24($sp) JAL sum NOP LW $t0, 24($sp) MOVE $a0, $v0 # s MOVE $a1, $t0 # tmp MOVE $a2, $s1 # b MOVE $a3, $s0 # a SW $s1, 16($sp) SW $s0, 20($sp) JAL sum NOP # add u (v0) and a (s0) ADD $v0, $v0, $s0 ADD $v0, $v0, $s1 # $v0 = u + a + b Epilogue

$fp à 40 36 32 28 24 20 16 12 8 4 0 $sp à Space for $t0 and six args to pass to subroutine saved ra saved fp saved reg $s1 saved reg $s0 local $t0 outgoing 6 th arg outgoing 5 th arg space for $a3 space for $a2 space for $a1 space for $a0 test: 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 (previous slide, 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 # allocate frame # save $ra # save old $fp # callee save... # callee save... # set new frame ptr...... # restore # restore # restore old $fp # restore $ra # dealloc frame

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 can we optimize the assembly code? 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 $t1 16($sp) LI $t1, 5 SW $t1, 20($sp) SW $t0, 24($sp) JAL sum NOP LW $t0, 24($sp) MOVE $a0, $v0 # s MOVE $a1, $t0 # tmp MOVE $a2, $s1 # b MOVE $a3, $s0 # a SW $s1, 16($sp) SW $s0, 20($sp) JAL sum NOP # add u (v0) and a (s0) ADD $v0, $v0, $s0 ADD $v0, $v0, $s1 # $v0 = u + a + b Epilogue

init(): 0x400000 printf(s, ): 0x4002B4 vnorm(a,b): 0x40107C main(a,b): 0x4010A0 pi: 0x10000000 str1: 0x10000004 What func is running? Who called it? vnorm Has it called anything? Will it? no printf no b/c no space for outgoing args Args? Str1 and 0x15 Stack depth? 4 Call trace? printf, vnorm, main, init CPU: $pc=0x004003c0 $sp=0x7fffffac $ra=0x00401090 main vnorm printf F4 F0 EA E8 E4 E0 DC 0x7 D8 0x7FFFFFD4 0x7FFFFFD0 0x7FFFFFCA 0x7FFFFFC8 0x7FFFFFC4 0x7FFFFFC0 0x7FFFFFBC 0x7FFFFFB8 0x7FFFFFB4 0x7FFFFFB0 0x7FFFFFAC 0x7FFFFFA8 Memory 0x00000000 0x0040010c 0x7FFFFFF4 0x00000000 0x00000000 0x00000000 0x00000000 0x004010c4 0x7FFFFFDC 0x00000000 0x00000000 0x00000015 0x10000004 0x00401090 0x7FFFFFC4 a3 fp ra a2 a1 a0 ra fp a3 a2 a1 a0 ra fp a3 a2 a1 a0 ra