csce 230, fall 2013 chapter 2 stacks and subroutines ( § 2.6–2.7)

Post on 22-Feb-2016

44 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Mehmet Can Vuran, Instructor University of Nebraska-Lincoln. CSCE 230, Fall 2013 Chapter 2 Stacks and Subroutines ( § 2.6–2.7) . Acknowledgement: Overheads adapted from those provided by the authors of the textbook. Stacks. - PowerPoint PPT Presentation

TRANSCRIPT

CSCE 230, Fall 2013

Chapter 2Stacks and Subroutines (§ 2.6–2.7)

Mehmet Can Vuran, Instructor University of Nebraska-Lincoln

Acknowledgement: Overheads adapted from those provided by the authors of the textbook

Stacks

A stack is a list of data elements whereelements are added/removed at top end only

Also known as pushdown stack orlast-in-first-out (LIFO) stack

We push a new element on the stack topor pop the top element from the stack

Programmer can create a stack in the memory There is often a special processor stack as well

2

Processor Stack

Processor has stack pointer (SP) registerthat points to top of the processor stack

Push operation involves two instructions:Subtract SP, SP, #4StoreRj, (SP)

Pop operation also involves two instructions:Load Rj, (SP)Add SP, SP, #4

Maintenance of stack requires checking when the stack is empty or overflows – can be done by checking the SP against lower and upper bounds.

Among other things, the processor stack is useful in subroutine calls.

3

NIOS-II Registers

4

Stack pointer (SP) register(should) points to top of the processor stack

5

SP = 100

Initial Stack

60646872768084889296100 [something]

6

SP = 92 N

#A

Add coupleinput parameters

60646872768084889296100 [something]

7

#AN

SP = 72

R1R2

After register saves

R3R4R5

60646872768084889296100 [something]

8

#AMax Value

SP = 72

R1R2

Update stackwith an output parameter

R3R4R5

60646872768084889296100 [something]

9

SP=92

After returnfrom a function

#AMax Value

60646872768084889296100 [something]

10

SP=100

After stack restoreby calling program

60646872768084889296100 [something]

The first rule of stack operations is… You do not talk about…

Leave the stack as you found it *

* some exceptions apply

11

Main Usages of Stack

Subroutine calls

Parameter passing

12

Subroutine Linkage

During execution of Call instruction,PC upated to point to instruction after Call

Save this address for Return instruction to use Simplest method: place address in link

register (return address register) Call instruction performs two operations:

store updated PC contents in link register,then branch to target (subroutine) address

Return just branches to address in link register

NIOS-II Registers

14

Subroutines Nesting: Example

16

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

Subroutines Nesting: Example

17

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1000

204PC

LINK

Subroutines Nesting: Example

18

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1000

204

PC

LINK

Subroutines Nesting: Example

19

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1000

204

PC

LINK

Subroutines Nesting: Example

20

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

2000

1604

204

PC

LINK

Subroutines Nesting: Example

21

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

2000

1604

PC

LINK

Subroutines Nesting: Example

22

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

#Return+4

1604

PC

LINK

Subroutines Nesting: Example

23

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1604

1604

PC

LINK

Subroutines Nesting: Example

24

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1604

1604

PC

LINK

Subroutines Nesting: Example

25

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1604

1604

PC

LINK

Subroutines Nesting: Example

26

SUB1 SUB2 SUB3

1000 First Instr.

. .

1600 Call SUB3

1604 Next Instr.

. .Return

. . .

200 Call SUB2204 Next Instr.

. . .

2000 First Instr. . .

.Return

1604

1604

PC

LINK

ERROR!

Analysis and Solution

When nested calls are made, the last call made is first one to be returned, i.e. the call-return protocol is Last-In First-Out (LIFO).

The nested calls can be arbitrarily deep, e.g. for recursive routines.

Hence, subroutines use the processor stack to store the Link register values during nested calls.

27

Parameter Passing

Mechanism hidden in HLL but must be explicit in assembly language.

A program may call a subroutine many times with different data to obtain different results

Information exchange to/from a subroutineis called parameter passing

Pass input parameters before the subroutine Call receive output parameters after the call

Parameters may be passed & received in registers Simple, but limited to available registers Alternative: use stack for parameter passing,

and also for local variables & saving registers28

Example: Parameters Passed in Registers Convert the example program of finding the max of N

numbers to a subroutine: Calling program provides N (number of elements) and the

address of the first number (i.e., A[0]) Subroutine MAX(N, #A) returns the max value of N numbers

stored starting at location #A. Hence, there are two input parameters and one output

parameter. First, consider passing& receiving parameters in registers (we

use the register assignments in the code we developed earlier to keep it simple)▪ N in reg. R3▪ Address #A of A[0] in reg. R5▪ Max value returned in R1

Assume the values of N and A[0] are at location N and A.29

Sketch of Solution Calling Program

Load parameters N and A in the designated registers (R3 & R5) Call MAX Return value should be available in the designated register (R1)

Subroutine (MAX) Push registers (other than parameter registers) used by the

subroutine on the stack (i.e. push R2 and R4) Find the value of the max element and place it in R1 (code identical

to what we already saw except for the last two lines, since the value is to be returned in register R1)

Pop registers from the stack (& update stack) Return

Note: Since MAX does not call another subroutine (it is a leaf subroutine), it does not need to save the Link register on the stack.

30

Sketch of Solution (contd.)

Calling Program Load parameters in designated registers

Move R3, #N # Location of NLoad R3, (R3) # Value of NLoad R5, #A # Address of first

element

Call MAXCall MAX

Max value will be available in R1 after return

31

Sketch of Solution (contd.)

Subroutine (MAX) Push registers R2 and R4 used by the subroutine on the stack

Subtract SP, SP, #8 # Create room for two itemsStore R2, 4(SP) # Push R2Store R4, (SP) # Push R4

Find the value of the max element<Code here from before except last two lines>

Pop registers from the stack (& update stack)Load R2, 4(SP) # Restore R2Load R4, (SP) # Restore R4Add SP, SP, #8 # Update stack pointer ReturnReturn

32

Convert Max(N,A) Code to Subroutine: Original Code

33

Variable: Max

i #N =(Addr. N)

A[i]

#A=Addr. A[0]

Register

R1 R2

R3 R4 R5

Move R3, #NLoad R3, (R3)Move R5, #ALoad R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopMove R2, #MaxStore R1, (R2)

Assembly Code

Convert Max(A,N) Code to Subroutine (1)

Break the Code into three pieces:1. Becomes part of calling

program for passing parameters

2. Becomes part of the subroutine; precede it with register saves; follow it with register restores and return

3. Becomes part of calling program to save returned value

34

Variable: Max

i #N =(Addr. N)

A[i]

#A=Addr. A[0]

Register

R1 R2

R3 R4 R5

Move R3, #NLoad R3, (R3)Move R5, #ALoad R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopMove R2, #MaxStore R1, (R2)

Assembly Code

1

2

3

Convert Max(A,N) Code to Subroutine (2)

35

Variable: Max

i #N =(Addr. N)

A[i]

#A=Addr. A[0]

Register

R1 R2

R3 R4 R5

Move R3, #NLoad R3, (R3)Move R5, #A

Move R2, #MaxStore R1, (R2)

Calling Program

Load R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) Loop

1

2

3

MAX Subroutine

Convert Max(A,N) Code to Subroutine (3)

36

Variable: Max

i #N =(Addr. N)

A[i]

#A=Addr. A[0]

Register

R1 R2

R3 R4 R5

Move R3, #NLoad R3, (R3)Move R5, #A

Move R2, #MaxStore R1, (R2)

Calling Program

Load R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) Loop

1

2

3

MAX Subroutine

Call MAX

MAX:<Save local variables and saving registers

on stack>

<Restore locals and saving registers on stack>

Return

Convert Max(A,N) Code to Subroutine (4)

37

Variable: Max

i #N =(Addr. N)

A[i]

#A=Addr. A[0]

Register

R1 R2

R3 R4 R5

Move R3, #NLoad R3, (R3)Move R5, #A

Move R2, #MaxStore R1, (R2)

Calling ProgramLoad R1, (R5)

Move R2, #1Loop: Add R5, R5, #4

Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) Loop

12

3

MAX Subroutine

MAX: Subtract SP, SP, #8Store R2, 4(SP)Store R4, (SP)

Load R2, 4(SP)Load R4, (SP)Add SP, SP, #8Return

Call MAX

Exercise

Convert the code for the calling program and MAX to Nios II and verify it works as expected.

38

Passing Parameters on the Stack Assume A calls B with input parameters i1, …,in

and B returns resulting values o1, …, om. Assume m <= n (common case).

General Scheme: A pushes i1, …,in on the stack and calls B. B pushes any (saving) registers it would need for its

computation on the stack; also the return-address register if it is not a leaf procedure.

B performs its computation and writes the resulting values o1, …, om on the stack (reusing the space used by input parameters).

B pops the saving registers from the stack and returns.39

Passing Parameters on the Stack: Example Max(A,N) Calling Program

Push input parameters onto stack (grows high to low),Subtract SP, SP, #8 # Create room for 2 itemsLoad R2, #N # Address of N in R2Load R2, (R2) # Value of N in R2Store R2, 4(SP) # Push it on the stackLoad R2, #A # Get the second parameter in R2Store R2, (SP) # push it on the stack

Call subroutineCall MAX

Get max value from the stack and restores stack (pop input parameters) Load R1,4(SP) # Result pushed on stack by MAX # Result overwrites value of N on stackAdd SP, SP, #8 #Effectively pops stack

40

Passing Parameters on the Stack: Example Max(A,N) - (contd.)

Subroutine MAX Save all regs. it will use (R1 – R5) on stack

Subtract SP, SP, #20 Create room for five itemsStore R1, 16(SP) Push R1Store R2, 12(SP) Push R2… …Store R5, (SP) Push R5

Load input parameters from stack and compute sumLoad R3, 24(SP) Get N into R3Load R5, 20(SP) Get #A into R5

Body of the Subroutine: <Code from before will need to change – see later how>

Restore saved registers and pop stack, returnLoad R1, 16(SP) Restore R1Load R2, 12(SP) R2… …Load R5, (SP) R5Add SP, SP, #20 Pop stackReturn Return to calling program

41

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on stack2. R3 and R5 must be

initialized from the stack3. Last two lines must be

replaced with pushing the result in R1 onto stack where input parameter N was passed.

4. Restore R1-R5 and pop stack

5. Return42

Move R3, #NLoad R3, (R3)Move R5, #ALoad R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopMove R2, #MaxStore R1, (R2)

Earlier Assembly Code

43

SP = 100

Initial Stack

60646872768084889296100 [something]

44

SP = 92 N

#A

Add coupleparameters

60646872768084889296100 [something]

45

#AN

SP = 72

R1R2

After register saves

R3R4R5

60646872768084889296100 [something]

46

#AMax Value

SP = 72

R1R2

Update stackwith output parameter

R3R4R5

60646872768084889296100 [something]

47

SP=92

After returnfrom a function

#AMax Value

60646872768084889296100 [something]

48

SP=100

After stack restoreby calling program

60646872768084889296100 [something]

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on

stack

49

MAX: Subtract SP, SP, #20Store R1, 16(SP) Push R1Store R2, 12(SP) Push R2

… …Store R5, (SP) Push R5Move R3, #NLoad R3, (R3)Move R5, #ALoad R1, (R5)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopMove R2, #MaxStore R1, (R2)

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on

stack2. R3 and R5

must be initialized from the stack

50

MAX: Subtract SP, SP, #20Store R1, 16(SP) Push R1Store R2, 12(SP) Push R2

… …Store R5, (SP) Push R5Load R3, 24(SP)Load R5, 20(SP)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopMove R2, #MaxStore R1, (R2)

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on stack2. R3 and R5 must be

initialized from the stack

3. Last two lines must be replaced with pushing the result in R1 onto stack where input parameter N was passed.

51

MAX: Subtract SP, SP, #20Store R1, 16(SP) Push R1Store R2, 12(SP) Push R2

… …Store R5, (SP) Push R5Load R3, 24(SP)Load R5, 20(SP)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopStore R1, 24(SP)

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on stack2. R3 and R5 must be

initialized from the stack

3. Last two lined must be replaced with pushing the result in R1 onto stack where input parameter N was passed.

4. Restore R1-R5 and pop stack

52

MAX: Subtract SP, SP, #20Store R1, 16(SP) Push R1Store R2, 12(SP) Push R2

… …Store R5, (SP) Push R5Load R3, 24(SP)Load R5, 20(SP)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopStore R1, 24(SP)Load R1, 16(SP) Restore R1Load R2, 12(SP) Restore R2

… …Load R5, (SP) Restore R5Add SP, SP, #20

Passing Parameters on the Stack: Changes to Max(A,N)

Required Changes1. Push R1–R5 on stack2. R3 and R5 must be

initialized from the stack

3. Last two lined must be replaced with pushing the result in R1 onto stack where input parameter N was passed.

4. Restore R1-R5 and pop stack

5. Return

53

MAX: Subtract SP, SP, #20Store R1, 16(SP) Push R1Store R2, 12(SP) Push R2

… …Store R5, (SP) Push R5Load R3, 24(SP)Load R5, 20(SP)Move R2, #1

Loop: Add R5, R5, #4Load R4, (R5)Branch_if_(R1>=R4) SkipMove R1, R4

Skip: Add R2, R2, #1Branch_if_(R3>R2) LoopStore R1, 24(SP)Load R1, 16(SP) Restore R1Load R2, 12(SP) Restore R2

… …Load R5, (SP) Restore R5Return

Exercise

Convert the code for the calling program and Max to Nios II and verify it works as expected.

54

ITOAH (Non-Recursive)

The next three slides show step-by-step development ofassembly code for another example of a non-recursive procedure.

You should study this carefully and then do the following exercise to convert the code to a subroutine, to understand better the process we used to convert the max-finding program

Integer to ASCII-HEX conversion(Non-recursive Program)

itoah(n, S) /* Convert positive integer n to hexadecimal string S in ASCII - non recursive */

int n; char S[];

{int i, ji = 0;do {

j = n % 16; /* modulo-16 operator */if(j<10) S[i++] = j + '0'; else S[i++] = j-10+'A’ /* i++ is C syntax */

} while ((n = n/16) > 0); /* while condition checked at the end of the loop */}

1. Hand-simulate the program for the call itoah(95, S).2. Assume, input parameters n & S, and the local variables i & j are mapped to

registers R2, R3, R4, and R5 respectively. Further, assume that the programrequires no other registers to compute the body of the loop. Show the stack state: (1) before the call to itoah (2) after the call just before the first instruction in the body is executed, and (3) just before the procedureis ready to return.

61

HLL to Intermediate Code

62

{int i, ji = 0;do {

j = n % 16;if(j<10) S[i++] = j +

'0'; else S[i++] = j-

10+'A’ } while ((n = n/16) > 0)

}

{int i, ji = 0;do {

j = n % 16;if(j<10) S[i++] = j +

'0'; else S[i++] = j-

10+'A’ } while ((n = n/16) > 0)

}

Intermediate to Assembly Code

63

n S[i] i j

R2 R3 R4 R5Register Assignments:

i = 0LOOP:

j = n and 0xFif(j<10) toto L1S[i] = j – 10 +

‘A’goto L2

L1: S[i] = j + ‘0’L2: i = i+1

n = n/16if(n>0) goto

LOOP

Move R4, R0LOOP:

And R5, R2, #0xFBranch_if_(R5<#10) L1Subtract R3, R5, #10Add R3, R3, #41Branch L2

L1: Add R3, R5, #30L2: Add R4, R4, #1 Right_Shift R2, R2, 4

Branch_if_(R2>0) LOOP

Intermediate Code Assembly Code

Exercise

Convert the itoah program to two programs: main that calls the subroutine itoah. Assume parameters n and #S are passed in registers.

Note that string S is both an input and the output parameter.

64

Integer to ASCII-HEX conversion(Recursive)

itoah(n, S, i) /* Convert positive integer n to hexadecimal string S in ASCII , i is index - recursive program*/

int n, i; char S[];{

int j;

if ((j = n/16) != 0) /* integer division */itoah(j, S, i+1);

j = n % 16;if(j<10) S[i] = j + '0'; else S[i] = j-10+'A'

}

1. Hand-simulate the program for the call itoah(95, S, 0).2. Assume, input parameters n, S, and i and the local variable j are mapped to

registers R2, R3, R4, and R5 respectively. Further, assume that the programrequires no other registers to compute the body of the loop. Show the stack state: (1) before each call (2) after each call just before the first instruction in the body is executed, and (3) just before the program is ready to return.

65

top related