A key part of any program is the ability to change the flow of execution in response to events or state changes. This is called branching and the PIC12F508 has a number of instructions to support this.
The first is the simple goto. Just like the infamous goto in a high level language this simply redirects execution to another place in the code:
// Program will jump to the instruction at // address 10 in the program memory. goto 10
Note that the simulator allows us to assign labels to specific program memory addresses to make our code easier to read. You can do this by clicking in the left column of the Program Memory Window and entering a unique name.
By itself the goto instruction is not very useful, and what we really want are instructions that allow us to branch as a result of a test condition. The simplest of these is the decfsz instruction. This decrements a data memory location and skips the instruction that immediately follows it if the result of the decrement is zero. We can use it to form a simple loop counter:
// Initialise loop counter (my_var) with number // of iterations. movlw 3 movwf my_var // Our loop :loop decfsz my_var, f goto loop // Execution doesn't get here until // my_var is zero.
For more generic test conditions there are the btfss and btfsc instructions. These test the value of a specific bit (see Lesson 10) and skip the next instruction if the bit is set or cleared respectively. We normally use these to test the STATUS flags or to start an operation based on the state of an input pin:
// Test C flag in the STATUS register btfss STATUS, C goto do_something_if_clear // Skipped if flag is set goto do_something_if_set
When combined with the Z and C flags from the STATUS register, these quite simple instructions can be used to implement all the conditional expressions you would find in a high level language.