Gosub chaining to conserve gosub slots...

DamonHD

Senior Member
Hi,

Bearing in mind the limited number of total gosubs that can be made in a PICAXE program, is it possible in general to replace the sequence:

Code:
subroutineA:
    ...
    gosub subroutineB
    return
given:

Code:
subroutineB:
    ...
    return
with:

Code:
subroutineA:
    ...
    goto subroutineB
ie chain the subroutines and let the return at the end of subroutineB return to subroutineA's caller, and save a gosub slot?

Rgds

Damon

PS. How would the chained solution's speed compare to the normal original version?
 

inglewoodpete

Senior Member
Is this really a problem with modern PICAXEs? I've written some monster programmes that fill several memory slots on 28X2s and 40X2s and have never encountered subroutine number problems (or nesting problems either). I've also filled 28X1s and 40X1s with no ill effects, prior to upgrading to X2s.

Perhaps you are not using gosubs in a conventional way? Added: or is this an M2-centric problem?
 
Last edited:

DamonHD

Senior Member
Hi,

It's an unusual constraint and because I don't get any warning of how near I am to the limit, and some optimisations such as loop unrolling would cause me to use a lot of gosubs, it's been preying on my mind!

Rgds

Damon
 

PaulRB

Senior Member
I would think that would work perfectly and the speed would be the same or slightly better, because you are replacing a gosub & return with a goto.

Paul
 

DamonHD

Senior Member
OK, I'm testing it out now with no apparent ill effects and some apparent reduction in program size (which is a bonus).
 

geoff07

Senior Member
The interpreter would only see the code that executes so there should be no problem with the stack. After all, a subroutine entry is only a label. Whether the code is intelligible three months later is another matter. Your code must be very complex to need 255 nested calls.
 

lanternfish

Senior Member
I have always followed the advice to question whether a particular gosub is necessary. And that means taking a close look at how often a particular subroutine is called and if only once then it can be part of the calling routine. If the subroutine is called a couple of times there may be a more efficient way to deal with a procedure.
It would be interesting to see code to see if you are possibly using gosubs unnecessarily.
 

geoff07

Senior Member
Another reason for using gosubs is code clarity. It can be much easier to understand if chunks of code that have a single purpose can be replaced with a descriptively-named subroutine call. This may be possible in future with the pre-processor as it has been for years with high-level languages in general such as 'C', but using current PE versions it is necessary. Few microcontroller programs use all the code space or execution cycles so efficiency is not generally as much of an issue as clarity and maintainability.
 

DamonHD

Senior Member
Indeed: I use subroutines to structure code and improve clarity, and inline occasionally for performance. But if using lots of gosubs was suddenly going to have me hit a brick wall I was worried that I might need an escape route, and that gosub chaining for this simple architecture with no stacked arguments might be it.

Rgds

Damon
 

westaust55

Moderator
An option may be to consider the
ON...GOSUB command.
The enables you to access multiple routines with a single GOSUB
Which From memory only counts as a single GOSUB
 

DamonHD

Senior Member
Well there's an interesting idea: not many places that I could apply it but I had been considering it (or on...goto) as an alternative to select in some cases. My main task dispatch point would be a good place for that!

Rgds

Damon
 

westaust55

Moderator
Be aware that while ON...GOSUB will reduce the GOSUB count it will/can increase the overall program space requiremnents.
 

hippy

Technical Support
Staff member
Be aware that while ON...GOSUB will reduce the GOSUB count it will/can increase the overall program space requiremnents.
Some of that can be claimed back by re-coding and using GOSUB chaining already discussed.

Code:
  On <var> Gosub x, y, z
  End
Can instead be coded as -

Code:
  Gosub Dispatch
  End

Dispatch:
  On <var> Goto x, y, z
  Return
 
Top