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.

programming code 'goto $+2'

Status
Not open for further replies.
i still not understand , coz i m newbie for PIC programming code zzzzzzzzzzz. can ericgibbs tell me more ??? tqtq:)

The Program counter keeps track of the current program address value.

Assume your program starts at program count of 0000h, the first instruction machine code is at this address. ]
The next instruction code would reside at 0001h and so on.

The instruction at 0001 address could be for example 'goto skip', this would load the PC program counter with the address of the skip instruction, which could be for example at 0100h.

A shorthand way to write the value of the PCntr into the program, is the $ sign.

Look at this link also Nigels tutorials.
 
Last edited:
The Program counter keeps track of the current program address value.

Assume your program starts at program count of 0000h, the first instruction machine code is at this address. ]
The next instruction code would reside at 0001h and so on.

The instruction at 0001 address could be for example 'goto skip', this would load the PC program counter with the address of the skip instruction, which could be for example at 0100h.

A shorthand way to write the value of the PCntr into the program, is the $ sign.

Look at this link also Nigels tutorials.

erm. now i m more understand . you mean PIC will go back the previous instruction . right ? how about this example can you tell me where the PIC will read after the 'goto $+2'

;Tutorial 1.2 - Nigel Goodwin 2002
LIST p=16F628 ;tell assembler what chip we are using
include "P16F628.inc" ;include the defaults for the chip
__config 0x3D18 ;sets the configuration settings (oscillator type etc.)

cblock 0x20 ;start of general purpose registers
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
endc

org 0x0000 ;org sets the origin, 0x0000 for the 16F628,
;this is where the program starts running
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)

bsf STATUS, RP0 ;select bank 1
movlw b'00000000' ;set PortB all outputs
movwf TRISB
movwf TRISA ;set PortA all outputs
bcf STATUS, RP0 ;select bank 0

Loop
movlw 0xff
movwf PORTA ;set all bits on
movwf PORTB
nop ;the nop's make up the time taken by the goto
nop ;giving a square wave output
call Delay ;this waits for a while!
movlw 0x00
movwf PORTA
movwf PORTB ;set all bits off
call Delay
goto Loop ;go back and do it again

Delay movlw d'250' ;delay 250 ms (4 MHz clock)
movwf count1
d1 movlw 0xC7
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0

decfsz count1 ,f
goto d1
retlw 0x00

end
 
Now i understand , thank eric and Nigel. Nigel P16PRO40 hardware suitable for burning program code into 16F877A PIC ??:confused:

I have never used the P16PRO40, I expect it would program the 16F877A , perhaps Nigel will confirm.:)

When you compile your assembler program using MPLAB IDE in addition to the hex file it also creates a 'lst' file.
Use your editor to display this file and you will see the Program Counter number along side the code, it will help you understand the $+2 and other parts of your code.
 
Last edited:
I have never used the P16PRO40, I expect it would program the 16F877A , perhaps Nigel will confirm.:)

Well it's not my hardware, but it will program almost any serial programmed PIC - depending on the software you use. The 16F877A is a common device, and is supported by almost anything.
 
Personally, I hate the use of goto $+x. It is just lazy programming.

The above code makes total sense when it's written,
Code:
Delay		movlw	d'250'		;delay 250 ms (4 MHz clock)
		movwf	count1
d1		movlw	0xC7
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	[COLOR="Red"]Delay_1[/COLOR]
		decfsz	countb, f
[COLOR="red"]Delay_1[/COLOR]		goto	Delay_0

		decfsz	count1 ,f
		goto	d1
		retlw	0x00

The use of goto $+n has no use in code that wasn't written 10 years ago.

Mike.
 
Personally, I hate the use of goto $+x. It is just lazy programming.

The above code makes total sense when it's written,
Code:
Delay		movlw	d'250'		;delay 250 ms (4 MHz clock)
		movwf	count1
d1		movlw	0xC7
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	[COLOR="Red"]Delay_1[/COLOR]
		decfsz	countb, f
[COLOR="red"]Delay_1[/COLOR]		goto	Delay_0

		decfsz	count1 ,f
		goto	d1
		retlw	0x00

The use of goto $+n has no use in code that wasn't written 10 years ago.

Mike.

The code above, as I'm sure you're fully aware, is generated by the PICList delay code generator, it makes obvious sense to avaoid the use of unrequired labels, so it can't clash with any existing labels when you cut and paste it. Notice they are only used for very short jumps, where it's no bother.
 
The former Apple II series ( from the early 1980s) solved this issue by calculating onscreen the branch address after the mnemonic. I wrote two Apple programs to track my music and magazine collections, and it was a test in patience getting the subroutines to work properly. Both programs take less than 3K RAM, the files are longer than that.
 
The code above, as I'm sure you're fully aware, is generated by the PICList delay code generator, it makes obvious sense to avaoid the use of unrequired labels, so it can't clash with any existing labels when you cut and paste it. Notice they are only used for very short jumps, where it's no bother.

The PicList delay generator may well qualify as more than 10 years old and so may be exempt. However, the original programmers managed to generate many labels (di, delay_0, count1, counta, countb) and then just got lazy and fell back on the goto $+n syntax. There is no reason to use the goto $+n syntax, all it does is confuse newbies and should be frowned upon.

Maybe I'll write a modern equivalent but then I'll be accused of plagiarism.

Mike.
 
goto $+2 or goto $-2

Surely as the assembler is reading through the mnumonics on each line, the program counter will be counting up. So to goto the line above would need the address of the program counter with a few knocked off, rather than added on... ? Help ?
 
Personally, I hate the use of goto $+x. It is just lazy programming.

The use of goto $+n has no use in code that wasn't written 10 years ago.

Totally agree. It takes, what, two seconds to type in a label and use it as the jump target?

By the way, apparently you cannot use tags inside
Code:
-tagged text.
 
goto $+2 or goto $-2

Surely as the assembler is reading through the mnumonics on each line, the program counter will be counting up. So to goto the line above would need the address of the program counter with a few knocked off, rather than added on... ? Help ?

Yes, the program counter counts up with each instruction. For the currently-executing instruction, "$" means "the PC at the time this instruction is executing". So $-n means "go to the location given by the current value of PC - n", which could be the previous instruction or one even farther back. $+n would jump forward in the code.

You see also that another problem with this is that you have to know the length of the instructions you're skipping back to, at least on processors that don't have identical-sized instructions (i.e., most of them).
 
Last edited:
I used that potentially confusing way only in few canned routines (macros) which I am sure I will never change. Example follows. Take it as is.

Code:
SKIP_WORD_HIG_V MACRO WORD_H,WORD_L,VAL
    MOVLW HIGH VAL    ;W =VAL_H - substracts value from
    SUBWF WORD_H,W  ;WORD_H (but not changing it)
 
    BTFSS STATUS,C    ;if C =1, WORD_H =>VAL_H     
    BRA $+16               ;C =0, W_H <V, go to the line!
 
    BTFSS STATUS,Z    ;if Z=1 WORD_H =VAL_H, check WORD_L
    BRA $+14               ;Z =0, WORD_H>VAL_H; skip the line!
 
    MOVLW LOW VAL     ;W =VAL_L - substracts value from
    SUBWF WORD_L,W   ;WORD_L (but not changing it)
 
    BTFSS STATUS,C     ;if C =1, WORD_L=>VAL_L - Check Z
    BRA $+4                 ;C =0, W<V - go to the line!
 
    BTFSC STATUS,Z     ;if Z =0, WORD_L>VAL_L; skip line!
    ENDM

I ran across this use when learning about my first micro, the Z80.
 
Why not?

Maybe I'll write a modern equivalent but then I'll be accused of plagiarism.

As long as you warn that you were bringing something up to date, who could?

Mancini's bible of opamps (TI) was upadted by two colleagues and it was good and welcome.
 
Well, three years on from that post, maybe I should write a modern equivalent. Or, maybe I should wait until this thread resurfaces in another 3 years. It's scary how time just drifts by.

Mike.
 
I have a couple of home-made ASM defines I use for that type of local branching;
Code:
#define    SKIP1   goto $+2
#define    SKIP2   goto $+3
#define    BACK1  goto $-1
#define    BACK2  goto $-2

They can be very handy for local loops like this;
Code:
btfss PORTB,3
BACK1
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top