One of the features that I’d like to see added to the SDCC toolchain for MPLABX is the ability to include .asm files in projects and have the tool chain understand them. The current version of the tool chain doesn’t understand how to build and object file from an .asm source file and include this object in the link step. After fiddling with this for an hour, I figured out a simple work-around that requires no manual build steps. This process involves using a pre-build instruction which executes the assembler.Note that paths used in this example assume a Windows installation of MPLABX, but can be easily adapted for use with Linux.
The file or files to be assembled should be included in your MPLABX project. Without a prebuild step, the build will fail lacking a recipe for generating an object (.0) file from your assembly files (.asm). In order to prevent this, right click on your project and edit the project properties. Select the building step and add a line to execute before the build, being sure to check the “Execute this line before build” checkbox. In text field, add the following:
asmbuild.cmd build\${ConfName}\${IMAGE_TYPE} ${Device}
Next, create an asmbuild.cmd file to assemble each of your project’s .asm files:
mkdir %1 gpasm -D _LIBBUILD=1 --expand ON -u -c -p %2 -o %1\function.o function.asm gplib -c %1\function.A %1\function.o
Note that the library line is optional, the important task is to create object files from your assembly source. Here is another asmbuild.cmd example that will assemble ALL of the .asm files in your project directory, respecting MPLABX’s project target directory structure:
@echo off mkdir %1 for %%f in (*.asm) do ( echo gpasm -D _LIBBUILD=1 --expand ON -u -c -p %2 -o %1\%%~nf.o %%f gpasm -D _LIBBUILD=1 --expand ON -u -c -p %2 -o %1\%%~nf.o %%f )
Having created object files for each .asm file in the prebuild step will prevent MPLABX make from attempting to build the object file itself as it will already exist. Note that the output path are specified as well as the target device are specified in the command line from the project properties and used in the build script as %1 and %2, respectively. This should allow creation of additional configurations without the need to modify the command file.
The assembly source for function.asm looks like this:
.function.data udata _arg1 res .1 _arg2 res .1 _result res .1 .function.code code global _arg1, _arg2 _functionAdd: movf _arg1, w addwf _arg2, w movwf _result return global _functionAdd end
Note the required underscore name mangling used by SDCC. Calling this function is as easy as declaring externs for arguments and the function itself, then calling the assembly routine as a regular C function:
extern unsigned char arg1; extern unsigned char arg2; extern void functionAdd(); /* * */ int main(int argc, char** argv) { argc; argv; //Quick oscillator configuration OSCCON = 0b01110000; arg1 = 10; arg2 = 120; functionAdd(); return 0; }
Additionally, breakpoints on or stepping into the assembly subroutine will take you right into your asm source which is extremely useful.
I hope this brief post is helpful. Feel free to leave any questions or comments below!