jumps to a subroutine address after storing the current address on a stack in memory. When Return is invoked, the program resumes at the line following the latest Gosub.
The PIC instruction set includes call and ret, which work much like PBASIC's Gosub and Return. The trouble is that the stack that call uses to store return addresses is only two levels deep in the PIC 16C5x series. This limits you to two nested calls. In other words, a called routine can call only one other. If that routine makes a call, the program will never find its way back the starting point. By contrast, PBASIC permits 16 nested Gosubs.
The demonstration program shows how you can break the two-level limit by having your program establish and manage a stack of return addresses for separate Gosub and Return routines. The calling program must put the address of the destination subroutine into sub, and the current contents of the program counter into w. It then jumps to Gosub, which stores the return-address information on a stack at the end of memory. When the subroutine is through, it jumps to Return. Return retrieves the return address from the stack, adjusts it to point to the line after the previous jmp Gosub, and goes there.
You can nest one subroutine for each byte of memory available. For example, if your program uses memory locations 8 through 19, then locations 20 through 31 are available for use as 12-level Return stack. There is a restriction in using Gosub. Since a program can read and store only the lower eight bits of the program counter, all of the subroutines must start in the lowest 256 instruction words of a program-memory page.
To see Gosub in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run GOSUB.SRC. When you apply power to the PIC, the LEDs will light up one at a time, demonstrating that the program executed all three nested subs and returned to the main program.
; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.bubblesoftonline.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; GOSUB sub, return address (in w) ; Jumps to the address in the variable sub after storing the return address on a ; stack in general-purpose RAM. When the destination routine is finished, it ; jumps to a routine called Return, which fetches the return address off the stack, ; and jumps to the instruction following the one that invoked Gosub. ; The Gosub/Return mechanism requires exclusive use of the file-select ; register (fsr). If other parts of the program need to use the fsr, ; copy it to a variable before altering it and restore it when done. P = pic16c55 #include <16c55.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start org 8 sub Res d'1' ; Destination of Gosub. temp Res d'1' ; Variables for delays temp2 Res d'1' ; used in demo subroutines. ; Device data and reset vector org 0 start MOVLW d'0' ; All outputs for LEDs TRIS 6h CLRF 6h ; Turn LEDs off. MOVLW d'31' ; Point to end of memory MOVWF fsr MOVLW One ; Destination: One. MOVWF sub MOVF pc,w ; Save program counter. GOTO Gosub ; Gosub One. MOVLW d'15' ; LEDs on. MOVWF 6h start_loop DECFSZ temp ; Short delay. GOTO start_loop DECFSZ temp2 GOTO start_loop CLRF 6h ; LEDs off. GOTO $ ; Endless loop. Gosub MOVWF indirect ; Return addr on stack. DECF fsr ; Decrement stack pointer. MOVF sub,w ; Destination address to w. MOVWF pcl ; Go there. Return inc fsr ; Increment stack pointer <Microchip instruction> INCF indirect,w ; w = return addr + 1. MOVWF pcl ; Jump to return addr. ; GOSUB (cont) ; Demonstration routines to show successful nesting of ; three Gosubs. One MOVLW d'1' ; LED on. MOVWF 6h One_loop DECFSZ temp ; Short delay. GOTO One_loop DECFSZ temp2 GOTO One_loop CLRF 6h ; LEDs off MOVLW Two ; Destination: Two. MOVWF sub MOVF pc,w ; Save program counter. GOTO Gosub ; Gosub Two. GOTO Return ; Return. Two MOVLW d'3' ; LEDs on. MOVWF 6h Two_loop DECFSZ temp ; Short delay. GOTO Two_loop DECFSZ temp2 GOTO Two_loop CLRF 6h ; LEDs off MOVLW Three ; Destination: Three. MOVWF sub MOVF pc,w ; Save program counter. GOTO Gosub ; Gosub Three GOTO Return ; Return. Three MOVLW d'7' ; LEDs on. MOVWF 6h Three_loop DECFSZ temp ; Short delay. GOTO Three_loop DECFSZ temp2 GOTO Three_loop CLRF 6h ; LEDs off GOTO Return ; Return. end
; GOSUB sub, return address (in w) ; Jumps to the address in the variable sub after storing the return address on a ; stack in general-purpose RAM. When the destination routine is finished, it ; jumps to a routine called Return, which fetches the return address off the stack, ; and jumps to the instruction following the one that invoked Gosub. ; The Gosub/Return mechanism requires exclusive use of the file-select ; register (fsr). If other parts of the program need to use the fsr, ; copy it to a variable before altering it and restore it when done. org 8 sub ds 1 ; Destination of Gosub. temp ds 1 ; Variables for delays temp2 ds 1 ; used in demo subroutines. ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 start mov !rb, #0 ; All outputs for LEDs clr rb ; Turn LEDs off. mov fsr,#31 ; Point to end of memory mov sub,#One ; Destination: One. mov w,pc ; Save program counter. jmp Gosub ; Gosub One. mov rb,#15 ; LEDs on. :loop djnz temp,:loop ; Short delay. djnz temp2,:loop clr rb ; LEDs off. jmp $ ; Endless loop. Gosub mov indirect,w ; Return addr on stack. dec fsr ; Decrement stack pointer. mov w,sub ; Destination address to w. jmp w ; Go there. Return inc fsr ; Increment stack pointer mov w,++indirect ; w = return addr + 1. jmp w ; Jump to return addr. ; GOSUB (cont) ; Demonstration routines to show successful nesting of ; three Gosubs. One mov rb,#1 ; LED on. :loop djnz temp,:loop ; Short delay. djnz temp2,:loop clr rb ; LEDs off mov sub,#Two ; Destination: Two. mov w,pc ; Save program counter. jmp Gosub ; Gosub Two. jmp Return ; Return. Two mov rb,#3 ; LEDs on. :loop djnz temp,:loop ; Short delay. djnz temp2,:loop clr rb ; LEDs off mov sub,#Three ; Destination: Three. mov w,pc ; Save program counter. jmp Gosub ; Gosub Three jmp Return ; Return. Three mov rb,#7 ; LEDs on. :loop djnz temp,:loop ; Short delay. djnz temp2,:loop clr rb ; LEDs off jmp Return ; Return.
See also:
file: /Techref/microchip/seepicsrc/psbpix/gosub.htm, 11KB, , updated: 2003/11/30 19:59, local time: 2024/12/24 21:34,
owner: DAV-MP-E62a,
52.14.173.116:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/microchip/seepicsrc/psbpix/gosub.htm"> microchip seepicsrc psbpix gosub</A> |
Did you find what you needed? |