PDA

View Full Version : cancelling gosubs



rossfree
- 17th February 2005, 15:52
Hi all,

I hate asking stupid questions so I beg forgiveness if this is one of them...

Using Picbasic Pro... if I "gosub" and then wind up somewhere in the program where I need to "goto", is there a simple way to break the chain of gosubs and start anew? Can gosubs be cancelled?

I hope this question made sense. Slap me if I need it. :-P

Ross

mister_e
- 17th February 2005, 16:06
SLAP! ;)

i don't understand what you need to do ... sorry

rossfree
- 17th February 2005, 16:51
Main:
do this
do that
gosub here
goto main
end

Here:
if do_dat_squat then goto there
do this
do that
return

There:
do this
do that
goto main

If the "IF" statement is true then the program winds up going back to "MAIN". Does the program think it is still nested in a subroutine?

If so, can the nested subroutines be cleared?

I needed the slap. *-)

Ross

mister_e
- 17th February 2005, 17:42
If the "IF" statement is true then the program winds up going back to "MAIN". Does the program think it is still nested in a subroutine?

yes... but in this case why not changing you if then goto to a if then gosub... that will fix it.

but in case you don't want to do what is next t your if then, i suggest you to set a flag to avoid this.. something like


VoidStatementsNextToIF = 0
Main:
do this
do that
gosub here
goto main

Here:
if do_dat_squat then Gosub There
IF VoidStatementsNextToIF=0 then
do this
do that
endif
VoidStatementsNextToIF = 0
return

There:
VoidStatementsNextToIF = 1
do this
do that
Return

Ron Marcus
- 17th February 2005, 20:00
I'd say don't do another Gosub, but do a goto as you have it. When you are done with that code, just insert a Return. It'll take you right back to main. Keep in mind, a Return from any subroutine will take you back to the last Gosub + 1 line.

Hope this helps,
Ron

languer
- 17th February 2005, 22:36
Remember that you can only nests gosubs as long as you have a stack to do so. If you nest gosubs deeper than your stack (which is only 4-8 levels in many cases, and you need to save some if your use interrupts) you will crash your PIC.

I would say, unless you have to use gosubs, don't. If you have to nest gosubs many levels deep, you should look for a different approach.

Just my two cents.

Warrier
- 18th February 2005, 01:24
Hi all:

Am I missing something and need a slap also?
Why can't the following work?

Main:
do this
do that
gosub here
goto main
end

Here:
if do_dat_squat then there
do this
do that
return

There:
do this
do that
return


This will close the gosub in either case of Here & There and take the routine to main which is the gosub+1 location....

-warrier

rossfree
- 18th February 2005, 10:16
Warrier,

Yep that would do it alright... if... you wanted to return to the line following the gosub.

My initial question was can you break out of a gosub nest... can the gosub be canceled such that a "return" would go nowhere. And from the replys I am getting that you can't.

That being said, if... while nested in a subroutine... the program comes across the original gosub... it does not cancel the original subroutine... rather it increments the stack count by one.

Such as...

Main:
gosub here
goto main
end

Here:
if this goto Main
do that
return

If this is true, the gosubs loop until they violate the stack count and the pic crashes (he purses his lips and makes a pffrrgghh sound). I love sound effects.

:-)

I can write code to get around things alright, but I wanted to just cancel where I was in subroutine and go back to "Main"... not "Return" to the next line following the "gosub".

Ross

hmr
- 18th February 2005, 13:53
Hi All,

Answering your question (rosfree) about the clearing nested subroutines, the answer is no. The subroutines can't be cleared what you have to do is set a lot of flags or just review all your algorithm to fit your needs.

Some time ago I had a problem with nested gosubs and had to use goto's mixed with gosub's it was a pain to figure out how to do that and I had to rewrite all the program. So my sugestion is: Stop and check all your needs before start writing your code. Check the manual for compiler limitations. It will save you a lot of time.


Main:
do this
do that
gosub here
goto main
end

Here:
if do_dat_squat then goto there
do this
do that
return

There:
do this
do that
goto main

What you can do is setting a flag and testing it so instead of using the "goto main" you just use the "return".

Main:
do this
do that
gosub here
goto main
end

Here:
if do_dat_squat then
flag=1
goto there
endif
do this
do that
return

There:
do this
do that
if flag=1
flag=0
return
endif
goto main


I'm not sure what are your needs but this is not a real good programming technique and it can spend a lot of space in programs memory (it will depend on how the compiler translate it).

Will you call the "There" routine in other parts of the program? if not and if you didn't use all the stack with nested gosubs, the best way is to call the routine or just follow Mister_e example that saves you a lot of trouble.


Hope this help.

Hans

Warrier
- 18th February 2005, 16:00
Ross:

I think you can break out of a gosub using the BREAK command and NOT return to the gosub+1 line of the code!

I've tried this a few times in the past but haven't tried to see if there would be a stack overflow problem and genarate the sound effect you're so fond of!

-warrier

rossfree
- 18th February 2005, 16:35
Warrier,

I'm familiar with broken... but not with break.

Is there such a command in PicBasic Pro or is this where I just toss the board and all of it's assundries out the two-story window?

I don't know assembler so if that's where this command comes from can you provide a bit more detail on it's use?

Window open... circuitboard in hand... *pause*

Ross

Warrier
- 18th February 2005, 17:33
Ross:

I have used the break command and PBP seems to accept this without the in-line @ for assembler! But I don't see it listed in the manual..... break seems to clear the gosub from the stack.

Melanie or Steve can come here and help?

-warrier

languer
- 20th February 2005, 09:21
Sorry to break your bubble guys, but the gosub/stack limitation has nothing to do with PBP.

The PICs do not have a way of 'POPing' the stack (hey, they're extremely powerful for their size - something's gotta give). A GOSUB is no more than a CALL in assembly. When a CALL is made the next address is 'PUSHed' into the stack, when the RETURN is encountered the stack is 'POPed'. So you see, without any other way of 'POPing' the stack you will overflow if you keep nesting GOSUBs.

Not to worry though, amazing programs have been made with these little devices for more than a decade. Just have to be more careful and a little creative.

mister_e
- 20th February 2005, 10:06
i agree.

Your program must have a structure to avoid breaking gosubs... not a common used to do that. Sometime some goto,branch and FLAG variable will do the job. That's once again food for brain cells...

always keep in mind of what you do and how it's suppose to work.... do a structured program. If your a 'Visual' kind of people, you can figure all your program using a kind of flowchart.

rossfree
- 20th February 2005, 11:28
Thanks all,

Sometimes I want to program like I think. It's a bit frightening!

Did you get it?

BIT... Frightening!???

*** he shudders***

I wanted a definite answer on canceling GOSUBs and I think I got it. I can work around my needs in code no problem. Just wanted to know if it could be done.

I could just hear that "POPing" sound Languer. Good sound! :-)

As always, this forum rocks!

Thanks again for the many replys,

Ross

peterdeco1
- 20th February 2005, 11:44
Hi Ross. I think I understand your question. If you gosub, the gosub will cancel if it doesn't reach the end line that says return. For example:

gosub lightled

lightled:
if porta.1 = 0 then turnonmotor 'jump out if motor switch is closed
high portb.1 'light up led on port
return

turnonmotor:
high portb.2 'turn on motor driver transistor
goto motorcontrol 'go to a completely different area in program

your gosub cancelled as soon as it went to turnonmotor and avoided the return line. Hope this helps.

rossfree
- 20th February 2005, 13:22
Hi Peter,

Thanks for your reply.

If you GOSUB in a program, then you must have a RETURN... or you will still be in a GOSUB stack. You can divert the program to go do something else as you have stated... but you are effectively still in the GOSUB.

Sorta like leaving the toilette seat up in a house full of women. It can be done but I wouldn't recommend it.

My original question was "could I put the toilette seat down with a remote control" (so I wouldn't have to walk back to the bathroom).

or maybe it was...

could I GOSUB... then from somewhere else in the program... CANCEL the GOSUB (so I wouldn't have to RETURN to the line following the GOSUB). Diverting to another part of the program is still effectively leaving the GOSUB (toilette seat) open.

Thanks again for your reply...

Ross

...a remotely controlled 'johnny seat'... There's a product there somewhere. Probably need a safety switch... or... NOT. **evil laugh**

hmr
- 21st February 2005, 18:15
Hi All,

I was sniffing the net and I have found a quite interesting stack subroutine that the authors claims to let PBP do up to 48 nested gosubs.

The url is:

http://www.pbpgroup.com/modules/wfsection/article.php?articleid=14

I haven't tested so I can't say if it really works or not but if it does , it's quite an improvement to write more structured programs.

Hope it can help.

Hans