PIC18: branch instructions

binary codeSkimming through the PIC 18F4550 istruction set we can see, among others, a bunch of branch instructions.

What are they for and what's their relationship with the STATUS register? Let's see them in practice using some assembly code examples. This will also be a nice occasion to do a bit of simple HEX math.

Branch instructions

BC - Branch if Carry

BN - Branch if Negative

BNC - Branch if Not Carry

BNN - Branch if Not Negative

BNOV - Branch if Not Overflow

BNZ - Branch if Not Zero

BOV - Branch if Overflow

BRA - Branch Unconditionally

BZ - Branch if Zero

Those instructions make the program counter (PC) jump to another part in the program code on the evaluation of the STATUS register (that's not true for the BRA instruction which branches unconditionally).

So it's important to understand the various flags of this register and how they are affected by the execution of other instructions; for this purpose we are going to use a great piece of Windows software named PIC18 Simulator IDE, which runs fine under Linux thanks to Wine.

The STATUS register

pic18 status register

Every flag in the STATUS register can be intercepted by the corrispondent branch instruction; let's see this in practice.

This is the first code we are going to assemble and load onto PIC18 Sim:

      processor 18F4550
      INCLUDE <p18f4550.inc>

  testreg equ 0x00

      org 0x00
      goto Start

      org 0x08
      nop

      org 0x18
      nop

  Start
      movlw .1
      movwf testreg 


  ; Main loop
  Main
      movlw .4
      addwf testreg

      bra Main

      END

testreg is defined as a file register located at 0x00 and loaded with .1 Then what the Main loop does is adding the value .4 to it over and over again to see how that's reflected on the STATUS register.

Digit carry bit

The values that testreg goes through are: 1h, 5h, 9h, Dh. Let's stop here and do the next operations by ourselves.

0Dh +
04h =
___
11h

There is a carry for the lower nibble, which is added to the higher nibble; it is called a digit carry and that situation is reflected on bit 1 of the STATUS register:

pic18 simulator ide digit carry

Overflow and negative bits

Let's go on and keep adding .4 to testreg until we come to the value 7Dh and do the math:

7Dh +
04h =
___
81h

Like before we have a digit carry (a carry resulting from the addition of the lower nibbles) ; as for the higher nibble, its most significant bit is on and that corresponds, in 2's complement notation, to a negative number: that turns on bit 4 of the STATUS reg.

That alone doesn't make the number negative; it all depends on the istruction that uses the operand (the register) to interpret it as a signed number or a positive one.

There is also an overflow, a condition which is met when there is a change in the sign, from positive to negative as in this case: bit 3 is therefore also on.

pic18 simulator ide overflow negative

Carry bit

In the next situation testreg is now FDh:

 FDh +
 04h =
____
101h

The result i 101h, but since testreg, as all GPRs, is an 8 bit register the leading '1' is truncated and 01h is instead saved; both the higher and lower nibble had a carry, so bit 0 (carry) is also on:

pic18 simulator ide carry

The Carry bit (but not the Digit Carry) is also affected by register rotate instructions like RLCF (Rotate Left f through Carry) and RRCF (Rotate Right f through Carry):

rrcfrrcf

Start
    movlw .1
    movwf testreg 

; Main loop
Main
    rrcf testreg,F

    bra Main

pic18 simulator rotate carry

Zero bit

This should be simple; for example:

Start
    movlw .255
    movwf testreg 

; Main loop
Main
    incf testreg,F

    bra Main

pic18 simulator zero

We can see that bit 2, the STATUS bit that intercepts operations which lead to a result equal to Zero, is turned on, but also bit 0 (Carry) and bit 1 (Digit Carry). Let's try to explain that:

 FFh +
 01h =
____
100h

When we sum the lower nibbles (Fh + 1h) we have a carry, so Digit Carry bit is on; the carry is then added to the higher nibbles (1h + Fh + 0), which makes the Carry bit on.

Borrow and Digit borrow bits

Carry and Digit Carry bits are affected by additions; but when numbers are subctracted they become Borrow and Digit Borrow bits, which are active low; this means that when there is a borrow the bits are off.

Start
    movlw .1
    movwf testreg 

; Main loop
Main
    decf testreg,F

    bra Main

In the above example the subtraction is:

01h -
01h =
___
00h

First the lower nibbles are subtracted (1h - 1h); there's no borrow so Digit Borrow bit (bit 1) is on; then the higher nibbles are subtracted (0 - 0): no borrow so Borrow bit (bit 0) is on:

pic18 simulator borrow

(Zero bit - bit 2 - is also on)

If we go further with the next subtraction:

00h -
01h =
___
FFh

The lower nibbles are subtracted: there's a need for borrow (Digit Borrow bit off), which is also needed in turn by the higher nibbles (Borrow bit off):

pic18 simulator borrow

(Negative bit - bit 4 - is also on)

With the following subtraction only the Digit Borrow bit is affected and so it is turned off:

F0h -
01h =
___
EFh

pic18 simulator borrow

Add new comment

Filtered HTML

  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <img> <p> <h1> <h2> <h3> <h4> <h5> <div> <pre> <object>
  • You may insert videos with [video:URL]
  • Web page addresses and e-mail addresses turn into links automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.