ece 154a introduction to computer architecturestrukov/ece154afall2012/lecture7.pdfece 154a...

36
ECE 154A Introduction to Computer Architecture Computer Architecture Fall 2012 Dmitri Strukov Lecture 7

Upload: truongdat

Post on 29-Mar-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

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.

Linked lists and memory managementmemory management

Courtesy of Prof. Garcia (UCB)

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.