csce 230, fall 2013 chapter 2 stacks and subroutines ( § 2.6–2.7)
Post on 22-Feb-2016
44 Views
Preview:
DESCRIPTION
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