2
votes

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:

  1. Shouldn't the instructions be stored sequentially from 0x0000-0x03FF (PIC16F84A's Program Memory addresses). 0x0000 should always be the starting line or origin of a program, and I've also explicitly stated 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.
  2. What is 0x0089 address and why is it there?

[EDIT] Mapping File (if it matters)
                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
2
Did you look up the semantics of psect? The linker might place the code section (if psect code means this) at this other address.the busybee
@thebusybee, yes it is psect code,class=CODE,space=SPACE_CODE,delta=2 where SPACE_CODE is defined in #define SPACE_CODE 0KMC
Linker probably picked any address available in that range. Add the option -Wl,-Map=temp.map and what does it show in temp.mapMichael Petch
@MichaelPetch edited with part of the mapping file I thought would be relevant (the whole thing is too long to post)KMC
The pic-as(v2.20) tool chain and linker are "old school" tools. The section directive in the assembler is powerful but cryptic. Your immediate issues is that the ORG directive is RELATIVE to where the command line directs the linker to locate that section. Without this directive the linker locates sections starting from the highest address in code space downward.Dan1138

2 Answers

4
votes

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.

0
votes

MPLabX IDE can't build pic-as project correctly for mid-range device due to lack of option to set reset vector at position 0x000 "-Wl,-presetVec=0h". You can build project from command line:

pic-as -mcpu=16f1937 -Wl,-presetVec=0h -Wa,-a -Wl,-Map=test.map test.S

as described in XC8-PIC Assembler Guide for EE.

Alternatively you can try to add option -Wl,-presetVec=0h to pic-as compiler/linker in project options, to build from IDE. MPLABX v5.40 compiler settings

Btw, option for placing interrupt vector in correct position is missing too.