Using PIC Assembly in SDCC Projects With MPLABX

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!

 

Leave a Reply

Your email address will not be published. Required fields are marked *

© Zillow, Inc., 2006-2016. Use is subject to Terms of Use
What's a Zestimate?