I recently started programming PIC microcontrollers after AVR and I wrote a small, do-nothing program just to see what the assembler produces in the HEX file:

;File:  main.s

.include    "p24FJ64GA202.inc"
.global     __reset
.global     __INT1Interrupt

    goto    infinite


    bra     infinite


After building and disassembling, I found that the assembler puts these unnecessary blocks in my code, that I did not write:

Unnecessary code block #1


Unnecessary code block #2

How can I prevent this from happening?


2 Answers 2


Those routines form part of the crt0, the system initialization routines. They are standard routines. Briefly they:

  • Erase the empty memory to a default of 0 throughout
  • Copy the pre-defined data from Flash into RAM

Without those routines the basic C system won't function. They are required for any program written in C.

I know your program isn't written in C, but the whole environment is C. You're using a C compiler, for instance.

Because of that you get the C routines.

You can try adding the linker option -nostartfiles to prevent the inclusion of the crt0. You can also use -nostdlib and -nodefaultlibs to prevent inclusion of standard library functions.

Note that this will completely break compilation of any C files.

Alternatively, you can keep the start files in there and instead of executing your program starting at the reset vector, define a "main" function in assembly which the crt0 will call for you after the system initialization has taken place.

By the way - XC16 is based on GCC 4.5.1.

  • \$\begingroup\$ Nonsense. Of course a basic system will function without these extra routines. As you say, they are required for initializing the C runtime library. If you don't use C, then you aren' using its runtime library, and therefore no need for initialization. \$\endgroup\$ Commented Dec 20, 2014 at 15:56
  • \$\begingroup\$ @OlinLathrop Sorry, that was meant to read "A basic C system", as the sentence following it makes clear. \$\endgroup\$
    – Majenko
    Commented Dec 20, 2014 at 16:18
  • \$\begingroup\$ Still wrong. "The whole environment is C". No. It can be set up that way, and that may be the default, but that still doesn't make the statement true. "You're using a C compiler". Just plain wrong. There is no C compiler in the path from pure assembly source to HEX file. \$\endgroup\$ Commented Dec 20, 2014 at 16:21
  • 2
    \$\begingroup\$ @OlinLathrop MPLAB-X calls xc16-gcc which then passes it on to the assembler when appropriate. By a C compiler I mean the entire XC16 environment. If you directly call the assembler and then the linker, then you could be said not to be working an a C environment, but the simple fact is that if you select XC16 instead of MPASM then you are working in a C environment. \$\endgroup\$
    – Majenko
    Commented Dec 20, 2014 at 16:23
  • \$\begingroup\$ @OlinLathrop In that environment you have to manually tell it you don't want to be using the C routines, as it assumes you want to since you are using C compilation programs to do all the work - gcc, cpp, etc. Call xc16-as and xc16-ld manually if you want to avoid all that, but calling through xc16-gcc, which MPLAB-X does, imposes the C environment on you. \$\endgroup\$
    – Majenko
    Commented Dec 20, 2014 at 16:25

Check your linker options. You probably have building of the project set up assuming C will be used. Those routines are run at startup to initialize the C runtime library. If you're not using C, then you don't need them, and in fact they are a waste of resources. If you define __RESET yourself, then these routines won't get run anyway.

This is one drawback of using a IDE for building. There can be various defaults for choices you didn't even know you were making. Either dig thru the IDE to see how to set all the build options for pure assembly code, or build the project outside the IDE where you control exactly what goes on every command line. The latter is what I always do, in part because I run other tools as part of the build process that MPLAB doesn't know about, including my assembler pre-processor. It also makes it possible to build all the things related to a particular project, not just the PIC firmware, as one batch operation.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.