# What happens when you fall off the end of main() in a PIC? [duplicate]

Another question included this program:

void main(void){
TRISD = 0x00;
PORTD = 0xFF;
}


Let us assume that it does exactly what was intended up through the last line of main().

My question is, what happens in a PIC18F4550 when the flow of control falls off the end of main()? I assume any decent PIC programmer will fill the instruction space after main() with either all-1s or all-0s, but I don't know which.

I can see from the PIC instruction set docs that an all-zeroes instruction is NOP, which is harmless in itself, but what happens when the program counter hits the end of the instruction space? Does it wrap around, halt, catch fire, emit monkeys...?

If PIC programmers fill program space with all-1s instead, as in an empty EEPROM, it appears that that will be an ADDLW instruction that adds 0xFF to W. If that is correct and we don't care about what happens to W, is this the same as the NOP case?

Do the answers to the above questions argue for doing something else, such as running an infinite loop to prevent execution from leaving main()? I don't think we can sleep the microcontroller here, since that won't keep the port D lines up indefinitely, as the OP wanted.

• – Renan Jun 2 '14 at 16:40
• @Renan: Thanks, I didn't find that when searching before asking. The first answer to the other question covers all of my questions. Let's close this one and ask the mods to merge the answers. – Warren Young Jun 2 '14 at 17:06

main() is a function just like any other. When you "run off the end", it returns to whoever called it. For a discussion of what happens then, see this question.

• *almost like any other. main is implicitly called from the top level upon boot. – Reinderien Sep 6 '17 at 21:55
• @Reinderien: The fact that main() is called by a startup function buried inside the C runtime library does not in fact affect in any way the manner in which main() is compiled. Did you look at the discussion in the linked question? – Dave Tweed Sep 6 '17 at 22:10

You can easily answer this for yourself by looking the disassembly of the compiled code in MPLAB, for whatever compiler you happen to be using (and by stepping through the program using MPSIM).

Typically it will start back again at the beginning rather than executing random stuff in the program memory, because the program will be entered with a 'call' in assembly language and will end with a 'return 0'.

This is considered a "freestanding environment" because there is no operating system.

Officially, from the ISO/IEC 9899:1999 (E) C standard, "The effect of program termination in a freestanding environment is implementation-defined" (emphasis added).

It is probably not a good idea to invoke implementation-defined behavior if it is not necessary.

If it were my intent to run the processor in an infinite loop at that point, I'd write it explicity and not count on whatever the C/C++ initialization code does if it ever gets control back (though one likely scenario is that it re-runs the application, initialization and all).

• Except that unlike a real start-from-reset, special purpose registers will NOT necessarily have their start-up default values. – Wouter van Ooijen Jun 2 '14 at 17:28