sect 05 stack subroutine
TRANSCRIPT
-
8/3/2019 Sect 05 Stack Subroutine
1/15
1
EE 4535 Packet 5 1
Stacks
and
Subroutines
EE 4535 Packet 5 2
Stacks and subroutine usage
(Textbook, sections 3.1-3.5)
K The stack is a special area of the
random access memory in the overallmemory system
K The stack is used for
General data storage (limited)
Temporary data storage (true)
Parameter and control information
storage for subroutines (yes!)
-
8/3/2019 Sect 05 Stack Subroutine
2/15
2
EE 4535 Packet 5 3
Some example stacks
Top
of stack
Bottom
of stack
EE 4535 Packet 5 4
Stacks
K Last-in, first-out (LIFO) structure
K All access is at the top of the stackK Operations
Push
Places an item onto the stack
Pull
Removes an item from the stack
Some (most!) people use the term pop
K Bottom of the stack is at highest memoryaddress, and top of the stack is at thelowest address Stack grows from high to low address
For EVBU, stack is usually placed at $01FF
K Stack Pointer (SP) Register that points to the memory location
immediately preceding the top of the stack
In other words, the SP normally contains the
address for a new data item to be pushed
-
8/3/2019 Sect 05 Stack Subroutine
3/15
3
EE 4535 Packet 5 5
HC11 implementation
EE 4535 Packet 5 6
K Push instructions
PSHA, PSHB, PSHX, PSHY Stores data in memory at address pointed to by SP
Decrements SP
For 16-bit values, low-order byte is pushed first,
followed by high-order byte
How can we push CCR?
-
8/3/2019 Sect 05 Stack Subroutine
4/15
4
EE 4535 Packet 5 7
K Pull instructions
PULA, PULB, PULX, PULY
Increments SP
Loads data from memory address pointed to
by SP
EE 4535 Packet 5 8
K Other stack operations
Can modify or read the SP
LDS Load the SP
STS Store the SP
INS Increment SP
DES Decrement SP
TSX Transfer SP+1 to IX
TSY Transfer SP+1 to IYTXS Transfer IX-1 to SP
TYS Transfer IY-1 to SP
-
8/3/2019 Sect 05 Stack Subroutine
5/15
5
EE 4535 Packet 5 9
K Stacks
Remember to initialize SP at beginning ofprogram
Important to pull data in reverse order that you
pushed it
Note that SP points to empty memory location
(= location where next value will be stored)
EE 4535 Packet 5 10
K Using the stack
Passing parameters to subroutines (more on thislater)
Temporary storage
68HC11 has limited number of registers
Use stack to preserve register values
K Example: Multiply ACCA and ACCB,
round to 8 bits
PSHB ; save value in ACCB
MUL ; ACCD = ACCA*ACCB
ADCA #$00 ; round to 8 bits
PULB ; restore ACCB
-
8/3/2019 Sect 05 Stack Subroutine
6/15
6
EE 4535 Packet 5 11
K Using the stack
You can also use the stack to save intermediatevalues
Example: (Listing 3.1 in text)This calculates x squared plus y squared.
x and y are 8-bit numbers stored in addresses$1031 and $1032.
The 8-bit result is put in ACCA.
ORG $E000
BEGIN: LDS #$FF ; initialize SP
LDAA $1031 ; get x value
TAB ; square it
MUL
ADCA #$00 ; round to 8 bits
PSHA ; save it
LDAA $1032 ; get y value
TAB ; square it
MUL
ADCA #$00 ; round to 8 bits
PULB ; retrieve first result
ABA ; add them
EE 4535 Packet 5 12
K Dangers in using the stack
Overflow Too many pushes
Stack grows so large that it overwritesportions of memory that are being used forother purposes
Example:
ORG $E0
FOO RMB 2
ORG $E000
LDS #$FF ; initialize SP
LDAB #$FF ; initialize loop count
LOOP:
PSHA ; push value on stack
DECB ; decrement count
BNE LOOP ; and repeat
-
8/3/2019 Sect 05 Stack Subroutine
7/15
7
EE 4535 Packet 5 13
K Dangers in using the stack (continued)
Underflow Too many pulls
SP points to address higher than theintended bottom of the stack
The HC11 does not protect you from overflowor underflow!
Only way to recover is to reset the system
Be aware of the stack size that your programneeds.
Typical memory layout for EVBU:
512 bytes of RAM ($00-$1FF)
$00 - $FF used by Buffalo monitor
K Dont use these locations in yourprograms
User variables should start at $100 ($100-?)
Stack starts at $1FF (? - $1FF)
More variables = less stack space
EE 4535 Packet 5 14
Subroutines
K Why use them?
Provides modularity to reduce programcomplexity
Creates many smaller, but more easily
developed and tested program units
May save on memory space (to store program)
Can be reused in different parts of a program
Can be placed in a library for use by many
programs and applications
-
8/3/2019 Sect 05 Stack Subroutine
8/15
8
EE 4535 Packet 5 15
K Subroutines should . . .
Be small, to ease writing, testing, andmodifying
Have a well defined purpose
Have a well defined interface
Be well documented (like the rest of theprogram!)
Describe input parameters
K Registers, memory locations, values onthe stack, etc.
Describe output parameters
K Registers, memory locations, stack,condition codes
Describe any side effects
K Registers that are changed, conditioncodes, etc.
EE 4535 Packet 5 16
K Example of proper documentation format:
;******************************
; Function: ToUpper
; This function replaces all lower-case
; characters in a string with upper-case.
; The end of the string is marked with
; $00.
; Input: IX = starting address of string; Output: none
; Registers affected: ACCA, CCR
;*******************************
-
8/3/2019 Sect 05 Stack Subroutine
9/15
9
EE 4535 Packet 5 17
K Calling a subroutine
JSR sbr
BSR sbr
Address of next instruction (return address) is
pushed onto the stack
This is the current value of PC
PC is loaded with the starting address of the
subroutine
Next instruction fetched will be from the
subroutine
EE 4535 Packet 5 18
K Returning from a subroutine
RTS instruction
Must be the last instruction in subroutine
Pops return address off the stack, loads it into
PC
Next instruction fetch will be the instruction
following the JSR/BSR
If your subroutine manipulates the stack, be
aware of where the return address is stored.
It must be at the top of the stack when you
execute the RTS
-
8/3/2019 Sect 05 Stack Subroutine
10/15
10
EE 4535 Packet 5 19
K Subroutine parameter passing -- how are theparameters / arguments for the subroutine passed toit?
Registers
Parameters are placed in predetermined registerlocations
Simple and fast
Number of parameters is limited by the numberof "free" registers
Code is not reentrant
Dedicated memory
A series of (predetermined) memory locations areused to hold the parameters
Simple, but added overhead due to memoryoperations
Possible to pass many parameters
Code is not reentrant
EE 4535 Packet 5 20
Pointer to memory
Pass the subroutine a register value containingthe address of the parameters in memory
More complex, extra overhead for use of the
pointer
Code is reentrant
Use the stack
Parameters, in addition to the return address, are
pushed onto the stack -- the combination is called
the stack frame
K You must push the parameters before the JSR/BSR
Requires care in manipulating the parameters
K Dont forget about the return address!
Many parameters can be passed
Separate parameter stack can be created and used
in addition to the system stack
Code is reentrant
-
8/3/2019 Sect 05 Stack Subroutine
11/15
11
EE 4535 Packet 5 21
K Example:
Timing delay Write a subroutine that will delay for a
specified number of milliseconds. The delay
time is passed as a parameter in ACCB.
K The subroutine should also preserve the
contents of all registers as well as the
condition codes
Main program:
LDAB #$0A ; delay for 10 ms
JSR DELAY
EE 4535 Packet 5 22
K Timing delay:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Subroutine: DELAY
; This subroutine delays for a specified number of milliseconds
; Input: ACCB = desired delay time
; Output: None
; Registers affected: None
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY:
PSHB ; save ACCB
PSHA ; save ACCA
TPA ; save CCR
PSHA
DELAY_1_MS:
LDAA #LOOP_CNT ; load counterLOOP:
NOP
NOP
DECA ; decrement counter
BNE LOOP ; repeat
DECB ; decrement ms count
BNE DELAY_1_MS ; repeat
PULA ; restore CCR
TAP
PULA ; restore ACCA
PULB ; restore ACCBRTS ; return
-
8/3/2019 Sect 05 Stack Subroutine
12/15
12
EE 4535 Packet 5 23
K Example:
Write a subroutine to find the maximum of twosigned 8-bit numbers. The two numbers are
passed to the subroutine on the stack, and the
maximum is returned to the calling routine on
the stack.
Main program:
LDAA #$73 ; load the 2 values
LDAB #$A8PSHA ; push them on the stack
PSHB
JSR MAX ; find the max
PULA ; pull max off stack
EE 4535 Packet 5 24
K Example:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Subroutine - MAX
; This subroutine returns the maximum of 2
; signed 8-bit numbers.
; Input - The 2 numbers are passed on the stack
; Output - The maximum is returned on the stack
; Registers used - ACCA, ACCB, IY, CCR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAX:
PULY ; save return address
PULB ; get the 2 numbers
PULACBA ; compare them
BGT A_IS_MAX ; branch if ACCA > ACCB
B_IS_MAX:
PSHB ; return the value in ACCB
BRA MAX_EXIT
A_IS_MAX:
PSHA ; return the value in ACCA
MAX_EXIT:
PSHY ; put return address back on stack
RTS ; and return
-
8/3/2019 Sect 05 Stack Subroutine
13/15
13
EE 4535 Packet 5 25
K Example:
Convert an 8-bit hex number into 2 ASCIIcharacters
For example, convert $3F into 3 and F
The hex number is passed to the subroutine on
the stack, and the 2 ASCII characters are
returned on the stack, with the high-order
character on top.
Main program:
LDAA #$3F ; get hex number
PSHA
JSR HEX_TO_ASCII ; convert it
PULB ; ACCB = 3 = $33
PULA ; ACCA = F = $46
EE 4535 Packet 5 26
K Example
Converting hex digit to 2 ASCII characters Pseudocode:
Get hex digit from stack
Convert lower nibble to ASCII
Push char on stack
Convert upper nibble to ASCII
Push char on stack
Return
Well use a second subroutine to convert a nibble toASCII
Note that the ASCII codes for 0-9 are $30-$39,and the codes for A-F are $41-$46
Pseudocode:
Add #$30 to nibble
If (result > $39)
Add #$07
Return
-
8/3/2019 Sect 05 Stack Subroutine
14/15
14
EE 4535 Packet 5 27
K Example:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Subroutine - CONVERT_NIBBLE
; This subroutine converts a nibble (4-bit value)
; to ASCII.
; Input: ACCB contains the nibble
; Output: ACCB contains the ASCII code
; Registers affected: None
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CONVERT_NIBBLE:
PSHA ; save ACCA
TPA ; save CCR
PSHA
ADDB #$30 ; convert to ASCII
CMPB #$39 ; is nibble > 9?
BLS CN_EXIT ; branch if not
ADDB #$07 ; for A-F
CN_EXIT:
PULA ; restore CCR
TAP
PULA ; restore ACCA
RTS ; return
EE 4535 Packet 5 28
K Example:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Subroutine - HEX_TO_ASCII
; This subroutine converts an 8-bit hex number
; to two ASCII digits.
; Input: Hex number is passed on the stack
; Output: ASCII characters are returned on the
; stack, with the high-order nibble on top.
; Registers affected: ACCA, ACCB, IY, CCR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HEX_TO_ASCII:
PULY ; save return address
PULA ; get hex number
TAB ; copy it to ACCBANDB #$0F ; get lower nibble
JSR CONVERT_NIBBLE
PSHB ; save ASCII on stack
TAB ; get hex number again
LSRB ; get upper nibble
LSRB
LSRB
LSRB
JSR CONVERT_NIBBLE
PSHB ; save ASCII on stack
PSHY ; push return address
RTS ; and return
-
8/3/2019 Sect 05 Stack Subroutine
15/15
15
EE 4535 Packet 5 29
K Summary
Stack Be sure to initialize the stack pointer at the
beginning of your program
LDS #$1FF
K Dont do this if youre calling your
program from Buffalo
K Buffalo initializes SP for you
Push and Pull operations
Remember SP points to next empty location
EE 4535 Packet 5 30
K Summary
Subroutines Break your program into subroutines
K Well-defined (and documented!)
function
K Well-defined (and documented!)
interface
Passing parameters
K Use registers if possible
K Else, use stack if needed
Dont forget about the return address