Essence of PIC Arithmetic

In the CSCI 255 labs we are going to base our assembly language programming exercises on the PIC12C671 microcontroller. There are four reasons for this:

  1. The PIC computers are extremely popular in embedded systems applications. You probably already own a few of them. You just don't know here.
  2. The PIC12C671 instruction set is really quite simple. It only has 35 instructions.
  3. The PIC12C671 has 128 bytes of RAM and that should be enough for our simple 255 exercises.
  4. The PIC IDE (Integrated Development Environment) has a pretty nifty simulator.

If you want to know every thing about the PIC12C671 processor, connect to the Microchip web site and download the 111-page PIC12C671 reference manual. We're only going to do point out all the wards in these CSCI 255 pages.

Program memory

The PIC12C671 can store 1024 14-bit machine instructions. That's about 2.25 kbytes. You'll only use a small fraction of that in these labs.

Data memory

There are 128 bytes of RAM, which the Microchip folks usually call file registers. Tricky programming in required to access all 128 registers. In CSCI 255 we will be content to use 96 of these: file registers 20h (32) to 7Fh (127).

There is also a W register which is used in many arithmetic operations. For example, if you want to add file registers 33h and 34h and store the result in file register 37h, you must

MOVE 33h,W
Move the contents of register 33h to the W register.
Add the contents of register 34h to the W register.
Move the contents of the W register to register 37h.

Finally, there are 16 special file registers. We'll introduce these only when absolutely necessary.

Arithmetic and logical instructions

We're going to divide the "pure" arithmetic and logical instructions into three categories, according to where they store their results:

  1. The result is always stored in the W register.
  2. The result is always stored in a file register.
  3. The result may be stored in either a file register or a W register.

In the next three sections, you'll see the "variables" k, f, d, and b.

k is an eight-bit constant (konstant) or literal. The possible values of k range from 0 to 255.
f is a file register.
d is a destination. There are only two possible values for d: W or F. If d is W, the result of the instruction is stored in the W register. If d is F, the result is store in a file register.
b is a bit index. It points to a particular bit within a byte. Its range is 0 to 7

Destination W

All these instructions, except one, performs an operation on W and a constant and stores the result back in W.

Clears W to 0.
Moves k into W.
Adds k and W.
Subtracts W from k.
Ands k and W.
Inclusive ors k and W.
Exclusive ors k and W.

Destination file register

These instructions modify file register f.

Clears f to 0.
Moves the contents of W to f.
BCF f,b
Clears bit b of f to 0.
BSF f,b
Sets bit b of f to 1.

Destination W or file register

All of these instructions perform an operation on a file register f or on f and W. The last "parameter" of the instruction is either F or W. This determines if the result of the operation is to be stored back into f or into W.

INCF f,d
Increment (add 1 to) f.
DECF f,d
Decrement (subtract 1 from) f.
COMF f,d
Complement (not) the bits of f.
Swap the nibbles, left and right half-bytes, of f.
MOVF f,d
Move (copy) f. There really is a reason why you'd want to copy f back to itself.
RLF f,d
Rotate f left one bit. This rotation also uses and modifies the carry bit. We'll have more on that later.
RRF f,d
Rotate f right one bit. Again, the carry bit is involved.
Add f and W.
Subtract W from W.
And f and W.
Inclusive or f and W.
Exclusive or f and W.

Control instructions

Normally, the PIC processor executes one instruction and then proceeds to next. However, sometimes we need a change.


The goto is the simplest way to modify the flow of control. The single argument of the goto is a label, the address of another instruction. Here's an infinite loop. Try to figure out what it does.

loop    addwf   20h,F
    addlw   2
    goto    loop

By the way, when the PIC12C671 processor is reset, it always begins execute the instruction a location (origin) 0. Because instruction 4 has a special use, you should make sure the instruction at location 0 has a GOTO to the instruction at location 5.

    org 0h
reset   goto    start
    org 5h
start           ; this is where execution begins


Of course, what we really need is a bit more control of where we go. We need a conditional instruction that goes according to the result of a test. In the PIC processor conditional execution is accomplished with skip instructions. For example, the instruction

will decrement register 35h and skip the next instruction if the result is zero.

It takes a bit of practice to master the skip. Here's a little piece of C code that adds the numbers from 25 down to 1 together.

tot = 0 ;
for (i=25; i != 0; --i)
  tot = tot + i ;

Now, let's try that in the PIC assembly language.

    I   EQU 30h ; define I to be file register 30h
    TOT EQU 31h ; define TOT to be register 31h

    CLRF    TOT     ; TOT = 0
    MOVLW   25      ; W = 25
    MOVWF   I       ; I = W = 25

FORL:   MOVF    I,W     ; W = I
    ADDF    TOT,W       ; TOT = TOT + W = TOT + I
    DECFZ   I       ; I = I - 1
    GOTO    FORL        ; skip if I is 0

FORE:   ....            ; out of the loop

In all there are four PIC instructions that can skip. One increments, another decrements, and the other two checks single bits of a byte. Here they are:

Increment f. Skip the next instruction if f is 0.
Decrement f. Skip, if f is 0.
Skip the next instruction if bit b of f is 0.
Skip the next instruction if bit b of f is 1.

You may wonder how you could do a test like

with just these four skips. Be patient. There's more to come.

Coming attractions

Return to Lab 1.