106 Lecture Topics C Brainteaser More on Procedure
10/6: Lecture Topics • C Brainteaser • More on Procedure Call – More than four arguments – A recursive example • Starting a Program • Exercise 3. 2 from H+P
A Brainteaser in C • What does this program print? Why? #include <stdio. h> int* foo() { int b = 6; return &b; } void bar() { int c = 7; } main() { int *a = foo(); bar(); printf(“The value at a is %dn”, *a); }
5+ Arguments • Up to four arguments can be passed in registers $a 0 -$a 3 • To pass more than four, – Push them on the stack – Set the frame pointer ($fp) to point to them • The frame pointer provides a stable base register for the duration of the procedure – why not just use $sp?
Stack Allocation Low address $sp Local vars. Saved $s regs. Saved $ra $sp $fp Saved args $sp Caller’s stack frame Before High address Callee’s stack frame $fp During Caller’s stack frame After
Activation Record • For a procedure call, the activation record is the portion of the stack containing – saved registers – local variables • Also known as stack frame or procedure frame
Recursive Procedure Call • A recursive procedure calls itself • With the stack, no more difficult than nested procedure call int fact(int n) { if(n < 1) return 1; else return (n * fact(n-1)); }
Factorial Implementation fact: L 1: subi sw sw slt beq add jr sub jal lw lw add mult jr $sp, $ra, $a 0, $t 0, $v 0, $sp, $ra $a 0, fact $a 0, $ra, $sp, $v 0, $ra $sp, 8 4($sp) 0($sp) $a 0, 1 $zero, L 1 $zero, 1 $sp, 8 $a 0, 1 0($sp) 4($sp) $sp, 8 $a 0, $v 0
Starting a Program • Two phases from source code to execution • Compile time – compiler creates assembly – assembler creates machine code – linker creates an executable • Run time – loader moves the executable into memory and starts the program
Compile Time • You’re experts on compiling from source to assembly • Two parts to translating from assembly to machine language: – Instruction encoding (including translating pseudoinstructions) – Translating labels to addresses • Label translations go in the symbol table
Symbol Table • Symbols are names of global variables or labels (including procedure entry points) • Symbol table associates symbols with their addresses in the object file • This allows files compiled separately to be linked Label 1: 0 x 01031 ff 0 big. Array 0 x 10006000
Modular Program Design • Small projects may use only one file – Any time any one line changes, recompile and reassemble the whole thing (death of Pascal) • For larger projects, recompilation time is significant • Solution: split project into modules – compile and assemble modules separately – link the object files
The Compiler + Assembler • Translates high-level language source files into object files • Object files – Contains machine instructions (1’s & 0’s) – Bookkeeping information • Procedures and variables the object file defines • Procedures and variables the source files use but are undefined (unresolved references) • Debugging information associating machine instructions with lines of source code
Object File Example main. c area. c double PI = 3. 14159; extern int ; main() { double A = Area( 5. 0 ); } double Area( double r ) { return PI * r; } main. o area. o code: static data: defined symbols: undefined symbols:
The Linker • The linker’s job is to “stitch together” the object files: 1. Place the data modules in memory 2. Determine the addresses of data and labels 3. Match up references between modules
Placing Modules in Memory • Link a word processor application: Editing text static data Spell checking Paperclip
Determining Addresses • Some addresses change during memory layout • Modules were compiled in isolation • Absolute addresses must be relocated • Object file keeps track of instructions that use absolute addresses text
Resolving References • The editing module calls a routine from the spell checker • That symbol is unresolved at compile time • The linker matches unresolved symbols to locations in other modules
Linker Example main. o code: main: A=area(5. 0) static data: PI = 3. 1415 area. o code: Area: return PI*r*r static data: defined symbols: main, PI undefined symbols: Area undefined symbols: PI LINKER main. exe header code: main: A=area(5. 0) Area: return PI*r*r static data: PI = 3. 1415 defined symbols: main, PI, Area
Libraries • Some code is used so often, it is bundled into libraries for common access • Libraries contain most of the code you use but didn’t write: e. g. , printf() • Library code is (often) merged with yours at link time main. o libc. a main. exe
The Executable • End result of compiling, assembling, and linking: the executable • Contains: – Header, listing the lengths of the other segments – Text segment – Static data segment – Potentially other segments, depending on architecture & OS conventions
Run Time • We’ll learn a lot more about this during the OS part of the course • In a nutshell: – Some dynamic linking may occur • some symbols aren’t defined until run time • Windows’ dlls (dynamic link library) • why do this? – The segments are loaded into memory – The OS transfers control to the program and it runs
add add outer: add lw add inner: add lw bne addi skip: addi bne slt bne add next: addi bne $a 1, $v 0, $t 4, $t 5, $t 1, $t 3, $t 5, $t 1, $t 2, $v 0, $v 1, $t 0, $a 1, $a 1 $zero, $zero $a 0, $t 0 0($t 4) $zero, $zero $a 0, $t 1 0($t 3) $t 4, skip $t 5, 1 $t 1, 4 $a 1, inner $t 5, $v 0 $zero, next $t 5, $zero $t 4, $zero $t 0, 4 $a 1, outer
int int int size = 5000; values[size]; mode = 0; mode. Count = 0; i, j; for( i = 0; i < size; i++ ) { count = 0; for( j = 0; j < size; j++ ) { if( values[i] == values[j] ) { count++; } } if( count > mode. Count ) { mode. Count = count; mode = values[i]; } }
- Slides: 23