I'm using MPLabX IDE 5.4 with XC8 compiler (a C/MPASM hybrid compiler that has a driver named pic-as v.2.2 as its assembler) to compile/assemble a simple piece of assembly code and to output a listing file.
My entire assembly code:
PROCESSOR 16F84A
#include <xc.inc>
PSECT code
; a comment
org 00
addlw 01
addlw 02
addlw 03
clrw
loop: addlw 04
goto loop
end loop
Listing file:
Same result generated either from MPLab X IDE's Disassembly Listing File or through a CLI command: $pic-as -mcpu=16F84A -Wa,-a MyAssemblyFile.S -o MyFolder/MyOutputFileName
):
1 processor 16F84A
2 pagewidth 132
3 psect udata,global,class=RAM,space=1,delta=1,noexec
4 psect udata_bank0,global,class=BANK0,space=1,delta=1,noexec
5 psect code,global,class=CODE,delta=2
6 psect data,global,class=STRCODE,delta=2,noexec
7 psect edata,global,class=EEDATA,space=3,delta=2,noexec
8 0089
9 psect code
10 01FA org 0
11 01FA 3E01 addlw 1
12 01FB 3E02 addlw 2
13 01FC 3E03 addlw 3
14 01FD 0103 clrw
15 01FE loop:
16 01FE 3E04 addlw 4
17 01FF 29FE goto loop
The first column contains the line number (i.e. 1,2,3...19). The second and third column list out respectively the memory (vector) addresses (0x01FA-0x01FE) and the opcode (3E08, 29FE etc.) per instruction.
Questions:
org 0
as the program origin. But the listing file shows instructions occupying 0x01FA-0x01FF instead - as if the assembler counted upward from the middle of the program memory (0x03FF / 2 = 0x01FF) and started off from 0x01FA.0x0089
address and why is it there? Name Link Load Length Selector Space Scale
Output/temp.o code 1FA 1FA 6 3F4 0
TOTAL Name Link Load Length Space
CLASS CODE
code 1FA 1FA 6 0
Microchip has made it very to hard to develop 8-bit assembly language applications using the latest release of MPLABX v5.40.
To help I have crafted a PIC16F84A example project you can find here.
This is the pic-as(v2.20) source code:
;
; File: main.S
; Target: PIC16f84A
; Author: dan1138
; Date: 2020-08-20
; Compiler: pic-as(v2.20)
; IDE: MPLABX v5.40
;
; Description:
;
; Example project for the PIC16F84A controller using the pic-as(v2.20) tool chain.
;
; Add this line in the project properties box, pic-as Global Options -> Additional options:
; -Wa,-a -Wl,-pPor_Vec=0h,-pIsr_Vec=4h
;
; PIC16F84A
; +----------:_:----------+
; <> 1 : RA2 RA1 : 18 <>
; <> 2 : RA3 RA0 : 17 <>
; <> 3 : RA4/T0CKI OSC1 : 16 <- 4MHz crystal
; ICSP_VPP -> 4 : MCLR OSC2 : 15 -> 4MHz crystal
; GND -> 5 : GND VDD : 14 <- 5v0
; <> 6 : RB0/INT PGD/RB7 : 13 <> ICSP_PGD
; <> 7 : RB1 PGC/RB6 : 12 <> ICSP_PGC
; <> 8 : RB2 RB5 : 11 <>
; <> 9 : RB3 RB4 : 10 <>
; +-----------------------:
; DIP-18
PROCESSOR 16F84A
PAGEWIDTH 132
RADIX DEC
#include <xc.inc>
; PIC16F84A Configuration Bit Settings
config FOSC = HS ; Oscillator Selection bits (HS oscillator)
config WDTE = OFF ; Watchdog Timer (WDT disabled)
config PWRTE = OFF ; Power-up Timer Enable bit (Power-up Timer is disabled)
config CP = OFF ; Code Protection bit (Code protection disabled)
skipnc MACRO
btfsc STATUS,STATUS_C_POSITION
ENDM
skipnz MACRO
btfsc STATUS,STATUS_Z_POSITION
ENDM
;
; Power-On-Reset entry point
;
PSECT Por_Vec,global,class=CODE,delta=2
global resetVec
resetVec:
PAGESEL main ;jump to the main routine
goto main
;
; Data space use by interrupt handler to save context
PSECT Isr_Data,global,class=RAM,space=1,delta=1,noexec
;
GLOBAL WREG_save,STATUS_save
;
WREG_save: DS 1
STATUS_save: DS 1
PCLATH_save: DS 1
;
; Interrupt vector and handler
PSECT Isr_Vec,global,class=CODE,delta=2
GLOBAL IsrVec
;
IsrVec:
movwf WREG_save
swapf STATUS,W
movwf STATUS_save
movf PCLATH,W
movwf PCLATH_save
;
IsrHandler:
;
IsrExit:
movf PCLATH_save,W
movwf PCLATH
swapf STATUS_save,W
movwf STATUS
swapf WREG_save,F
swapf WREG_save,W
retfie ; Return from interrupt
;objects in bank 0 memory
PSECT MainData,global,class=RAM,space=1,delta=1,noexec
max: DS 1 ;reserve 1 byte for max
tmp: DS 1 ;reserve 1 byte for tmp
/* find the highest PORTB value read, storing this into the object max */
PSECT MainCode,global,class=CODE,delta=2
main:
BANKSEL TRISB ;starting point
movlw 0xFF
movwf BANKMASK(TRISB) ;
BANKSEL max
clrf BANKMASK(max)
loop:
BANKSEL PORTB ;read and store port value
movf BANKMASK(PORTB),w
BANKSEL tmp
movwf BANKMASK(tmp)
subwf max,w ;is this value larger than max?
skipnc
goto loop ;no - read again
movf BANKMASK(tmp),w ;yes - record this new high value
movwf BANKMASK(max)
goto loop ;read again
END resetVec
If you can please get a copy of the entire MPLABX project from my git repository. There are some things you need to learn about setting up an assembly language project in MPLABX that Microchip has not document in enough detail yet.
I am not an employee if Microchip and they could not pay me enough to do this for them.
I expect issues with the MPLABX tools to become more of a problem as schools start teaching PIC assembly language in the fall sessions. My goal with this answer is to try to help before more students get frustrated and fail because of trivial issues with lame tools.