Reading the stack
Armored Cars
Posts: 172
Is there a way to read the top of the stack so a subroutine can know where it was called from?· I would prefer this over setting some bits in my mishmash variable (slower, makes uglier code).
Thanks
Thanks
Comments
Inside the isr it is possible using the secret instruction popPC.
For normal calls, you could pass the return address to the
subroutine, then use pushPC and reti to jump back to
that address.
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
use the debugger. The shadow stack is only 2 levels deep.
(isr and debug, or isr and your use)
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
http://forums.parallax.com/showthread.php?p=542748
regards peter
MOV·W,JMPLOC·;Load W with "Next" Addr on this 1/2 Page2
If I am reading this correctly this will load w with the next address.· If "next address" means the top of the stack or where the next ret will return to, that code·will do exacly what I need.
http://forums.parallax.com/showthread.php?p=520630
regards peter
from location 1
mov m,#($+4)>>8
mov w,#adr1
call @mySub
adr1:·· ;ret adr for this call
from location 2
mov m,#($+4)>>8
mov w,#adr2
call @mySub
adr2:·· ;ret adr for this call
mySub:
;save m and w for reference or store to private stack or whatever
;do some code
retp· ;return to adr1 or adr2, specified by m and w
regards peter
·
I'd like to pipe in here as I have some experience at this.
The 8 level CALL STACK is totally independent of the 2 level SHADOW STACKS, and the CALL STACK is not accessible under program control in any manner that I have been able to determine.
As Peter V indicates, the desired action could be simulated by saving a return address prior to jumping to (calling) the subroutine, and then returning from the subroutine via pushing the saved return address on the M:W registers and forcing the return jump via the RETI instruction.
There is caution to be used here as there are also hidden STATUS bits that get effected on executing a RETI.
Paul;
Your description is not correct; pushPC loads M:W into the PCshadow, and popPC does the reverse. It takes a RETI to trigger the jump, but of course all other shadows are then also popped, thereby changing the whole state of the processor.
As an answer to Armored Cars' original post, my recommendation for the casual programmer is to just use the standard call/return instructions if at all possible. The other approaches, while possible as in the RTOS I have written, are quite involved.
Cheers,
Peter (pjv)
While your suggestion is technically correct, I believe that your last line (retp ;return to adr1 or adr2, specified by m and w) may lead the reader to believe that the return is directed by the contents of M and W, rather than the entry at the top of the call stack.
The contents of M and W are totally irrelevant to the return; you had simply chosen them as a convenient location to save the return address so that the subroutine code could use it if so required.
Also, would loading M and W also not be written somewhat more simply as:
Location1· ·· ·code···························· ;arbitrary code
· ··············· ·code···························· ;arbitrary code
············· ···· mov··· m,#Return1>>8··· ;get the upper 4 return address bits into m (must go through w for SX48/52)
·· ········· ····· mov··· w,#Return1········· ;get the lower 8 return address bits into w
················· ·call·····Subroutine··········· ;go to the routine
Return1······· ·code···························· ;arbitrary code
·················· code···························· ;arbitrary code
Subroutine·····code···························· ;arbitrary code
···················code···························· ;arbitrary code
·················· retp
Cheers,
Peter (pjv)
Post Edited (pjv) : 11/1/2005 6:11:41 PM GMT
Yes, that would rule out possible errors due to counting storage words.
And yes, the example only shows how to pass the value that is on top of
stack (after call Subroutine), to be used in the subroutine, without changing the
call/return scheme.
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10
Sorry to keep harping on this, but I understood your suggestion (pushPC) to literally mean that you expected the PC itself to be pushed onto the shadow stack, and this of course is not how it works; pushPC pushes M:W onto the PCshadow.
And the converse, popPC pops the PCshadow into M:W.
It is the RETI instruction that pops the PCshadow into the PC; and, as previously noted, all other shadows (W, FSR,STATUS), into their respective registers.
Cheers,
Peter (pjv)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·1+1=10