Opcode (Hex) | Instruction | Parameters | Meaning |
---|---|---|---|
0000 | NOP | No operation | |
018f | CLRF | f | Clear f |
0100 | CLRW | Clear W | |
30vv | MOVLW | v | Move Literal to W |
008f | MOVWF | f | Move W to f |
08ff | MOVF | f,d | Move f |
3Evv | ADDLW | v | Add literal to W |
3Cvv | SUBLW | v | Subtract W from literal |
39vv | ANDLW | v | AND literal and W |
38vv | IORLW | v | Incl. OR literal and W |
3Avv | XORLW | v | Exclusive OR literal and W |
07ff | ADDWF | f,d | Add W and f |
02ff | SUBWF | f,d | Subtract W from f |
05ff | ANDWF | f,d | AND W and f |
04ff | IORWF | f,d | Inclusive OR W and f |
06ff | XORWF | f,d | Exclusive OR W and f |
0Eff | SWAPF | f,d | Swap halves f |
09ff | COMF | f,d | Complement f |
2kkk | CALL | k | Call subroutine |
2kkk | GOTO | k | Goto address (k is nine bits) |
0008 | RETURN | Return from subroutine | |
0009 | RETFIE | Return from Interrupt | |
34vv | RETLW | v | Return with literal in W |
0062 | OPTION | Load OPTION register | |
006f | TRIS | f | Tristate port f |
03ff | DECF | f,d | Decrement f |
0Bff | DECFSZ | f,d | Decrement f, skip if zero |
0Aff | INCF | f,d | Increment f |
0Fff | INCFSZ | f,d | Increment f, skip if zero |
0Dff | RLF | f,d | Rotate left f |
0Cff | RRF | f,d | Rotate right f |
1bff | BCF | f,b | Bit clear f |
1bff | BSF | f,b | Bit set f |
1bff | BTFSC | f,b | Bit test, skip if clear |
1bff | BTFSS | f,b | Bit test, skip if set |
0063 | SLEEP | Processor Sleep | |
0064 | CLRWDT | Clear Watchdog timer |
Key:
These are the core instructions for the PIC16X84 family. In addition to these core instructions, the standard Microchip assembler supports a number of 'Special' instructions which are short forms of those above. Some special instructions encode to a specific single opcode. Others may encode to two separate processor instructions. The special instructions are listed below:
Instruction | Parameters | Meaning | Equivalent |
---|---|---|---|
ADDCF | f,d | Add Carry to Register | BTFSC 3,0 INCF f,d |
ADDDCF | f,d | Add Digit Carry to Register | BTFSC f,d INCF 3,1 |
B | k | Branch | GOTO k |
BC | k | Branch on Carry | BTFSC 3,0 GOTO k |
BDC | k | Branch on Digit Carry | BTFSC 3,1 GOTO k |
BNC | k | Branch on No Carry | BTFSS 3,0 GOTO k |
BNDC | k | Branch on No Digit Carry | BTFSS 3,1 GOTO k |
BNZ | k | Branch on No Zero | BTFSS 3,2 GOTO k |
BZ | k | Branch on Zero | BTFSC 3,2 GOTO k |
CLRC | Clear Carry | BCF 3,0 | |
CLRDC | Clear Digit Carry | BCF 3,1 | |
CLRZ | Clear Zero | BCF 3,2 | |
MOVFW | f | Move Register to W | MOVF f,0 |
NEGF | f,d | Negate Register | COMF f,1 INCF f,d |
SETC | Set Carry | BSF 3,0 | |
SETDC | Set Digit Carry | BSF 3,1 | |
SETZ | Set Zero | BSF 3,2 | |
SKPC | Skip on Carry | BTFSS 3,0 | |
SKPDC | Skip on Digit Carry | BTFSS 3,1 | |
SKPNC | Skip on No Carry | BTFSC 3,0 | |
SKPNDC | Skip on No Digit Carry | BTFSC 3,1 | |
SKPNZ | Skip on Non Zero | BTFSC 3,2 | |
SKPZ | Skip on Zero | BTFSS 3,2 | |
SUBCF | f,d | Subtract Carry from Register | BTFSC 3,0 DECF f,d |
SUBDCF | f,d | Subtract Digit Carry from Register | BTFSC 3,1 DECF f,d |
TSTF | f | Test Register | MOVF f,1 |
The assembler recognises literals in the following formats:
So 0x30E is equivalent to B'1100001110' or D'782'. The default base (radix) for numbers is base 16, so a number 1234 in the listing is hex 1234, or 4660 decimal. However, the LIST command (explained later) allows the default base to be changed to decimal or octal.
Comments in the listing start with the semi-colon ';' character and continue to the end of the line. Comments may contain any combination of characters and are ignored by the assembler.
For example:
; This is my comment, It was written on 16th Jan 2001
A Label is a text string that has an associated numeric value. A label is any sequence of characters, starting with a letter (A..Z,a..z) and including letters, numbers and underscore characters. Valid labels are 'myLabel', 'an_address', 'label234'. Invalid labels are '3again' (starts with a number) or 'as-were' (minus symbol is not valid in a label). Labels are not case-sensitive, so 'Hello' and 'hELLO' are treated as the same. Instructions, special instructions and assembler commands are reserved and cannot be used as labels.
Numeric labels are created with either the SET, EQU or '=' commands. For example
Labels created with the EQU command are constants, and cannot be altered. Labels
created with SET or '=' are variables, and can be assigned new values at any
point after they have been initialised.
label EQU 45
temp SET 3
temp1 = 2
Address labels must start at the beginning of a new line. An address label may optionally be followed by a colon ':' character, which is ignored. The value of the address label will be the address immediately following the last assembled instruction.
Constant and address labels may be forward referenced - that is, they may be used in an instruction before they are given a value. However variable labels may not be used in this way, and forward references cannot be used in conditional assembly or macro commands.
Numeric expressions consist of numeric literals and labels, and the following operators:
* | Multiply | label = 2*4 |
/ | Divide | label = 8/2 |
% | Modulus | label = 8%3 |
+ | Add | label = 1+5 |
- | Subtract | label = 2-2 |
<< | Left shift | label = bits << 4 |
>> | Right shift | label = bits >> 1 |
>= | Greater or equal | IF label >= 0 |
> | Greater | IF label > 1 |
!= | Not equal to | IF label != 4 |
< | Less | IF label < 6 |
<= | Less or equal | IF label <= 3 |
== | Equal to | IF label==2 |
& | Bitwise AND | label = flags & 7 |
| | Bitwise OR | label = flags | 8 |
^ | Bitwise exclusive OR | label = flags ^ 5 |
&& | Logical AND | IF (label == 1) && (flags != 0) |
|| | Logical OR | IF (label > 8) || (label < 2) |
= | Set equal to | label = 0 |
+= | Add to, set equal | label += 2 |
*= | Multiply, set equal | label *= 3 |
/= | Divide, set equal | label /= 2 |
-= | Subtract, set equal | label -= 1 |
%= | Modulus, set equal | label %= 8 |
<<= | Left shift, set equal | label <<= 2 |
>>= | Right shift, set equal | label >>= 1 |
&= | AND, set equal | flags &= 0x7 |
|= | OR, set equal | flags |= 8 |
^= | Exclusive OR, set equal | flags ^= 1 |
++ | Increment | label++ |
-- | Decrement | label-- |
Normal operator precedence is observed and shown in the table above (operators with the highest precedence are at the top of the table). Brackets ('(' and ')') can be used to control evaluation. The Increment (++) and decrement (--) operators must be used on a line of their own.
In addition the following unary operators are supported:
! | Logical Not | IF !(label=3) |
~ | Complement | label = ~label |
- | Negation | label = -label |
Finally the symbol '$' represents the current value of the program counter.
The assembler recognises a number of commands that allow the assembly process to be controlled. These are not assembled into opcodes, but will affect the way in which the file is assembled.
For example: ORG 0x100 ;Assembles from address 256 onwards.
For example: LIST p=PIC16C84,r=hex
The list command by itself turns listing back on.
For example:
countReg EQU 0x34
minValue EQU 20
maxValue EQU 45
range EQU maxValue - minValue
For example:
temp SET 0x34
temp SET 20
temp SET 4*temp
temp = temp -3
ORG 0x2100
DW 0x01, 0x02, 0x03
DW "Hello"
For example:
IF count > 3
movlw count
movwf store
ELSE
nop
nop
ENDIF
For example:
#DEFINE nothing 0,f
addwf nothing
The LOCAL command in a macro makes the given label(s) act as unique to that macro, so that the same label may appear many times in the expanded code. The Macro definition ends with the ENDM command.
This is an example of a simple macro that provides a delay:
delay MACRO
LOCAL loop
movwf delaycnt
loop decfsz delaycnt
goto loop
ENDM
This code declares a macro 'delay' which stores the value of the W register in delaycnt, then loops that many times, introducing a short delay. The delay macro can then be used as follows:
movlw 0x09 ; Loop nine times
delay
When this is assembled it will be expanded to look like the following code:
movlw 0x09 ; Loop nine times
movwf delaycnt
loop decfsz delaycnt
goto loop
Macros may take parameters, which are any unique labels. When the macro is expanded, any reference to the parameter labels is substituted with the value passed to the macro. If a macro parameter has a numeric value when the macro is encountered it is evaluated and that number is substituted in the macro expansion. Otherwise, the parameter text is substituted.
For example:
delay2 MACRO count
LOCAL loop
movlw count
movwf delaycnt
loop decfsz delaycnt
goto loop
ENDM
The EXITM comand stops macro expansion immediately. For example
This will expand to just a single 'nop' instruction if the count parameter is
less than two.
delay2 MACRO count
nop
IF count < 2
EXITM
ENDIF
movlw count
movwf delaycnt
loop decfsz delaycnt
goto loop
ENDM
![]() |
![]() |
![]() |