Post on 29-Mar-2018
ECE 154A Introduction to Computer ArchitectureComputer Architecture
Fall 2012
Dmitri Strukov
Lecture 7
AgendaAgenda
• Stack and memory mappingStack and memory mapping
• Procedures
i d li k d li• Arrays, pointers and linked lists
Illustrating a Procedure Call
Prepare main
jal proc
proc S t
PC Prepare
to continue
to call
Save, etc.
jr $ra Restore
Relationship between the main program and a procedure.
Memory Map Reserved 1 M words
Hex address
00000000
00400000
in MIPS Program
10000000
Text segment 63 M words
Static dataAddressable10008000
1000ffff
Data segment
Static data
Dynamic data
Addressable with 16-bit signed offset
$gp
$sp
448 M words $28
$29
$
Stack
7ffffffc
Stack segment
$fp
$30
80000000
Second half of address space reserved for memory-mapped I/O
Memory Management
• How do we manage memory?• Code Static storage are easy:• Code, Static storage are easy: they never grow or shrink
• Stack space is also easy:• Stack space is also easy: stack frames are created and destroyed in last‐in, first‐out (LIFO) order, ( )
• Managing the heap is tricky:memory can be allocated / deallocated at y /any time
Memory Map Reserved 1 M words
Hex address
00000000
00400000
in MIPS Program
10000000
Text segment 63 M words
Static dataAddressable10008000
1000ffff
Data segment
Static data
Dynamic data
Addressable with 16-bit signed offset
$gp
$sp
448 M words $28
$29
$
Stack
7ffffffc
Stack segment
$fp
$30
80000000
Overview of the memory address space in MiniMIPS
Second half of address space reserved for memory-mapped I/O
Overview of the memory address space in MiniMIPS.
Using the Stack for Data Storage
sp
Analogy:Cafeteria stack of
ba
sp
Push c Pop x
stack of plates/trays
b sp
b c
a a sp sp = sp – 4 mem[sp] = c
x = mem[sp]sp = sp + 4
Effects of push and pop operations on a stack.
push: addi $sp,$sp,-4sw $t4,0($sp)
pop: lw $t5,0($sp)addi $sp,$sp,4sw $t4,0($sp) addi $sp,$sp,4
ProceduresProcedures
Prolog
‐ spill all register to stack used by procedure expect for $t0‐$t9
and the one used for returning values
d k i ($ ) fi h i k‐ advance stack pointer ($sp) first then write to stack
Body
code of the procedurecode of the procedure
Epilog
‐ restore all used registers
‐ adjust stack pointer at the end ($sp)
Simple Procedure Calls
Using a procedure involves the following sequence of actions:
1 Put arguments in places known to procedure (reg’s $ 0 $ 3)1. Put arguments in places known to procedure (reg s $a0-$a3)2. Transfer control to procedure, saving the return address (jal)3. Acquire storage space, if required, for use by the procedure4 P f th d i d t k4. Perform the desired task5. Put results in places known to calling program (reg’s $v0-$v1)6. Return control to calling point (jr)
MiniMIPS instructions for procedure call and return from procedure:
jal proc # jump to loc “proc” and link;“ ” “# “link” means “save the return
# address” (PC)+4 in $ra ($31)
jr rs # go to loc addressed by rs
Recalling Register
Procedure results
Reserved for assembler use $0 $1 $2 $3 $4
0
$zero $at $v0
$a0
$v1
3 2 1 0
A 4-byte word sits in consecutive memory addresses according to the big-endian order Register
ConventionsSaved Procedure arguments
$4 $5 $6 $7 $8 $9
$t0
$t1
$a0
$a2
$a1
$a3
Byte numbering: 0 1 2 3
g(most significant byte has the lowest address)
Temporary values
$10 $11 $12 $13 $14
$t2
$t4
$t6
$t3
$t5
When loading a byte into a register, it goes in the low end Byte
W d
Operands
Saved across
procedure
$15 $16 $17 $18 $19
$t7
$s0
$s2
$s1
$s3
Word
Doublew ord
More temporaries
p
procedure calls
$20 $21 $22 $23 $24
$
$s4
$s6
$s5
$s7
$t8
$
A doubleword sits in consecutive
i t Registers and data sizes in MiniMIPS.
temporaries
Global pointer Stack pointer Frame pointer Saved
Reserved for OS (kernel)
$25 $26 $27 $28 $29 $30
$t9
$gp
$sp
$fp
$k0
$k1
registers ormemory locations according to the big-endian order (most significant word comes first)
Frame pointerReturn address
$30 $31
$fp
$ra
A Simple MIPS Procedure
Procedure to find the absolute value of an integer.
$v0 |($a0)|
Solution
The absolute value of x is –x if x < 0 and x otherwise.
abs: sub $v0,$zero,$a0 # put -($a0) in $v0; # in case ($a0) < 0($ )
bltz $a0,done # if ($a0)<0 then done add $v0,$a0,$zero # else put ($a0) in $v0
done: jr $ra # return to calling program
In practice, we seldom use such short procedures because of the overhead that they entail. In this example, we have 3-4 instructions of overhead for 3 instructions of useful computation.
Memory Map Reserved 1 M words
Hex address
00000000
00400000
in MIPS Program
10000000
Text segment 63 M words
Static dataAddressable10008000
1000ffff
Data segment
Static data
Dynamic data
Addressable with 16-bit signed offset
$gp
$sp
448 M words $28
$29
$
Stack
7ffffffc
Stack segment
$fp
$30
80000000
Overview of the memory address space in MiniMIPS
Second half of address space reserved for memory-mapped I/O
Overview of the memory address space in MiniMIPS.
Parameters and Results
$sp z
Stack allows us to pass/return an arbitrary number of values
$sp
Frame for current procedure Saved
y z
. . . Local variables
b$sp c
Frame for bc
Frame for$fp
Old ($fp)
Savedregisters
b a
Frame forcurrent procedure
$fp
. . .
ba
Frame forprevious procedure . . .
Use of the stack by a procedure. Before calling After calling
y p
Example of Using the Stack
Saving $fp, $ra, and $s0 onto the stack and restoring them at the end of the procedure
proc: sw $fp,-4($sp) # save the old frame pointeraddi $fp $sp 0 # save ($sp) into $fpaddi $fp,$sp,0 # save ($sp) into $fpaddi $sp,$sp,–12 # create 3 spaces on top of stacksw $ra,-8($fp) # save ($ra) in 2nd stack elementsw $s0,-12($fp) # save ($s0) in top stack element
$ ...lw $s0,-12($fp) # put top stack element in $s0lw $ra -8($fp) # put 2nd stack element in $ra
$sp($fp)
$fp
$sp($ra)($s0)
lw $ra, 8($fp) # put 2nd stack element in $raaddi $sp,$fp, 0 # restore $sp to original statelw $fp,-4($sp) # restore $fp to original statejr $ra # return from procedure
$fp
p
Fibonacci numbersFibonacci numbers
F(n) = F(n‐1)+F(n‐2)F(1) = 1F(2) = 1n = 1 2 3 4 5 6n = 1 2 3 4 5 6 …F(n) = 1 1 2 3 5 8 …
/* R i f i i *//* Recursive function in c */int fib(int n) {
If (n==1) return 1;If (n==2) return 1;return fib(n‐1)+fib(n‐2);
}}
Nested Procedure Calls
Prepare
main
jal abc
abc Save
PC Prepare to continue
Prepareto call
Procedure abc
Procedure xyz
jal xyz
xyz xyz
jr $ra Restore
jr $ra
Example of nested procedure calls.
ReviewP i t d i t ll• Pointers and arrays are virtually same
• C knows how to increment pointers• C is an efficient language, with little protection– Array bounds not checked– Variables not automatically initialized
• (Beware) The cost of efficiency is more overhead for the programmer.
“ i l f b b f l– “C gives you a lot of extra rope but be careful not to hang yourself with it!”
Pointers (1/4)
• Sometimes you want to have a procedure increment a variable?
• What gets printed?
void AddOne(int x){ x = x + 1; }
y = 5{ x x + 1; }
int y = 5;AddO ( )AddOne( y);printf(“y = %d\n”, y);
Pointers (2/4)
• Solved by passing in a pointer to our subroutine.
• Now what gets printed?
void AddOne(int *p){ *p = *p + 1; }
y = 6{ p p + 1; }
int y = 5;AddO (& )AddOne(&y);printf(“y = %d\n”, y);
Pointers (3/4)
• But what if what you want changed is a pointer?p
• What gets printed?
void IncrementPtr(int *p){ p = p + 1; }
*q = 50
A q{ p p + 1; }
int A[3] = {50, 60, 70};i t * A
A q
int *q = A;IncrementPtr( q);printf(“*q = %d\n”, *q);
50 60 70
Pointers (4/4)
• Solution! Pass a pointer to a pointer, declared as **h
• Now what gets printed?
void IncrementPtr(int **h){ *h = *h + 1; }
*q = 60
A q q{ h h + 1; }
int A[3] = {50, 60, 70};i t * A
A q q
int *q = A;IncrementPtr(&q);printf(“*q = %d\n”, *q);
50 60 70
Arrays examplevoid foo() {
int *p, *q, x;int a[4];p = (int *) malloc (sizeof(int));q = &x;q = &x;
*p = 1; // p[0] would also work hereprintf("*p:%u, p:%u, &p:%u\n", *p, p, &p);
*q = 2; // q[0] would also work hereprintf("*q:%u, q:%u, &q:%u\n", *q, q, &q);*a = 3; // a[0] would also work here
i f( * % % % \ * )printf("*a:%u, a:%u, &a:%u\n", *a, a, &a);
? ? ......0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 ...
p q x
? ? ?
unnamed‐malloc‐space40 20 2 3 1
} *p:1, p:40, &p:12*q:2, q:20, &q:16*a:3, a:24, &a:24a
24
?
a:3, a:24, &a:24
K&R: “An array name is not a variable”
C structures• A struct is a data structure composed from• A struct is a data structure composed from simpler data types.– Like a class in Java/C++ but without methods or i h iinheritance.
struct point { /* type definition */int x;i tint y;
};
void PrintPoint(struct point p)( p p){
printf(“(%d,%d)”, p.x, p.y);} As always in C, the argument is passed by “value” – a copy is made.
struct point p1 = {0,10}; /* x=0, y=10 */
PrintPoint(p1);PrintPoint(p1);
C structures: Pointers to them
• Usually, more efficient to pass a pointer to the structstruct.
• The C arrow operator (->) dereferences and extracts a structure field with a single operatorextracts a structure field with a single operator.
• The following are equivalent:
struct point *p;/* code to assign to pointer */g pprintf(“x is %d\n”, (*p).x);printf(“x is %d\n”, p->x);
How big are structs?
• Recall C operator sizeof() which gives size in bytes (of type or variable)size in bytes (of type or variable)
• How big is sizeof(p)? struct p {struct p {
char x;int y;y;
};– 5 bytes? 8 bytes? – Compiler may word align integer y
Linked List Example
• Let’s look at an example of using structures, pointers, malloc(), and free() to po te s, a oc(), a d ee() toimplement a linked list of strings.
/* node structure for linked list */struct Node {
h * lchar *value;struct Node *next;
}; cursive
inition!
};
Rec
def
typedef simplifies the codestruct Node {struct Node {
char *value;struct Node *next;
};
String value;
/* "typedef" means define a new type */typedef struct Node NodeStruct;
… OR …typedef struct Node {typedef struct Node {
char *value;struct Node *next;
} NodeStruct; /* Note similarity! */
… THEN
typedef NodeStruct *List;
/* To define 2 nodes */
struct Node {char *value;typedef char *String; char value;struct Node *next;
} node1, node2;
Linked List Example/* Add a string to an existing list *// g g /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);
d t li tnode->next = list;return node;
}
{String s1 = "abc", s2 = "cde";List theList = NULL;List theList NULL;theList = cons(s2, theList);theList = cons(s1, theList);
/* or, just like (cons s1 (cons s2 nil)) */jtheList = cons(s1, cons(s2, NULL));
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:list:
… …
NULL?
"abc"
NULLs:
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:list:
… …?
"abc"
NULL?
?s:
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:list:
… …
NULL
"abc"
NULL
?
"????"
s:
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:list:
… …
NULL
"abc"
NULL
?
"abc"
s:
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:list:
… …
NULLs:
"abc"
NULL
"abc"
Linked List Example/* Add a string to an existing list 2nd call *// Add a string to an existing list, 2nd call /List cons(String s, List list){
List node = (List) malloc(sizeof(NodeStruct));( ) ( ( ));
node->value = (String) malloc (strlen(s) + 1);strcpy(node->value, s);node->next = list;return node;
}
node:… …
NULLNULL
"abc"
s:
"abc"
Important points to rememeber
• Remember:– Structure declaration does not allocate memory
Variable declaration does allocate memory– Variable declaration does allocate memory
• So far we have talked about several different ways to allocate memory for data:1. Declaration of a local variable
int i; struct Node list; char *string; int ar[n];
2. “Dynamic” allocation at runtime by calling allocation function (alloc).
int myGlobal;
ptr = (struct Node *) malloc(sizeof(struct Node)*n);
• One more possibility exists…3 Data declared outside of any procedure int myGlobal;
main() { }
3. Data declared outside of any procedure (i.e., before main).
– Similar to #1 above, but has “global” scope.