Subroutines on the PIC

Getting Ready

Once again, you must make sure that MPLAB is installed on your computer. Go back to CSCI 255 Lab 1 to make sure this is done.

This time you'll start by downloading a ZIPed file with a couple of projects. The ZIPed file should install a directory called lab03. The names of the projects within the directory are:

All the PIC

Open up the project call picall.pjt. This project contains an assembler program picall.asm that uses almost all the instructions of the PIC12C671. It also has a watch window stored in picall.wat that displays the contents of a file register named freg.

Once you open up the project, arrange its windows so that you have good view of the assembler source, the special function registers, and the watch window:
picall project
In addition to the freg file registers, there are four special function registers that you should follow during this exercise:

w
The accumulator
pcl
The lower byte of the program counter
status
The program status register
fsr
The file register index

If you look at the assembler code, you'll also notice several uses of an additional register INDF, the indirect file register. This special register is similar to a C++ pointer variable. When you read or write INDF, you really read or write the register whose address is stored in FSR. Here's some very sneaky code to store the value 75 into register freg.

        movlw   freg    ; load W with "address" of freg
        movwf   FSR     ; move address of freg into FSR
        movlw   D'75'   ; load 75 into W
        movwf   INDF    ; store W to freg via indirection

Do not proceed until you completely understand these four lines of code. Frequent use of FSR and INDF will be made in the second project of this lab. In fact, it might be a good time to review all special file registers by looking at our handout on Special registers in the PIC.

The checkoff

Your job is to compile the program and then slowly step through it (with F7). You should do this very carefully, instruction-by-instruction. You may want to do this part of the lab with a partner, so you'll have two sets of eyes to follow the action.

Use the source: Pay attention to the comments in the code. They will show you which registers will change.

When you are done, inform the lab instructor of your enlightenment.

Call the PIC

If you haven't read our handout Subroutines on the PIC, this would be the time to do so.

Close project picall.pjt and open up project picmult.pjt. The project has assembler code picmult.asm and a watch window. Try to arrange your MPLAB windows to show the code and watch window:
picmult project

The subroutines

This program contains two PIC subroutines. One is Add32. Add32 is passed three arguments in registers pX (70h), pY (71h), and pZ (72h). These arguments are really pointers to 32-bit integers. For example, in our code we'll call Add32 with pX containing the value 20h. This means than the 32-bit integer argument is really stored in the four registers 20h, 21h, 22h, and 23h.

Take a look at the code. Note that six file registers, 79h to 7Fh, are reserved for the temporary, or local, variables of Add32. The heavy work is done within the loop starting at Add32. Here the 32-bit arguments are added one byte at a time. The local variable tCarry tracks the carry from byte to byte. The special function registers FSR and INDF are used to simulate C++-style pointers.

The second subroutine is Mul32. This routine has three arguments, also passed as pointers. The first two are 32-bit integers to be multiplied. The third is a 64-bit integer to hold the result. The multiplication algorithm is the one presented in class on 2 February and illustrated, in 8-bits, with an Excel spreadsheet.

Mul32 has several loops. The one starting with MlLp1 copies the four-byte multiplier into the lower four bytes of the result buffer. The MlLp2 loop clears out the upper four bytes. The main loop MlLp3 is executed 32 times. It tests the final bit of the result buffer and, should that final bit be set, calls Add32 to add in the multiplicand. Its inner loop, MlLp4, is then used to shift over the result buffer one bit position.

Looking at the show

After you've mastered the source, animate the multiplication with

The code will start to square numbers starting with 1,000,000,001. Notice how the algorithm shifts the number through the eight-byte result field 32 times. Show your lab instructor the movie.

Your task

The main program has a loop that calls Add32 to add one to Count. Write a PIC routine called PlusPlus32 that takes a single 32-bit operator, passed as a pointer in register pX and adds one to it. Replace the code

loop    movlw   Count
        movwf   pX
        movwf   pZ
        movlw   One
        movwf   pY
        call    Add32

with

loop    movlw   Count
        movwf   pX
        call    PlusPlus32

to call your routine.

A even bigger task

If you find PlusPlus32 trivial, try another problem.

There is a definite overhead in having Add32 and Mult32 receive their arguments in pointers. Rewrite Mult32 so that it expects its arguments at fixed register locations. The multiplier can be passed in 60h to 63h; and the multiplicand, in 64h to 67h. The result can be stored in 68h to 6Fh. Run the modified program and try to determine how much faster it is.


Return to CSCI 255 home page