Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Label vs Sub routine

Status
Not open for further replies.

patricktran

New Member
I think a label is better than a subroutine. The reason is returnning from a lable, we can GOTO anywhere we like!! 8) But with subroutine, we must return to where we called it before.
We can even "pretend" a label as a subroutine as follow:

Loop
decfsz d1
goto DoSomeThing
Back goto Loop


DoSomeThing
blah blah blah
goto Back


---------------------
It is the same with subroutine:
Loop
decfsz d1
call DoSomeThing
goto Loop


DoSomeThing
blah blah blah
return
----------------------
Please correct me if I am wrong.
Thanks
Pat
 
What you say is true but the point of a subroutine is you can use it in two different places. This lets you write code once for a repetative action and then just call the subroutine. For example: if you want to display the temperature of two different things you can just call the display routine twice instead of using two different sections of code.

Brent
 
The goto command should only ever be used as a very last resort, in fact there are people out there who would say that if you need to use a goto, then you are doing it wrong. Many modern languages just dont let you use the goto command at all since it is considered such bad programming practice
 
weegee said:
The goto command should only ever be used as a very last resort, in fact there are people out there who would say that if you need to use a goto, then you are doing it wrong. Many modern languages just dont let you use the goto command at all since it is considered such bad programming practice

But this doesn't apply to assembler, and certainly not to a RISC processor like the PIC. Goto is used extensively in PIC assembler, and for that matter is used extensively in the assembler code produced by high level compilers (for any processor) which discourage it's use at a high level.

A while back I was converting a large VB program to Delphi, and due to the existing program structure I was unable to illiminate all the goto's - I had to resort to the Delphi help file to find out how to do goto's in Delphi!. In many years of Pascal/Delphi programming I'd never used a goto!.

But Pascal (which is what Delphi is) is a highly structured language, which is why it was the training language of choice at universities - it encourages good programming practice, and the modern 'hate' of goto's stems from Pascal.
 
i have to agree nigel, your probably right, im still getting my head round low level/assembly code. I was just trying to make the point that you should see if there are other ways around problems other than gotos but I suppose that with the stack on the PICs being quite small, that an occasional goto would be a nessesary evil just to avoid running out of stack space.

Therefore I bow before your superior knowledge on such matters :?
 
The fact that using GOTO then GOTO or CALL then RETURN is the same. However, CALL will put the next line to TOS, and you only have 8 Mmories stacks. So if you use GOTO, you don't have to take care of how many subroutine you are using.

However, A subroutine can be call by many other routines, but GOTO cannot. This is an example:


Code:
main
      do something here
      CALL   hello (print hello to LCD for example)
      then do something next
      CALL   hello (print again)
      do something then end
end.


hello
      print "hello" to LCD for example
return

So, if you use GOTO, you have to copy and paste like this

main
do something here
GOTO hello1 (print hello to LCD)
label1 then do something next
GOTO hello2
label2 do something then end
end

hello1
print hello to LCD
GOTO label1

hello2
print hello to LCD
GOTO label2

That is the difference.

Goodluck
 
weegee said:
i have to agree nigel, your probably right, im still getting my head round low level/assembly code. I was just trying to make the point that you should see if there are other ways around problems other than gotos but I suppose that with the stack on the PICs being quite small, that an occasional goto would be a nessesary evil just to avoid running out of stack space.

It's not just occasional, 'goto' is an extremely common instruction in PIC assembler - it's only high level languages that have a problem with it. But even your nice modern C or C++ compiler probably generates loads of goto's in the assembler code on Intel processors, and certainly on PIC's. You can't use a PIC with out using 'goto' a great deal, here's a small example (taken from one of my tutorials).

Code:
Chk_Code   movf   code1, w      ;test first digit 
      subwf   key1, w 
      btfss   STATUS, Z 
      goto   Wrong 
      movf   code2, w      ;test second digit 
      subwf   key2, w 
      btfss   STATUS, Z 
      goto   Wrong 
      movf   code3, w      ;test third digit 
      subwf   key3, w 
      btfss   STATUS, Z 
      goto   Wrong 
      movf   code4, w      ;test fourth digit 
      subwf   key4, w 
      btfss   STATUS, Z 
      goto   Wrong 
      goto   Correct

It checks an entered 4 digit code against the stored code, for a keypad lock. Five 'goto' lines out of a total of 17 lines!, the 'btfss' bit test instructions are commonly followed by 'goto'.
 
Thanks guys :lol: I reckon goto is good in the context that we can easily return back where ever we want!!!! 8)
and subroutine is good in reusing the code, avoiding repeating code.
 
patricktran said:
Thanks guys :lol: I reckon goto is good in the context that we can easily return back where ever we want!!!! 8)
and subroutine is good in reusing the code, avoiding repeating code.

Yes, they essentially perform different tasks.

It's fairly good practice to try and write your programs as modular subroutines, so your main program loop ends up as mainly a collection of subroutine calls - something like this:

Code:
Start
       call Initialise
Loop
       call ReadKeys
       call Convert_To_Decimal
       call Display
       call RS232_Out
       goto Loop

In this way you can test each section individually, and it makes it easy to reuse the subroutines in other programs. Often, in between the calls, you would move data between registers as well.
 
thanks, falleafd. I am having exactly that problem!!! 8) As I wanted to use subroutine! Not good at all after bit test! GOTO is the best for this sittuation!!! :p
 
Why wouldn't you be able to use a subroutine after a bit test ?

Code:
     BTFSC    A_File, A_Bit
     CALL     DoSomeThing
     INCF     A_File, F

would simply test a_bit in a_file and, if the bit was set call the subroutine, and afther it completed come back and increase A_File with 1.
If the bit would be clear then if would skip the call to thez subroutine and directly increase a_file.
 
Exo said:
Why wouldn't you be able to use a subroutine after a bit test ?

Code:
     BTFSC    A_File, A_Bit
     CALL     DoSomeThing
     INCF     A_File, F

would simply test a_bit in a_file and, if the bit was set call the subroutine, and afther it completed come back and increase A_File with 1.
If the bit would be clear then if would skip the call to thez subroutine and directly increase a_file.

You can (and I do!), it's perfectly fine - it's simply a different process.

Using 'call' in this way is equivilent to 'If Then', using 'goto' is equivilent to 'If Then Else'.
 
A specific turn on and off an LED

Code:
     BTFSS    A_File, A_Bit 
     CALL     Turn_On_LED 
     CALL     Turn_Off_LED


Code:
TEST
     BTFSS    A_File, A_Bit 
     GOTO    Turn_On_LED 
     GOTO    Turn_Off_LED

Turn_On_LED
     Do_st
     GOTO TEST

Turn_Off_LED
     Do_st_else
     GOTO TEST
The first implementation of Calls is wrong. I guess in this case, I can not use call!!!
 
Hi, a thing that I wonder if it is true or not. in ISR, we should not have a GOTO
The reason I think so is in ISR, the GOTO can take us to somewhere, and will return us to somewhere else, not in the ISR. So it takes for quite long time to return back the ISR and finally, the retfie is executed.
The better method is using CALL of a sub routine, as we are sure after the routine is done, we come back the ISR.
We should not keep the CONTEXT in the stack (ISR causes a context saving!)...
Thats only my personal idea, please correct me though.
Thanks :wink:
 
It doesn't really make any difference, as long as you keep track of where you are and exit the interrupt correctly. I almost always start an interrupt routine with a 'goto' (as do most people) - the interrupt vector is at 0x004, I would normally have a 'goto Int_Routine' there, with the routine itself stored higher up. As long as the interrupt routine saves any altered registers, and restores them as it exits everything should be fine.

However, it's probably NOT a good idea to use subroutine calls from an interrupt, simply because the PIC has a very small stack - if the interrupt is called when you are already in a nested subroutine calling another one could easily overflow the stack - DISASTER!!. Something to be very aware of if using subroutines!.
 
Indeed, You can jump around all you want inside an ISR (using GOTO), as long as you do not jump out of the ISR...

And never jump to a place where the isr will return without context restoring.

As for the stack problem nigel pointed out. It all depends on how deep the main program can be nested. If you keep track of the calling tree and write your program in such a way that the main will never be nested deeper then 6 levels, then you can go 1 level deep inside your ISR.
(8 level stack)
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top