180 likes | 284 Views
Calling subroutines in assembly. And using the Stack. CS2851 Review: the Queue. Queue: a traditional CS data structure Classical semantics (behavior) are: Elements can only be inserted at the back and removed from the front of the collection This is known as First-In, First-Out (FIFO).
E N D
Calling subroutines in assembly And using the Stack CS-280 Dr. Mark L. Hornick
CS2851 Review: the Queue Queue: a traditional CS data structure • Classical semantics (behavior) are: • Elements can only be inserted at the back and removed from the front of the collection • This is known as First-In, First-Out (FIFO) CS-280 Dr. Mark L. Hornick
JCF Queue – behavioral methods • offer() – place an element at the back of the queue • poll() or remove() – return and remove an element from the front of the queue • poll() returns null if the queue is empty • remove() throws an exception if the queue is empty • peek() or element() – return (without removing) the element at the front of the queue • peek() returns null if the queue is empty • element() throws an exception if the queue is empty CS-280 Dr. Mark L. Hornick
CS2851 Review: Stack Another traditional CS data structure • Classical semantics (behavior) • Elements can only be inserted and removed from the front of the collection • This is known as Last-In, First-Out (LIFO) • Less commonly: First-Out, Last-In (FILO) • Random-access is not defined CS-280 Dr. Mark L. Hornick
JCF Stack – behavioral methods • The naming for the structure and the methods is an analogy for how the data elements within the structure are accessed • Principal methods that define behavior: • push() – place an element on (top of) the stack • pop() – return and remove an element from the (top of the) stack • peek() – return the top element of the stack • Without removing (popping) it CS-280 Dr. Mark L. Hornick
Most CPUs have a built-in implementation of Stack • The actual stack data structure is just an ordered collection of bytes • The stack “data structure” is maintained in Data Memory • A special CPU register (SP) is used to keep track of the front of the stack • Dedicated instructions are used to push data (bytes) onto and pull items from the stack CS-280 Dr. Mark L. Hornick
By convention, the stack starts at (or very near) the end of data memory • On our Atmega32 systems, the high address in Data Memory is 0x85F • Because we have 2048 (0x800) bytes of SRAM • And the first 96 (0x60) bytes are assigned to Registers and IO Ports • The address 0x085F is .EQU’d in m32def.inc as RAMEND Mapped toRegistersand IO 0x0000to0x005F 0x0060to0x085F UsableSRAM CS-280 Dr. Mark L. Hornick
The special register (SP) used to maintain the stack is called the Stack Pointer • Like X, Y, and Z, the SP is a 16-bit register divided into two 8-bit registers • If SP contains the address 0x085F: • SPL contains the low byte of the address of the front of the stack (e.g. 0x5F) • SPH contains the high byte(e.g. 0x08) . . . CS-280 Dr. Mark L. Hornick
The SP registers are located in the IO address space • In the IO address space • SPL address is 0x3D • SPH address is 0x3E • These are .DEF’d in m32def.inc • SP registers are set using the OUT instruction • similar to how PORTB is written to ldi TEMP, LOW(RAMEND) out SPL,TEMP ldi TEMP,HIGH(RAMEND) out SPH, TEMP . . . 0x085B 0x085C 0x085D 0x085E 0x085F SP CS-280 Dr. Mark L. Hornick
The stack starts out with a size of 0 Data (bytes) are pushed onto the front of the stack • The front of the stack grows “downward” towards lower memory address . . . Front of Stack growsdownward 0x085B 0x085C 0x085D 0x085E 0x085F SP start CS-280 Dr. Mark L. Hornick
Using the Stack – pushing a byte onto the stack LDI R20, 5 ; load 5 to R20 PUSH R20 ; push 5 to stackINC R20PUSH R20 ; push 6 to stackINC R20PUSH R20 ; push 7 to stack 0x085B 0x085C 0x085D 0x085E 0x085F SP (after 3) SP (after 2) SP (after 1) SP (before) 7 • SP is automaticallydecremented by each PUSH instruction 6 5 CS-280 Dr. Mark L. Hornick
Using the Stack – pulling a byte from the stack POP R21 ; pull 7 from stackPOP R22 ; pull 6 from stackPOP R23 ; pull 5 from stack • SP is automaticallyincremented by each POP instruction • Although the SP is incremented, the values in Data Memory are not actually removed 0x085B 0x085C 0x085D 0x085E 0x085F SP (before) SP (after 1) SP (after 2) SP (after 3) 7 6 5 CS-280 Dr. Mark L. Hornick
OK, so how do you actually use the stack to do something useful? • Demo CS-280 Dr. Mark L. Hornick
Instructions for calling a subroutine • RCALL <close_address> ; relative call • Like RJMP, where the call target address must be no more than +/- 2K from the call origin • Operand can be a raw address (e.g. 0x0123) or a label that represents an address • CALL <far_address> ; long call • Like JMP, where the call target address can be any address 0x0-0xFFFF • ICALL ; indirect call • Call target address is contained indirectly in the Z register • Z register can contain any address 0x0-0xFFFF • The address of the next instruction following RCALL, CALL, or ICALL is automatically pushed onto the Stack CS-280 Dr. Mark L. Hornick
The address of the next instruction following RCALL, CALL, or ICALL is automatically pushed onto the Stack 0x002A ldi r0,1 ; sample instruction 0x002B RCALL sub1 ; call subroutine0x002C CLR r0 ; sample instruction SP is automatically decremented by RCALL by 2 bytes (2-byte address) The low byte is pushed first, followed by the high byte Program execution jumps to the first instruction in sub1 0x085B 0x085C 0x085D 0x085E 0x085F SP (after RCALL) SP (before RCALL) 0x00 0x2C CS-280 Dr. Mark L. Hornick
Only one instruction is used for returning from a subroutine • RET ; return from subroutine • The return address (the address of the instruction that immediately followed the RCALL, CALL, or ICALL) is popped from the Stack and placed in the PC • SP is pre-decremented during execution of RET • RET is the ONLY way to return from a subroutine • NEVER use RJMP or JMP to return • SP will not get decremented without RET • Never use JMP, RJMP, or IJMP to call a subroutine • The Stack will not get incremented • Use only CALL, RCALL, or ICALL CS-280 Dr. Mark L. Hornick
When the RET statement in the subroutine is executed, the return address is popped from the Stack and placed in the PC 0x002A ldi r0,1 ; sample instruction 0x002B RCALL sub1 ; call subroutine0x002C CLR r0 ; sample instruction • SP is automatically incremented by RETby 2 bytes (2-byte address) • The high byte is popped first, followed by the low byte • Program execution resumes at address 0x002C after the RET from sub1 0x085B 0x085C 0x085D 0x085E 0x085F SP (before RET) SP (after RET) 0x00 0x2C CS-280 Dr. Mark L. Hornick
Some more uses for the stack • Short term data storage • vs. regular Data Memory storage • Easy to just PUSH and POP data on/off the stack vs. LD/ST from memory • Preserving registers during calculations • PUSH a register value onto the Stack to save it • Do some other work involving that register • POP the value off the Stack back into the register • Preserving registers prior to a subroutine call • PUSH register values onto the Stack to save them • Call subroutine(s) that might use those registers • POP the values off the Stack back into the registers after the subroutine call returns