All documentation becomes dated and this manual is no exception. Microchip tools and documentation are constantly
evolving to meet customer needs, so some actual dialogs and/or tool descriptions can differ from those in this
document. Please refer to our web site (https://www.microchip.com) to obtain the latest documentation available.
Documents are identified with a “DS” number. This number is located on the bottom of each page, in front of the page
number. The numbering convention for the DS number is “DSXXXXXA,” where “XXXXX” is the document number
and “A” is the revision level of the document.
For the most up-to-date information on development tools, see the MPLAB® IDE online help. Select the Help menu,
and then Topics to open a list of available online help files.
Notice to Customers.......................................................................................................................................1
The Microchip Website.................................................................................................................................76
This user’s guide describes the use and features of the MPLAB XC8 PIC Assembler. The following Microchip
documents are available and recommended as supplemental reference resources.
MPLAB® XC8 PIC Assembler Migration Guide
This guide is for customers who have MPASM projects and who wish to migrate them to the MPLAB XC8 PIC
assembler. It describes the nearest equivalent assembler syntax and directives for MPASM code.
MPLAB® XC8 PIC Assembler Guide For Embedded Engineers
This guide is a getting started guide, describing example projects and commonly used coding sequences used by the
MPLAB XC8 PIC assembler. Use this guide if you need to develop new projects using the assembler.
MPLAB® XC8 C Compiler Release Notes for PIC MCU
For the latest information on changes and bug fixes to this assembler, read the Readme file in the docs subdirectory
of the MPLAB XC8 installation directory.
Development Tools Release Notes
For the latest information on using other development tools, read the tool-specific Readme files in the docs
subdirectory of the MPLAB X IDE installation directory.
Preface
1.3 Document Revision History
Revision A (March 2020)
• Initial release of this document, based on the assembler chapter from the MPLAB® XC8 C Compiler User's
Guide (DS50002737).
The MPLAB XC8 PIC Assembler is a free-standing cross assembler and linker package, supporting all 8-bit PIC
microcontrollers.
2.1 Device Description
This guide describes the MPLAB XC8 PIC Assembler's support for all 8-bit Microchip PIC devices with baseline, midrange, enhanced mid-range and PIC18 cores. The following descriptions indicate the distinctions within those device
cores:
The baseline core uses a 12-bit-wide instruction set and is available in PIC10, PIC12 and PIC16 part numbers.
The enhanced baseline core also uses a 12-bit instruction set, but this set includes additional instructions. Some of
the enhanced baseline chips support interrupts and the additional instructions used by interrupts. These devices are
available in PIC12 and PIC16 part numbers.
The mid-range core uses a 14-bit-wide instruction set that includes more instructions than the baseline core. It has
larger data memory banks and program memory pages, as well. It is available in PIC12, PIC14 and PIC16 part
numbers.
The Enhanced mid-range core also uses a 14-bit-wide instruction set but incorporates additional instructions and
features. There are both PIC12 and PIC16 part numbers that are based on the Enhanced mid-range core.
The PIC18 core instruction set is 16 bits wide and features additional instructions and an expanded register set.
PIC18 core devices have part numbers that begin with PIC18.
See 3.3.22 Print-devices for information on finding the full list of devices that are supported by the assembler.
Assembler Overview
®
2.2 Compatible Development Tools
The assembler works with many other Microchip tools, including:
• The MPLAB X IDE (https://www.microchip.com/mplab/mplab-x-ide)
• The MPLAB X Simulator
• The Command-line MDB Simulator—see the Microchip Debugger (MDB) User’s Guide (DS52102)
• All Microchip debug tools and programmers (https://www.microchip.com/mplab/development-boards-and-tools)
• Demonstration boards and Starter kits that support 8-bit devices
The name of the command-line driver used by the MPLAB XC8 PIC Assembler is pic-as.
This driver can be invoked to perform both assembly and link steps and is the application called by development
environments, such as the MPLAB X IDE, to build assembly projects.
The pic-as driver has the following basic command format:
pic-as [options] files [libraries]
Throughout this manual, it is assumed that the assembler applications are in your console’s search path or that the
full path is specified when executing the application.
It is customary to declare options (identified by a leading dash “-” or double dash “--”) before the files’ names;
however, this is not mandatory.
The formats of the options are supplied in 3.3 Assembler Option Descriptions along with corresponding
descriptions of the options' function.
The files can be an assortment of assembler source files and precompiled intermediate files. While the order in
which these files are listed is not important, it can affect the allocation of code or data and can affect the names of
some of the output files.
The libraries is a list of user-defined library files that will be searched by the compiler. The order of these files will
determine the order in which they are searched. It is customary to insert the libraries after the list of source files;
however, this is not mandatory.
Assembler Driver
3.1 Single-step Assembly
Assembly of one or more source files can be performed in just one step using the pic-as driver.
The following command will build both the assembly source files, passing these files to the appropriate internal
applications, then link the generated code to form the final output.
pic-as -mcpu=16F877A main.S mdef.s
The driver will compile all source files, regardless of whether they have changed since the last build. Development
environments (such as MPLAB® X IDE) and make utilities must be employed to achieve incremental builds (see 3.2
Multi-step Assembly).
Unless otherwise specified, a HEX file and ELF file are produced as the final output. The intermediate files remain
after compilation has completed, but most other temporary files are deleted, unless you use the -save-temps
option (see 3.3.26 Save-temps Option) which preserves all generated files. Note that some generated files can be in
a different directory than your project source files (see also 3.3.21 O: Specify Output File).
3.2 Multi-step Assembly
A multi-step assembly method can be employed to achieve an incremental build of your project. Make utilities take
note of which source files have changed since the last build and only rebuild these files to speed up assembly. From
within MPLAB X IDE, you can select an incremental build (Build Project icon), or fully rebuild a project (Clean and
Build Project icon).
Make utilities typically call the assembler multiple times: once for each source file to generate an intermediate file and
once to perform the link step.
The option -c is used to create an intermediate file. This option stops after the assembler application has executed,
and the resulting object output file will have a .o extension.
The intermediate files can then be specified to the driver during the second stage of compilation, when they will be
passed to the linker.
The first two of the following command lines build an intermediate file for each assembly source file, then these
intermediate files are passed to the driver again to be linked in the last command.
As with any assembler, all the files that constitute the project must be present when performing the second (link)
stage of compilation.
You might also wish to generate intermediate files to construct your own library files. See 7.1 Archiver/Librarian for
more information on library creation.
3.3 Assembler Option Descriptions
Most aspects of the build process can be controlled using options passed to the assembler's command-line driver,
pic-as.
All options are case sensitive and are identified by leading single or double dash character, e.g. -o or --version.
Use the --help option to obtain a brief description of accepted options on the command line.
If you are compiling from within the MPLAB X IDE, it will issue explicit options to the assembler that are based on the
selections in the project's Project Properties dialog. The default project options might be different to the default
options used by the assembler when running on the command line, so you should review your IDE properties to
ensue that they are acceptable.
The summary of all available driver options tabulated below is followed by a detailed description of each option.
Table 3-1. PIC Assembler Driver Options
Assembler Driver
OptionControls
-###
-c
-mcallgraph=type
-mchecksum=specs
-mcpu=device
-D
-mdfp=path
-dM
-m[no-]download
-E
--fill=options
-gformat
-H
--help
-I
-misa
-l
-L
Display of application command-lines but with no execution
Generation of an intermediate object file
The type of callgraph printed in the map file
The generation and placement of a checksum or hash
Whether intermediate files should be kept after compilation
The insertion of a serial number in the output
What memory summary information is produced
The undefining of preprocessor symbols
Verbose compilation output
Display of assembler version information
The suppression of all warning messages
The threshold at which warnings are output
Options passed to the assembler
Options passed to the preprocessor
Options passed to the linker
The language in which the source files are interpreted
Options passed to the assembler
Options passed to the preprocessor
System-specific options to passed to the linker
Assembler Driver
3.3.1 ### Option
The -### option is similar to -v, but the commands are not executed. This option allows you to see the assembler’s
command lines without executing the assembler.
3.3.2 C: Compile To Intermediate File
The -c option is used to generate an intermediate file for each source file listed on the command line.
This option is often used to facilitate multi-step builds using a make utility.
3.3.3 Callgraph Option
The -mcallgraph=type option controls what sort of call graph is printed in the map file. The available types are
shown in the table.
The callgraph is generated by the linker, primarily for the purposes of allocating memory to objects in the compiled
stack. Those routines defining stack objects that are not overlaid with other stack objects and that are hence
contributing to the program's data memory usage are considered as being on a critical path.
3.3.4 Checksum Option
The -mchecksum=specs option will calculate a hash value (for example checksum or CRC) over the address range
specified and stores the result in the hex file at the indicated destination address. The general form of this option is as
follows.
-mchecksum=start-end@destination[,specifications]
The following specifications are appended as a comma-separated list to this option.
Table 3-3. Checksum Arguments
ArgumentDescription
width=n
offset=nnnn
algorithm=n
polynomial=nn
code=nn
Assembler Driver
Standard, short-form call graph (default)
Full call graph
Selects the width of the hash result in bytes for non-Fletcher algorithms, or in bits for SHA
algorithms. A negative width will store the result in little-endian byte order; positive widths in bigendian order. Result widths from one to four bytes are permitted, or 256 bits for SHA algorithms.
Specifies an initial value or offset added to the checksum.
Selects one of the hash algorithms implemented in Hexmate. The selectable algorithms are
described in Table 7-3.
Selects the polynomial value when using CRC algorithms
Specifies a hexadecimal code that will trail each byte in the result. This can allow each byte of
the result to be embedded within an instruction, for example code=34 will embed the result in a
retlw instruction on Mid-range devices.
revword=n
The start, end and destination attributes are, by default, hexadecimal constants. The addresses defining the
input range are typically made multiples of the algorithm width. If this is not the case, zero bytes will pad any missing
input word locations.
If an accompanying --fill option (3.3.11 Fill Option) has not been specified, unused locations within the specified
address range will be automatically filled with 0xFFF for baseline devices, 0x3FFF for mid-range devices, or 0xFFFF
for PIC18 devices. This is to remove any unknown values from the calculations and ensure the accuracy of the result.
For example:
-mchecksum=800-fff@20,width=1,algorithm=2
will calculate a 1-byte checksum from address 0x800 to 0xfff and store this at address 0x20. A 16-bit addition
algorithm will be used. Table 3-9 shows the available algorithms and 7.2.2 Hash Functions describes these in detail.
Read data in reverse byte order from n-byte wide words. Currently this value can be 0 or 2. A
value of 0 disables the reverse-read feature.
Reflected cyclic redundancy check (CRC)
Subtraction of 32 bit values from initial value
User Guide
DS50002974A-page 10
Assembler Driver
...........continued
SelectorAlgorithm description
-3
-2
-1
1
2
3
4
5
7
8
10
The hash calculations are performed by the Hexmate application. The information in this driver option is passed to
the Hexmate application when it is executed.
Subtraction of 24 bit values from initial value
Subtraction of 16 bit values from initial value
Subtraction of 8 bit values from initial value
Addition of 8 bit values from initial value
Addition of 16 bit values from initial value
Addition of 24 bit values from initial value
Addition of 32 bit values from initial value
Cyclic redundancy check (CRC)
Fletcher’s checksum (8 bit calculation, 2-byte result width)
Fletcher’s checksum (16 bit calculation, 4-byte result width)
SHA-2 (currently only SHA256 is supported)
3.3.5 Cpu Option
The -mcpu=device option must be used to specify the target device when building. This is the only option that is
mandatory.
For example -mcpu=18f6722 will select the PIC18F6722 device. To see a list of supported devices that can be used
with this option, use the -mprint-devices option (3.3.22 Print-devices).
3.3.6 D: Define a Macro
The -Dmacro=text option allows you to define preprocessor macros. For macros to be subsequently processed,
the source files must be preprocessed by having them use a .S file extension or by using the -xassembler-wth-cpp option.
A space may be present between the option and macro name.
With no =text specified in the option, this option defines a preprocessor macro called macro that will be considered
to have been defined by any preprocessor directive that checks for such a definition (e.g. the #ifdef directive) and
that will expand to be the value 1 if it is used in a context where it will be replaced. For example, when using the
option, -DMY_MACRO (or -D MY_MACRO) and supplying the following code:
#ifdef MY_MACRO
movlw MY_MACRO;
#endif
the movlw instruction will be assembled and the value 1 will be assigned to the W register.
When the replacement, text, is specified with the option, the macro will subsequently expand to be the replacement
specified with the option. So if the above example code was compiled with the option -DMY_MACRO=0x55, then the
instruction would be assembled as: movlw 0x55
All instances of -D on the command line are processed before any -U options.
3.3.7 dM: Preprocessor Debugging Dumps Option
The -dM option has the preprocessor produce macro definitions that are in effect at the end of preprocessing. This
option should be used in conjunction with the -E option, and if you want the output directed to a file, use also the -o
option.
The -mdfp=path option indicates that device-support for the target device (indicated by the -mcpu option) should
be obtained from the contents of a Device Family Pack (DFP), where path is the path to the xc8 sub-directory of the
DFP.
When this option has not been used, the pic-as driver will where possible use the device-specific files provided in
the assembler distribution.
The MPLAB X IDE automatically uses this option to inform the assembler of which device-specific information to use.
Use this option on the command line if additional DFPs have been obtained for the assembler.
A DFP might contain such items as device-specific header files, configuration bit data and libraries, letting you take
advantage of features on new devices without you having to otherwise update the assembler. DFPs never contain
executables or provide bug fixes or improvements to any existing tools or standard library functions.
When using this option, the preprocessor will search for include files in the <DFP>/xc8/pic/include/proc and
<DFP>/xc8/pic/include directories first, then search the standard search directories.
3.3.9 Download Option
The -mdownload option conditions the Intel HEX for use by bootloader. The -mdownload-hex option is equivalent
in effect.
When used, this option will pad data records in the Intel HEX file to 16-byte lengths and will align them on 16-byte
boundaries.
The default operation is to not modify the HEX file and this can be made explicit using the option -mno-download.
(-mno-download-hex)
Assembler Driver
3.3.10 E: Preprocess Only
The -E option is used to generate preprocessed assembly source files (also called modules or translation units).
When this option is used, the build sequence will terminate after the preprocessing stage, leaving behind files with
the same basename as the corresponding source file and with a .i extension.
You might check the preprocessed source files to ensure that preprocessor macros have expanded to what you think
they should. The option can also be used to create assembly source files that do not require any separate header
files. This is useful when sending files to a colleague or to obtain technical support without sending all the header
files, which can reside in many directories.
3.3.11 Fill Option
The --fill=options option allows you to fill unused memory with specified values in a variety of ways.
This option is functionally identical to Hexmate's -fill option. For more detailed information and advanced controls
that can be used with this option, refer to 7.2.1.11 Fill.
3.3.12 G: Produce Debugging Information Option
The -gformat option instructs the assembler to produce additional information, which can be used by hardware
tools to debug your program.
The support formats are tabulated below.
Table 3-5. Supported Debugging File Formats
FormatDebugging file format
-gcoff
-gdwarf-3
-ginhx32
-ginhx032
COFF
ELF/Dwarf release 3
Intel HEX with extended linear address records, allowing use of addresses beyond 64kB
INHX32 with initialization of upper address to zero
By default, the assembler produces Dwarf release 3 files.
The -H option prints to the console the name of each header file used, in addition to other normal activities.
3.3.14 Help
The --help option displays information on the pic-as assembler options, then the driver will terminate.
3.3.15 I: Specify Include File Search Path Option
The -Idir option adds the directory dir to the head of the list of directories to be searched for header files. A space
may be present between the option and directory name.
The option can specify either an absolute or relative path and it can be used more than once if multiple additional
directories are to be searched, in which case they are scanned from left to right. The standard system directories are
searched after scanning the directories specified with this option.
Under the Windows OS, the use of the directory backslash character may unintentionally form an escape sequence.
To specify an include file path that ends with a directory separator character and which is quoted, use -I "E:\\",
for example, instead of -I "E:\", to avoid the escape sequence \“. Note that MPLAB X IDE will quote any include
file path you specify in the project properties and that search paths are relative to the output directory, not the project
directory.
3.3.16 Isa Option
The -misa=set option allows the instruction set to be specified for PIC18 targets. The default is the standard PIC18
instruction set, a selection that can be made explicit by using -misa=std. Alternatively, the PIC18 extended
instruction set can be selected by using -misa=xinst. When used with a device that does not support the
requested instruction set, the option will be ignored and a warning issued.
Note that this option will permit the assembler to check for conformance of the assembly program to the selected
instruction set, but it does not instruct the device to operate with the selected instruction set. Use the XINST
configuration bit to enable this in your device.
Assembler Driver
3.3.17 L: Specify Library File Option
The -llibrary option looks for the specified file (with a .a extension) and scans this library archive for unresolved
symbols when linking.
The only difference between using an -l option (e.g., -lmylib) and specifying a file name on the command line
(e.g., mylib.a) is that the assembler will search for the library specified using -l in several directories, as specified
by the -L option.
3.3.18 L: Specify Library Search Path Option
The -Ldir option allows you to specify an additional directory to be searched for library files that have been
specified by using the -l option. The assembler will automatically search standard library locations, so you only need
to use this option if you are linking in your own libraries.
3.3.19 Max Errors
The -fmax-errors=n option sets the maximum number of errors each assembler application, as well as the driver,
will display before execution is terminated.
By default, up to 20 error messages will be displayed by each application before the assembler terminates. The
option -fmax-errors=10, for example, would ensure the applications terminate after only 10 errors.
3.3.20 Maxichip Option
The -mmaxichip option tells the assembler to build for a hypothetical device with the same physical core and
peripherals as the selected device, but with the maximum allowable memory resources permitted by the device
family. You might use this option if your program does not fit in your intended target device and you wish to get an
indication of the code or data size reductions needed to be able to program that device.
The assembler will normally terminate if the selected device runs out of program memory, data memory, or EEPROM.
When using this option, the program memory of PIC18 and mid-range devices will be maximized to extend from
address 0 to either the bottom of external memory or the maximum address permitted by the PC register, whichever
is lower. The program memory of baseline parts is maximized from address 0 to the lower address of the
Configuration Words.
The number of data memory banks is expanded to the maximum number of selectable banks as defined by the BSR
register (for PIC18 devices), RP bits in the STATUS register (for mid-range devices), or the bank select bits in the
FSR register (for baseline devices). The amount of RAM in each additional bank is equal to the size of the largest
contiguous memory area within the physically implemented banks.
If present on the device, EEPROM is maximized to a size dictated by the number of bits in the EEADR or NVMADR
register, as appropriate.
If required, check the map file (see 6.3 Map Files) to see the size and arrangement of the memory available when
using this option with your device.
Note: When using the -mmaxichip option, you are not building for a real device. The generated code may not load
or execute in simulators or the selected device. This option will not allow you to fit extra code into a device.
3.3.21 O: Specify Output File
The -o option specifies the base name and directory of the output file.
The option -o main.elf, for example, will place the generated output in a file called main.elf. The name of an
existing directory can be specified with the file name, for example -o build/main.elf, so that the output file will
appear in that directory.
You cannot use this option to change the type (format) of the output file.
Only the base name of the file specified with this option has significance. You cannot use this option to change the
extension of an output file.
Assembler Driver
3.3.22 Print-devices
The -mprint-devices option displays a list of devices the assembler supports.
The names listed are those devices that can be used with the -mcpu option. This option will only show those devices
that were officially supported when the assembler was released. Additional devices that might be available via device
family packs (DFPs) will not be shown in this list.
The assembler will terminate after the device list has been printed.
3.3.23 Ram Option
The -mram=ranges option is used to adjust the data memory that is specified for the target device. Without this
option, all the on-chip RAM implemented by the device is available, thus this option only needs be used if there are
special memory requirements. Specifying additional memory that is not in the target device might result in a
successful compilation, but can lead to code failures at runtime.
For example, to specify an additional range of memory to that already present on-chip, use:
-mram=default,+100-1ff
This will add the range from 100h to 1ffh to the on-chip memory. To only use an external range and ignore any onchip memory, use:
-mram=0-ff
This option can also be used to reserve memory ranges already defined as on-chip memory in the relevant chipinfo
file. To do this, supply a range prefixed with a minus character, -, for example:
-mram=default,-100-103
will use all the defined on-chip memory, but not use the addresses in the range from 100h to 103h for allocation of
RAM objects.
This option will adjust the memory ranges used by linker classes (see 6.1.1 A: Define Linker Class) . Any objects
contained in a psect that do not use the classes affected by this option might be linked outside the valid memory
specified by this option.
3.3.24 Reserve Option
The -mreserve=ranges option allows you to reserve memory normally used by the program. This option has the
general form:
-mreserve=space@start:end
where space can be either of ram or rom, denoting the data and program memory spaces, respectively; and start
and end are addresses, denoting the range to be excluded. For example, -mreserve=ram@0x100:0x101 will
reserve two bytes starting at address 100h from the data memory.
This option performs a similar task to the -mram and -mrom options, but it cannot be used to add additional memory
to that available for the program.
3.3.25 Rom Option
The -mrom=ranges option is used to change the default program memory that is specified for the target device.
Without this option, all the on-chip program memory implemented by the device is available, thus this option only
needs be used if there are special memory requirements. Specifying additional memory that is not in the target
device might result in a successful compilation, but can lead to code failures at runtime.
For example, to specify an additional range of memory to that on-chip, use:
Assembler Driver
-mrom=default,+100-2ff
This will add the range from 100h to 2ffh to the on-chip memory. To only use an external range and ignore any onchip memory, use:
-mrom=100-2ff
This option can also be used to reserve memory ranges already defined as on-chip memory in the chip configuration
file. To do this supply a range prefixed with a minus character, -, for example:
-mrom=default,-100-1ff
will use all the defined on-chip memory, but not use the addresses in the range from 100h to 1ffh for allocation of
ROM objects.
This option will adjust the memory ranges used by linker classes (see 6.1.1 A: Define Linker Class) . Any code or
objects contained in a psect that do not use the classes affected by this option might be linked outside the valid
memory specified by this option.
Note that some psects must be linked above a threshold address, most notably some psects that hold constqualified data. Using this option to remove the upper memory ranges can make it impossible to place these psects.
3.3.26 Save-temps Option
The -save-temps option instructs the assembler to keep temporary files after compilation has finished.
The intermediate files will be placed in the current directory and have a name based on the corresponding source file.
Thus, compiling foo.s with -save-temps would produce the foo.o object file.
The -save-temps=cwd option is equivalent to -save-temps.
The -save-temps=obj form of this option is similar to -save-temps, but if the -o option is specified, the
temporary files are placed in the same directory as the output object file. If the -o option is not specified, the -save-temps=obj switch behaves like –save-temps.
The -mserial=options option allows a hexadecimal code to be stored at a particular address in program memory.
A typical task for this option might be to position a serial number in program memory.
The byte-width of data to store is determined by the byte-width of the hexcode parameter in the option. For example,
to store a one-byte value, 0, at program memory address 1000h, use -mserial=00@1000. To store the same value
as a four byte quantity use -mserial=00000000@1000.
This option is functionally identical to Hexmate's -serial option. For more detailed information and advanced
controls that can be used with this option (refer to 7.2.1.20 Serial).
3.3.28 Summary Option
The -msummary=type option selects the type of information that is included in the summary that is displayed once
the build is complete. By default, or if the mem type is selected, a memory summary with the total memory usage for
all memory spaces is shown.
A psect summary can be shown by enabling the psect type. This shows individual psects after they have been
grouped by the linker and the memory ranges they cover. Table 4-20 shows what summary types are available. The
default output printed corresponds to the mem setting.
SHA hashes for the generated hex file can also be shown using this option. These can be used to quickly determine
if anything in the hex file has changed from a previous build.
Table 3-6. Summary Types
Assembler Driver
TypeShows
psect
mem
class
hex
file
sha1
sha256
xml
xmlfull
If specified, the XML files contain information about memory spaces on the selected device, consisting of the space’s
name, addressable unit, size, amount used and amount free.
A summary of psect names and the addresses where they were linked will be shown.
A concise summary of memory used will be shown (default).
A summary of all classes in each memory space will be shown.
A summary of addresses and HEX files that make up the final output file will be shown.
Summary information will be shown on screen and saved to a file.
A SHA1 hash for the hex file.
A SHA256 hash for the hex file.
Summary information will be shown on the screen, and usage information for the main memory spaces
will be saved in an XML file.
Summary information will be shown on the screen, and usage information for all memory spaces will be
saved in an XML file.
3.3.29 U: Undefine Macros
The -Umacro option undefines the macro macro.
Any macro defined using -D will be undefined by this option. All -U options are evaluated after all -D options.
3.3.30 V: Verbose Compilation
The -v option specifies verbose compilation.
When this option is used, the name and path of the internal assembler applications will be displayed as they are
executed, followed by the command-line arguments that each application was passed.
You might use this option to confirm that your driver options have been processed as you expect, or to see which
internal application is issuing a warning or error.
The --version option prints assembler version information then exits.
3.3.32 W: Disable all Warnings Option
The -w option inhibits all warning messages, and thus should be used with caution.
3.3.33 Wa: Pass Option To The Assembler Option
The -Wa,option option passes its option argument directly to the assembler. If option contains commas, it is split
into multiple options at the commas. For example -Wa,-a will request that the assembler produce an assembly list
file.
3.3.34 Warn Option
The -mwarn=level option is used to set the warning level threshold. Allowable warning levels range from -9 to 9.
The warning level determines how pedantic the assembler is about dubious type conversions and constructs. Each
warning has a designated warning level; the higher the warning level, the more important the warning message. If the
warning message’s warning level exceeds the set threshold, the warning is printed. The default warning level
threshold is 0 and will allow all normal warning messages.
Use this option with care as some warning messages indicate code that is likely to fail during execution, or
compromise portability.
Assembler Driver
3.3.35 Wp: Pass Option To The Preprocessor Option
The -Wp,option option passes option to the preprocessor, where it will be interpreted as a preprocessor option. If
option contains commas, it is split into multiple options at the commas.
3.3.36 WL: Pass Option To The Linker Option
The -Wl,option option passes option to the linker where it will be interpreted as a linker option. If option
contains commas, it is split into multiple options at the commas.
3.3.37 X: Specify Source Language Option
The -xlanguage option allows you to specify that the source files that follow are written in the specified language,
regardless of the extension they use.
The languages allowed by the PIC Assembler are tabulated below.
Table 3-7. Language options
LanguageDescription
assembler
assembler-with-cpp
For example, the command:
pic-as -mcpu=18f4520 -xassembler-with-cpp init.s
will tell the assembler to run the preprocessor over the assembly source file, even though the init.s file name does
not use a .S extension.
Assembly source code
Assembly source code that must be preprocessed
3.3.38 Xassembler Option
The -Xassembler option option passes option to the assembler, where it will be interpreted as an assembler
option. You can use this to supply system-specific assembler options that the assembler does not know how to
recognize or that can't be parsed by the -Wa option.
The -Xpreprocessor option option passes option to the preprocessor, where it will be interpreted as a
preprocessor option. You can use this to supply system-specific preprocessor options that the assembler does not
know how to recognize.
3.3.40 Xlinker Option
The -Xlinker option option pass option to the linker where it will be interpreted as a linker option. You can use
this to supply system-specific linker options that the assembler does not know how to recognize.
Information about the source language accepted by the macro assemblers is described in this section.
All opcode mnemonics and operand syntax are specific to the target device, and you should consult your device data
sheet. Additional mnemonics, deviations from the instruction set, and assembler directives are documented in this
section.
4.1 Assembly Instruction Deviations
The MPLAB XC8 assembler can use a slightly modified form of assembly language to that specified by the Microchip
data sheets. This form is generally easier to read, but the form specified on the data sheet can also be used. The
following information details allowable deviations to the instruction format as well as pseudo instructions that can be
used in addition to the device instruction set.
4.1.1 Destination And Access Operands
To specify the destination for byte-orientated file register instructions, you may use the operands from either style
shown in Table 4-1. The wreg destination indicates that the instruction result will be written to the W register and the
file register destination indicates that the result will be written to the register specified by the instruction's file register
operand. This operand is usually represented by ,d in the device data sheet.
MPLAB XC8 Assembly Language
Table 4-1. Destination Operand Styles
StyleWreg destinationFile register destination
XC8
MPASM
For example (ignoring bank selection and address masking for this example):
addwf foo,w ;add wreg to foo, leaving the result in wreg
addwf foo,f ;add wreg to foo, updating the content of foo
addwf foo,0 ;add wreg to foo, leaving the result in wreg
addwf foo,1 ;add wreg to foo, updating the content of foo
It is highly recommended that the destination operand is always specified with those instructions where it is needed.
If the destination operand is omitted, the destination is assumed to be the file register.
To specify the RAM access bit for PIC18 devices, you may use operands from either style shown in Table 4-2.
Banked access indicates that the file register address specified in the instruction is just an offset into the currently
selected bank. Unbanked access indicates that the file register address is an offset into the Access bank, or common
memory.
Table 4-2. RAM Access Operand Styles
StyleBanked accessUnbanked access
XC8
MPASM
,w,f
,0,1
,b
,1,0
,c or ,a
This operand is usually represented by ,a in the device data sheet.
Alternatively, an instruction operand can be preceded by the characters “c:” to indicate that the address resides in
the Access bank. For example:
addwf bar,f,c ;add wreg to bar in common memory
addwf bar,f,a ;add wreg to bar in common memory
addwf bar,1,0 ;add wreg to bar in common memory
addwf bar,f,b ;add wreg to bar in banked memory
addwf bar,1,1 ;add wreg to bar in banked memory
btfsc c:bar,3 ;test bit three in the common memory symbol bar
It is recommended that you always specify the RAM access operand or the common memory prefix. If these are not
present, the instruction address is absolute and the address is within the upper half of the access bank (which
dictates that the address must not masked), the instruction will use the access bank RAM. In all other situations, the
instruction will access banked memory.
If you use the XC8 style, the destination operand and the RAM access operand can be listed in any order for PIC18
instructions. For example, the following two instructions are identical:
addwf foo,f,c
addwf foo,c,f
Always be consistent in the use of operand style for each instruction, and preferably, that style should remain
consistent through the program. For example, the instruction addwf bar,1,c is illegal.
For example, the following instructions show the W register being moved to first, an absolute location; and then to an
address represented by an identifier. Bank selection and masking has been used in this example. The PIC18
opcodes for these instructions, assuming that the address assigned to foo is 0x516 and to bar is 0x55, are shown
below.
6EE5 movwf 0FE5h ;write to access bank location 0xFE5
6E55 movwf bar,c ;write to access bank location 0x55
0105 BANKSEL(foo) ;set up BSR to access foo
6F16 movwf BANKMASK(foo),b ;write to foo (banked)
6F16 movwf BANKMASK(foo) ;defaults to banked access
Notice that the first two instruction opcodes have the RAM access bit (bit 8 of the op-code) cleared, but that the bit is
set in the last two instructions.
4.1.2 Bank And Page Selection
The BANKSEL() pseudo instruction can be used to generate instructions to select the bank of the operand specified.
The operand should be the symbol or address of an object that resides in the data memory.
Depending on the target device, the generated code will either contain one or more bit instructions to set/clear bits in
the appropriate register, or use a movlb instruction (in the case of enhanced mid-range or PIC18 devices). As this
pseudo instruction can expand to more than one instruction on mid-range or baseline parts, it should not immediately
follow a btfsx instruction on those devices.
For example:
movlw 20
BANKSEL(_foobar) ;select bank for next file instruction
movwf BANKMASK(_foobar) ;write data and mask address
In the same way, the PAGESEL() pseudo instruction can be used to generate code to select the page of the address
operand. For the current page, you can use the location counter, $, as the operand.
Depending on the target device, the generated code will either contain one or more instructions to set/clear bits in the
appropriate register, or use a movlp instruction in the case of enhanced mid-range PIC devices. As the directive
could expand to more than one instruction, it should not immediately follow a btfsx instruction.
For example:
fcall _getInput
PAGESEL $ ;select this page
This directive is accepted when compiling for PIC18 targets but has no effect and does not generate any code.
Support is purely to allow easy migration across the 8-bit devices.
4.1.3 Address Masking
A file register address used with most instructions should be masked to remove the bank information from the
address. Failure to do this might result in a linker fixup error.
All MPLAB XC8 assembly identifiers represent a full address. This address includes the bank information for the
object it represents. Virtually all instructions in the 8-bit PIC instruction sets that take a file register operand expect
this operand value to be an offset into the currently selected bank. As the device families have different bank sizes,
the width of this offset is different for each family.
The BANKMASK() macro can be used with identifier or address operands. The macro ANDs out the bank information
in the address using a suitable mask. It is available once you include <xc.inc>. Use of this macro increases
assembly code portability across Microchip devices, since it adjusts the mask to suit the bank size of the target
device. An example of this macro is given in 4.1.2 Bank And Page Selection.
Do not use this macro with any instruction that expects its operand to be a full address, such as the PIC18’s movff
instruction.
4.1.4 Movfw Pseudo Instruction
The movfw pseudo instruction implemented by MPASM is not implemented in the MPLAB XC8 assemblers. You will
need to use the standard PIC instruction that performs an identical function. Note that the MPASM instruction:
movfw foobar
maps directly to the standard PIC instruction:
movf foobar,w
MPLAB XC8 Assembly Language
4.1.5 Movff/movffl Instructions
The movff instruction is a physical device instruction, but for PIC18 devices that have extended data memory, it also
serves as a placeholder for the movffl instruction.
For these devices, when generating output for the movff instruction, the assembler checks the psects that hold the
operand symbols. If the psect containing the source operand and the psect containing the destination operand both
specify the lowdata psect flag, the instruction is encoded as the two-word movff instruction. If an operand is an
absolute address and that address is in the lower 4kB of memory, then that is also considered acceptable for the
shorter form of the instruction. In all other situations, the instruction is encoded as a three-word movffl instruction.
Note that assembly list files will always show the movff mnemonic, regardless of how it is encoded. Check the
number of op-code words to determine which instruction was encoded.
4.1.6 Interrupt Return Mode
The retfie PIC18 instruction can be followed by “f” (no comma) to indicate that the shadow registers should be
retrieved and copied to their corresponding registers on execution. Without this modifier, the registers are not
updated from the shadow registers. This syntax is not relevant for Baseline and Mid-range devices.
The following examples show both forms and the opcodes they generate.
0011 retfie f ;shadow registers copied
0010 retfie ;return without copy
The “0” and “1” operands indicated in the device data sheet can be alternatively used if desired.
4.1.7 Long Jumps And Calls
The assembler recognizes several mnemonics that expand into regular PIC MCU assembly instructions. The
mnemonics are fcall and ljmp.
On baseline and mid-range parts, these instructions expand into regular call and goto instructions respectively, but
also ensure the instructions necessary to set the bits in PCLATH (for mid-range devices) or STATUS (for baseline
devices) will be generated, should the destination be in another page of program memory. Page selection instructions
can appear immediately before the call or goto, or be generated as part of, and immediately after, a previous
fcall/ljmp mnemonic.
On PIC18 devices, these mnemonics are present purely for compatibility with smaller 8-bit devices and are always
expanded as regular PIC18 call and goto instructions.
These special mnemonics should be used where possible, as they make assembly code independent of the final
position of the routines that are to be executed.
The following mid-range PIC example shows an fcall instruction in the assembly list file. You can see that the
fcall instruction has expanded to five instructions. In this example, there are two bit instructions that set/clear bits in
the PCLATH register. Bits are also set/cleared in this register after the call to reselect the page that was selected
before the fcall.
Since fcall and ljmp instructions can expand into more than one instruction, they should never be preceded by an
instruction that can skip, e.g., a btfsc instruction.
The fcall and ljmp instructions assume that the psect that contains them is smaller than a page. Do not use these
instructions to transfer control to a label in the current psect if it is larger than a page. The default linker options will
not permit code psects to be larger than a page.
On PIC18 devices, the regular call instruction can be followed by a “,f” to indicate that the W, STATUS and BSR
registers should be pushed to their respective shadow registers. This replaces the “,1” syntax indicated on the
device data sheet.
4.1.8 Relative Branches
The PIC18 devices implement conditional relative branch instructions, e.g., bz, bnz. These instructions have a
limited jump range compared to the goto instruction.
MPLAB XC8 Assembly Language
Unlike the MPLAB XC8 C Compiler, the PIC Assembler will never transform relative branch sequences to increase
their range. If you need a relative branch that can reach targets outside the usual instruction range, use a relative
branch with the reverse condition over a goto instruction. For example, instead of writing:
bz next
write something like:
bnz tmp
goto next
tmp:
4.2 Statement Formats
Valid statement formats are shown in Table 4-3.
The label field is optional and, if present, should contain one identifier. A label can appear on a line of its own, or
precede a mnemonic as shown in the second format.
The third format is only legal with certain assembler directives, such as MACRO, SET and EQU. The name field is
mandatory and should contain one identifier.
If the assembly source file is first processed by the preprocessor, then it can also contain lines that form valid
preprocessor directives. See 5.1 Preprocessor Directives for more information on the format for these directives.
There is no limitation on what column or part of the line in which any part of the statement should appear.
The character set used is standard 7 bit ASCII. Alphabetic case is significant for identifiers, but not mnemonics and
reserved words. Tabs are equivalent to spaces.
4.3.1 Delimiters
All numbers and identifiers must be delimited by white space, non-alphanumeric characters or the end of a line.
4.3.2 Special Characters
There are a few characters that are special in certain contexts. Within a macro body, the character & is used for token
concatenation. To use the bitwise & operator within a macro body, escape it by using && instead or use the and form
of this operator. In a macro argument list, the angle brackets < and > are used to quote macro arguments.
MPLAB XC8 Assembly Language
4.4 Comments
An assembly comment is initiated with a semicolon that is not part of a string or character constant.
If the assembly file is first processed by the preprocessor, then the file can also contain C or C++ style comments
using the standard /* ... */ and // syntax.
4.4.1 Special Comment Strings
Assembly code produced by the MPLAB XC8 C compiler makes use of special comment strings such as ;volatile
and ;wreg free. As the MPLAB XC8 PIC Assembler does not employ optimizations, these strings have no effect
and do not need to be used with assembly source.
4.5 Constants
4.5.1 Numeric Constants
The assembler performs all arithmetic with signed 32-bit precision.
The default radix for all numbers is 10. Other radices can be specified by a trailing base specifier, as given in Table
5-2.
Table 4-4. Numbers And Bases
RadixFormat
BinaryDigits 0 and 1 followed by B
OctalDigits 0 to 7 followed by O, Q, o or q
DecimalDigits 0 to 9 followed by D, d or nothing
HexadecimalDigits 0 to 9, A to F preceded by 0x or followed by H or h
Hexadecimal numbers must have a leading digit (e.g., 0ffffh) to differentiate them from identifiers. Hexadecimal
digits are accepted in either upper or lower case.
Note that a binary constant must have an upper case B following it, as a lower case b is used for temporary (numeric)
label backward references.
In expressions, real numbers are accepted in the usual format, and are interpreted as IEEE 32-bit format.
4.5.2 Character Constants And Strings
A character constant is a single character enclosed in single quotes '.
Multi-character constants, or strings, are a sequence of characters, not including carriage return or newline
characters, enclosed within matching quotes. Either single quotes ' or double quotes " can be used, but the opening
and closing quotes must be the same.
4.6 Identifiers
Assembly identifiers are user-defined symbols representing memory locations or numbers. A symbol can contain any
number of characters drawn from alphabetics, numerics, as well as special characters: dollar, $; question mark, ?;
and underscore, _.
The first character of an identifier cannot be numeric nor the $ character. The case of alphabetics is significant, e.g.,
Fred is not the same symbol as fred. Some examples of identifiers are shown here:
An identifier cannot be one of the assembler directives, keywords, or psect flags.
4.6.1 Significance Of Identifiers
Users of other assemblers that attempt to implement forms of data typing for identifiers should note that this
assembler attaches no significance to any symbol, and places no restrictions or expectations on the usage of a
symbol.
The names of psects (program sections) and ordinary symbols occupy separate, overlapping name spaces, but other
than this, the assembler does not care whether a symbol is used to represent bytes, words or sports cars. No special
syntax is needed or provided to define the addresses of bits or any other data type, nor will the assembler issue any
warnings if a symbol is used in more than one context. The instruction and addressing mode syntax provide all the
information necessary for the assembler to generate correct code.
4.6.2 Assembler-generated Identifiers
Where a LOCAL directive is used in a macro block, the assembler will generate a unique symbol to replace each
specified identifier in each expansion of that macro. These unique symbols will have the form ??nnnn where nnnn is
a 4-digit number. The user should avoid defining symbols with the same form.
4.6.3 Location Counter
The current location within the active program section is accessible via the symbol $. This symbol expands to the
address of the currently executing instruction (which is different than the address contained in the program counter
(PC) register when executing this instruction). Thus:
goto $ ;endless loop
will represent code that will jump to itself and form an endless loop. By using this symbol and an offset, a relative
jump destination can be specified.
Any address offset added to $ has the native addressability of the target device. So, for baseline and mid-range
devices, the offset is the number of instructions away from the current location, as these devices have wordaddressable program memory. For PIC18 instructions, which use byte addressable program memory, the offset to
this symbol represents the number of bytes from the current location. As PIC18 instructions must be word aligned,
the offset to the location counter should be a multiple of 2. All offsets are rounded down to the nearest multiple of 2.