sect 05 stack subroutine

Upload: teph-stef

Post on 06-Apr-2018

236 views

Category:

Documents


0 download

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