PDA

View Full Version : GOTO vs RETURN after a GOSUB



rsocor01
- 18th April 2018, 01:48
Hi, I have the following code,



MainLoop:

'DO SOME STUFF HERE.....

FOR J = 0 TO 7
GOSUB SearchForClockSignal
NEXT J

goto MainLoop

SearchForClockSignal:

USBSERVICE
SERIN2 PORTE.3, 32, 3, CLOCKSEARCHFAILED, [wait(252), STR RFID_IN\6]
USBSERVICE

IF RFID_IN[0] = 252 THEN GOTO MAINLOOP

SquaresArray[0] = 255
SquaresArray[1] = 202
SquaresArray[2] = RFID_IN[0]
SquaresArray[3] = RFID_IN[1]
SquaresArray[4] = RFID_IN[2]
SquaresArray[5] = RFID_IN[3]
SquaresArray[6] = RFID_IN[4]
SquaresArray[7] = RFID_IN[5]

if PPB_DeviceState = 32 then 'ONLY WHEN THERE IS A USB CONNECTION PRESENT
GOSUB SendUSBData
endif

GOTO MAINLOOP 'CLOCK SERIAL COMMUNICATION WAS RECEIVED

CLOCKSEARCHFAILED:

RETURN


The program above will run for about 20 seconds and then it will stop working. Now, if I replaced the code in red "GOTO MAINLOOP" above by RETURN, then the code works just fine. Now, I understand that every GOSUB waits for a RETURN, but since I had the option "STACK OVERFLAW" disabled I thought that I could get away with it. Can somebody explains to me what is going on with this issue?

Thanks,

Robert

pedja089
- 18th April 2018, 10:57
Better question is why you would use GOSUB without RETURN? That just doesn't have any sense.
If stack is full then PBP can't call internal subroutines, and it crash...
You just disabled reset on overflow. That fuse doesn't expand stack to infinity and beyond.

Better solution to get same result



MainLoop:
GOSUB SearchForClockSignal
goto MainLoop

SearchForClockSignal:
FOR J = 0 TO 7
USBSERVICE
SERIN2 PORTE.3, 32, 3, CLOCKSEARCHFAILED, [wait(252), STR RFID_IN\6]
USBSERVICE

IF RFID_IN[0] = 252 THEN RETURN 'GOTO MAINLOOP

SquaresArray[0] = 255
SquaresArray[1] = 202
SquaresArray[2] = RFID_IN[0]
SquaresArray[3] = RFID_IN[1]
SquaresArray[4] = RFID_IN[2]
SquaresArray[5] = RFID_IN[3]
SquaresArray[6] = RFID_IN[4]
SquaresArray[7] = RFID_IN[5]

if PPB_DeviceState = 32 then 'ONLY WHEN THERE IS A USB CONNECTION PRESENT
GOSUB SendUSBData
endif

RETURN 'CLOCK SERIAL COMMUNICATION WAS RECEIVED

CLOCKSEARCHFAILED:
NEXT J
RETURN

Dave
- 18th April 2018, 14:20
It's probably overflowing the stack and halting.

sayzer
- 19th April 2018, 05:38
This should work.



MainLoop:

'DO SOME STUFF HERE.....

FOR J = 0 TO 7
GOTO SearchForClockSignal
NEXT J

goto MainLoop

rsocor01
- 19th April 2018, 06:09
Better question is why you would use GOSUB without RETURN?

Yes, I'm asking myself the same question :D. Yes, your code looks better than mine. The program is probably overflowing the stack and halting like Dave said. Will the program restart from the beginning if the stack overflow is enabled?

Dave
- 19th April 2018, 14:47
Yes it should create an internal reset condition.

pedja089
- 19th April 2018, 14:47
Yes. It have almost same effect as MCLR pulled low, then high. Only 2 bits are different, if I remember correctly.

rsocor01
- 20th April 2018, 07:20
Thank you guys.

Robert

Art
- 25th April 2018, 16:16
If you want to be a cowboy for some reason you could have used GOTO instead of GOSUB.
Then you could GOTO back as well (instead of RETURN).

The difference between GOTO and GOSUB is that GOSUB loads the stack with the location it was called from so that a RETURN can go back there, but GOTO doesn’t need to do that.

BUT! using a GOTO to go somewhere, and another GOTO to go back, just means that neither GOTO had to exist, and you could have just dropped the routine right in where the GOTO was.

Ioannis
- 25th April 2018, 21:24
Also, using GOSUB reduces code size as this Sub can be called from various points of the program to do the same job, maybe with some parameters passing to it.

Keeps things structured.

Ioannis