Stacks and Subroutines. Some example stacks Stacks and subroutine usage The stack is a special area...
-
Upload
june-short -
Category
Documents
-
view
235 -
download
3
Transcript of Stacks and Subroutines. Some example stacks Stacks and subroutine usage The stack is a special area...
Stacks and Subroutines
Some example stacksSome example stacks
Stacks and subroutine usageStacks and subroutine usage
• The stack is a special area of the random access memory in the overall memory system
• The stack is used foro General data storage (limited)
o Temporary data storage (true)
o Parameter and control information storage for subroutines (yes!)
StackStack
• Last-in, first-out (LIFO) structure• All access is at the top of the stack• Operations
o PushPlaces an item onto the stack
o PullRemoves an item from the stackSome (most!) people use the term “pop”
• Bottom of the stack is at highest memory address, and top of the stack is at the lowest addresso Stack grows from high to low address
Cont..
StackStack
o For EVBU, stack is usually placed at $01FF
• Stack Pointer (SP)o Register that points to the memory location immediately
preceding the top of the stack
o In other words, the SP normally contains the address for a new data item to be pushed
Cont..
HC11 ImplementationHC11 Implementation
PUSH InstructionsPUSH Instructions
• Push instructionso 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
o How can we push CCR?
PUSH InstructionsPUSH Instructions
• Pull instructionso PULA, PULB, PULX,
PULY Increments SP Loads data from
memory address pointed to by SP
Other Stack OperationsOther Stack Operations
• Other stack operationso 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 IY
TXS Transfer IX-1 to SP
TYS Transfer IY-1 to SP
StacksStacks
• Stackso Remember to initialize SP at beginning of
o program
o Important to pull data in reverse order that you pushed it
o Note that SP points to empty memory location (= location where next value will be stored)
Using the StacksUsing the Stacks
• Using the stacko Passing parameters to subroutines (more on this later)
o Temporary storage68HC11 has limited number of registersUse stack to preserve register values
• 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
Cont..
Using the StacksUsing the Stacks
• Using the stacko You can also use the stack to save intermediateo valueso 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 $E000BEGIN: LDS #$FF ; initialize SPLDAA $1031 ; get x valueTAB ; square it
Cont..
Using the StacksUsing the Stacks
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
Dangers Using the StacksDangers Using the Stacks
• Dangers in using the stacko Overflow
Too many pushesStack grows so large that it overwrites portions of memory that
are being used for other purposes Example:ORG $E0FOO RMB 2ORG $E000LDS #$FF ; initialize SPLDAB #$FF ; initialize loop countLOOP:
Cont..
Dangers Using the StacksDangers Using the Stacks
PSHA ; push value on stack
DECB ; decrement count
BNE LOOP ; and repeato Underflow
Too many pullsSP points to address higher than the intended bottom of the
stack
o The HC11 does not protect you from overflow or underflow!Only way to recover is to reset the systemBe aware of the stack size that your program needs.
Cont..
Dangers Using the StacksDangers Using the Stacks
o Typical memory layout for EVBU:512 bytes of RAM ($00-$1FF)$00 - $FF used by Buffalo monitor
• Don’t use these locations in your programsUser variables should start at $100 ($100-?)Stack starts at $1FF (? - $1FF)More variables = less stack space
SubroutineSubroutine
• Why use them?o Provides modularity to reduce program complexityo Creates many smaller, but more easily developed and tested
program unitso May save on memory space (to store program)o Can be reused in different parts of a programo Can be placed in a library for use by many programs and
applications
• Subroutines should . . .o Be small, to ease writing, testing, and modifyingo Have a well defined purposeo Have a well defined interface
Cont..
SubroutineSubroutine
o Be well documented (like the rest of the program!) Describe input parameters
• Registers, memory locations, values on the stack, etc.Describe output parameters
• Registers, memory locations, stack, condition codesDescribe any side effects
• Registers that are changed, condition codes, etc.
Example of proper Example of proper Documentation FormatDocumentation Format
• 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;*******************************
Calling SubroutinesCalling Subroutines
• Calling a subroutineJSR sbr
BSR sbr• Address of next instruction (return address) is pushed onto the
stackThis is the current value of PC
o PC is loaded with the starting address of the subroutineNext instruction fetched will be from the subroutine
Returning SubroutineReturning Subroutine
• Returning from a subroutineo RTS instruction
o Must be the last instruction in subroutine
o Pops return address off the stack, loads it into PCNext instruction fetch will be the instruction following the
JSR/BSR
o 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
Subroutine Parameter PassingSubroutine Parameter Passing
• Subroutine parameter passing -- how are the parameters / arguments for the subroutine passed to it?o Registers
Parameters are placed in predetermined register locationsSimple and fastNumber of parameters is limited by the number of "free"
registersCode is not reentrant
o Dedicated memoryA series of (predetermined) memory locations are used to
hold the parameters
Cont..
Subroutine Parameter PassingSubroutine Parameter Passing
Simple, but added overhead due to memory operationsPossible to pass many parametersCode is not reentrant
o Pointer to memoryPass the subroutine a register value containing the address
of the parameters in memoryMore complex, extra overhead for use of the pointerCode is reentrant
o Use the stackParameters, in addition to the return address, are pushed
onto the stack -- the combination is called the stack frame• You must push the parameters before the JSR/BSR
Cont..
Subroutine Parameter PassingSubroutine Parameter Passing
Requires care in manipulating the parameters
• Don’t forget about the return address!Many parameters can be passedSeparate parameter stack can be created and used in
addition to the system stackCode is reentrant
ExampleExample
• Example:
o Timing delayWrite a subroutine that will delay for a specified
number of milliseconds. The delay time is passed as a parameter in ACCB.
• The subroutine should also preserve the contents of all registers as well as the condition codes
o Main program:LDAB #$0A ; delay for 10 ms
JSR DELAY
ExampleExample
• Example:o Write a subroutine to find the maximum of two signed 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.
o Main program:LDAA #$73 ; load the 2 valuesLDAB #$A8PSHA ; push them on the stackPSHBJSR MAX ; find the maxPULA ; pull max off stack
ExampleExample
• 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
Cont..
ExampleExample
PULACBA ; compare themBGT A_IS_MAX ; branch if ACCA > ACCB
B_IS_MAX:PSHB ; return the value in ACCBBRA MAX_EXIT
A_IS_MAX:PSHA ; return the value in ACCA
MAX_EXIT:PSHY ; put return address back on stackRTS ; and return
ExampleExample
• Example:o Convert an 8-bit hex number into 2 ASCII characters
For example, convert $3F into ‘3’ and ‘F’o 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.
o Main program:LDAA #$3F ; get hex numberPSHAJSR HEX_TO_ASCII ; convert itPULB ; ACCB = ‘3’ = $33PULA ; ACCA = ‘F’ = $46
ExampleExample
• Exampleo Converting hex digit to 2 ASCII characters
Pseudo code:Get hex digit from stackConvert lower nibble to ASCIIPush char on stackConvert upper nibble to ASCIIPush char on stackReturn
o We’ll use a second subroutine to convert a nibble to ASCIINote that the ASCII codes for 0-9 are $30-$39, and the
codes for A-F are $41-$46
Cont..
ExampleExample
Pseudo code:
Add #$30 to nibble
If (result > $39)
Add #$07
Return
ExampleExample
• 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
Cont..
ExampleExample
TPA ; save CCRPSHAADDB #$30 ; convert to ASCIICMPB #$39 ; is nibble > 9?BLS CN_EXIT ; branch if notADDB #$07 ; for A-F
CN_EXIT:PULA ; restore CCRTAPPULA ; restore ACCARTS ; return
ExampleExample
• 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
Cont..
ExampleExample
PULA ; get hex numberTAB ; copy it to ACCBANDB #$0F ; get lower nibbleJSR CONVERT_NIBBLEPSHB ; save ASCII on stackTAB ; get hex number againLSRB ; get upper nibbleLSRBLSRBLSRBJSR CONVERT_NIBBLE
Cont..
ExampleExample
PSHB ; save ASCII on stack
PSHY ; push return address
RTS ; and return
SummarySummary
• Summary
o StackBe sure to initialize the stack pointer at the
beginning of your program
LDS #$1FF• Don’t do this if you’re calling your program from Buffalo
• Buffalo initializes SP for youPush and Pull operationsRemember SP points to next empty location
SummarySummary
• Summaryo Subroutines
Break your program into subroutines
• Well-defined (and documented!) function
• Well-defined (and documented!) interfacePassing parameters
• Use registers if possible
• Else, use stack if needed
o Don’t forget about the return address