PASM - Nested Call question
Chris_D
Posts: 305
Hi folks,
After reading through the manual about call, I think I understand it but would like a bit of clarification.
It appears that a subroutine cannot call itself (recursive).
Can a subroutine call another subroutine and if so, is there any limit to the depth of called subroutines?
Main...
·· Call Sub1
Main end...
Sub1
·· Call Sub2
Sub1_Ret
Sub2
Sub2_Ret
Chris
After reading through the manual about call, I think I understand it but would like a bit of clarification.
It appears that a subroutine cannot call itself (recursive).
Can a subroutine call another subroutine and if so, is there any limit to the depth of called subroutines?
Main...
·· Call Sub1
Main end...
Sub1
·· Call Sub2
Sub1_Ret
Sub2
Sub2_Ret
Chris
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
· Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
BUT a subroutine cannot call itself recursively or be a part of a chain of recursive calls.
So this won't work: A calls A
and this won't work: A calls B calls C calls A.
As you may have read the the return address for a CALL is stored in the RET instruction of the called function. So a recursive call would destroy the previous calls return address.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
If you really need nested calls, you would have to save the return address yourself on entry into the subroutine and restore it before you hit the return.
Note the movs in the exit code. It copies bits 8..0 of the source (tmp) to the source field (also bits 8...0) of the destination without touching the other bits.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 11:43:06 AM GMT
Why would you copy nested_subroutine_ret to tmp before writing to HUB-RAM?
wrword nested_subroutine_ret, stackptr 'is doing the same job
And what about
rdword nested_subroutine_ret, stackptr
movi nested_subroutine_ret, # code for ret
? Shouldn't that work as well ... would save a LONG because tmp·is no longer needed then·;o)
Post Edited (MagIO2) : 3/15/2010 1:02:09 PM GMT
You know, there is always one last bug in any piece of code.
Further any piece of code can be made shorter by at least one instruction.
The logical consequence is that every code consists of one instruction which is wrong.
Thanks for the hint. Yes, using tmp isn't necessary. I first had an AND tmp, #$1ff in there until it came to me that the MOVS later on would do the masking anyway, so I removed the AND again.
Your version of the exit code needs to insert a NOP before the RET, so we are on par again
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/15/2010 1:43:06 PM GMT
Chris
It uses the cog for the stack (assuming you've got the room and don't recurse too deeply) so there's no hub access penalty. The stack pointer is embedded in the first instruction of enter.
Please remember: You do not need to do this for nested subroutines -- only those which create a recursion loop. Nested subroutines take care of themselves.
-Phil