In SX Microcontrollers, SX/B Compiler and SX-Key Tool, g_daubach wrote: Sam, hiere is a little test program: [code] LIST Q = 37 DEVICE SX28L, TURBO, STACKX, OSCHS2 IRC_CAL IRC_FAST FREQ 50_000_000 RESET Main ;MISSING_PAGE ;BAD_RET org 0 Main call Sub1 clr 8 ; dummy instruction jmp Main Sub1 ifdef MISSING_PAGE jmp _Sub1 ; bad jump to page 0, address 0, i.e. to Main else page _Sub1 ; seting the page first jmp _Sub1 ; performs a good jump to _Sub1 ; jmp @_Sub1 ; Shorthand for the previous two lines endif org $200 _Sub1 clr 8 ; dummy instruction ifdef BAD_RET ret ; Causes a bad jmp Main later as the page is ; wrong else retp ; Restores the page, so the jmp Main is done ; correctly endif[/code] First single-step it with SXSim, or with SX-Key on a "real chip" as is. Sub1 is called from Main with Sub1 located in the same page as Main. In Sub1, a jump to _Sub1 is performed which is located in Page $200. Therefore, it is necessary to set the page correctly before the jump. _Sub1 terminates with RETP which means that the page is restored to the page of the calling code (Main, or page 0 in this case), and the next instruction following the call (clr 8) will be executed next. Now remove the semicolon in front of MISSING_PAGE, and single-step again. When the jmp _Sub1 instruction is executed, you will notice that the jump does not go there but to Main instead. This is because the page is wrong (still page 0), so the jump is performed to address 0 in page 0 (which is Main) but not to page $200, address 0, where _Sub1 is located. Next, place a semicolon in front of MISSING_PAGE again to correct that error, and remove the semicolon in front of BAD_RET. Again single-step the program. On the first glance, it seems as if everything is fine but notice what happens when the jmp Main is executed after the subroutine call, and the clr 8. The program jumps to _Sub1 and not to Main as expected. As this time, the subroutine ends with RET insted with RETP, the return from the subroutine is performed as expected, but the selected page is still $200. This means that jmp Main jumps to address 0 in page $200 (to _Sub1) instead to address 0 in page 0 (to Main). So both return instructions cause a return to the instruction following the call but RETP in addition restores the page bits in STATUS to the caller's page. To be honest, I could not find a situation where using RETP caused trouble, even when the call and the return are both located in the same page. So I alays use RETP instead of RET just to avoid such problems. Instead of RETP you might use the sequece: page 0 ret in the subroutine which restores the page back to Main before returning but this is no good programming style, as a subroutine should be designed like "black boxes", not knowing who called them and from where. Instead, you might place the page 0 instruction following the call Sub1 instruction in Main. But why make things more complicated than necessary - simply use RETP, and you are in good shape. RETW also does a return from a subroutine. In addition, it stores the parameter given to RETW in W on return. Note that RETW does not rsetore the page, so be careful when changing pages in between. ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=104866#m104892 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)