MPASM to MPLAB XC8 PIC Assembler


Starting with MPLABX IDE version 5.40, the assembler MPASM toolchain is no longer supported or installed with the IDE. To program in assembly using MPASM, one needs to install a previous MPLABX version that comes with MPASM. The last version that worked with MPASM was MPLABX v5.35. I’m following the PIC10F200 microcontroller tutorials using v5.35 version, and everything is working okay so far.

But, FYI, you can install multiple MPLABX versions! They are installed in their own directory using the version as the name (so no conflicts or overwriting). I have installed the latest version so that I can use the latest features with other toolchains, but also version v5.35 to work with MPASM. Previous software versions, like v5.35, can be obtained at the Microchip downloads archive page: MPLAB X IDE Archives

To program in assembly with the MPLABX (IDE) v5.40 or the current version (as of early 2021) (v5.45), you also need to install the Microchip C compiler for 8 bit devices, MPLAB XC8, which comes with the new assembler - MPLAB XC8 PIC Assembler (pic-as toolchain). This new assembler is available since version MPLAB XC8 2.20.

MPASM assembly code does not assemble with XC8 PIC Assembler. To help everyone, I have converted all the tutorials source code to the new XC8 PIC Assembler, and they should be at the bottom of each PIC10F200 tutorial page. There are some documents in the XC8 PIC Assembler installation folder about the PIC Assembler and migration from MPASM. If you are really interested in this new assembler make sure to check them out!

Here are the steps that I have followed to convert MPASM code to the PIC Assembler, maybe it will help someone. They are quite a few steps, but it’s easier than it looks.

  • MPASM assembly source files names end with “.asm” extension. PIC Assembler files use “.s” or “.S”.
  • Instead of including the device-specific include files (like “”), the source files should usually include the <> file available with the PIC Assembler.
  • Some constants definitions are different. For example, instead of “GP1” we can use “GPIO_GP1_POSITION”. Some definitions don’t seem to exist, though. For example, “T0CS”, “NOT_GPPU”, “Z”. But we can define them using equates and using MPASM “” file as the reference.
  • The assembler directive “_CONFIG” should be replaced by “CONFIG”.

    Example code in MPASM and PIC Assembler:


    PIC Assembler:
    config WDTE = OFF
    config CP = OFF
    config MCLRE = OFF

  • Labels in PIC Assembler must be followed by a colon “:” In MPASM the colon is optional.
  • By default, MPASM interprets the numeric constants as hexadecimal values. PIC Assembler interprets them by default as decimal values! This is where explicit definition can help with code portability.
  • The radix specifiers in the numeric constants are also a bit different. See the following example.

    Example code in MPASM and PIC Assembler with the default RADIX:

    movlw b'10110011' ; binary value
    movlw o'72' ;octal value
    movlw d'34' ;decimal value
    movlw 4F ;hexadecimal value
    movlw ‘b’ ;ASCII value

    PIC Assembler:
    movlw 10110011B ;binary value
    movlw 72q ;octal value
    movlw 34 ;decimal value
    movlw 04Fh ;hexadecimal value
    movlw ‘b’ ;ASCII value

  • MPASM supports absolute mode, using the ORG directive, or relocatable mode, using program sections. PIC Assembler only supports the relocatable mode. Since the tutorials use the absolute mode you will need to remove the ORG directive and add a program section for the code and data. I have just added a code section for all the instructions and used the already defined equates to access the data memory variables (user registers). So, I have just replaced the ORG directive with the PSECT directive like this:

    PSECT MyCode,class=CODE,delta=2

    Where “MyCode” is the section name, “class=CODE” tells the linker to use the default code section, “delta=2" tells the linker the number of data bytes that are associated with each address.

    We can also just define a code section like this:

    PSECT code

    But I’d rather define my own code section “MyCode” so that I can tell the linker to specifically place this code section at the zero address. Otherwise, the linker will place it somewhere else, and it will probably overwrite the RC oscillator calibration instruction at the top of the memory (address 0FFh).

    To make sure the linker places this section at address 000h, we need to provide an additional command line parameter: Go to “Project Properties” > “pic-as Global Options” > “Additional Options:” and add the following parameter (without spaces!): -Wl,-pMyCode=0h

  • The End directive marks the end of the source code in that module. We can also use a label with the END directive indicating the program entry point.

All these steps may sound like a lot of work, but it’s actually very easy after converting the first couple of tutorials.

We just want to thank tinyelectr from the Discord channel again for converting all of the tutorials over to the XC8 compiler and providing these helpful instructions!

Related Tutorials

Terms Used

Make Bread with our CircuitBread Toaster!

Get the latest tools and tutorials, fresh from the toaster.

What are you looking for?