Picking up bytes littered around main
If you’ve been following my quest for the smallest program from the beginning, you know that we still have 54 extra bytes to get rid of.
Next let us look at the code bracketing the top and bottom our main() function.
Before our code, we have…
36: 02 d0 rcall .+4 ; 0x3c 38: 04 c0 rjmp .+8 ; 0x42 <_exit>
…which does a call into our main(), and then jumps to the exit handler when our main() returns.
The code after our main() looks like this…
00000042 <_exit>: 42: f8 94 cli 00000044 <__stop_program>: 44: ff cf rjmp .-2 ; 0x44 <__stop_program>
Why does the compiler want to call into our code, only to jump to the end when our code returns? Wouldn’t it be easier just put the exit routine dangling after our code so that the execution would just naturally flow from the end of our program into the exit routine?
One good explanation: It is important to call into main() so that can have a return at the end. The return makes it so that we can (theoretically) call main() from other parts of our program just as if it was a normal function. This makes perfect sense, except that the compiler didn’t put a return at the end of the main() function! Hmmm.. I am getting very mixed messages here. Either put a return at the end of the function or don’t call into the function – but not both.
In fact, our code can never return because it has an infinite loop. I think the compiler knows this at some level and that is why it didn’t put in the return, but it forgot to tell the part of the compiler that generated the call. In any case, we don’t need the call, or the return.
The exit code turns off interrupts and goes into an infinite loop. I can understand the loop – in general you don’t want a program to finish and then run off the end of the earth. I don’t understand why you’d want to turn off interrupts – to me intuitively interrupts should still keep working even after main() returns, but this is a matter of taste. The point is moot here because our little program has its own little infinite loop so it never finishes and never touches any of this exit code.
We’ve been able to prune away everything now except for the interrupt vectors – and those are bigger than everything so far put together. A job for next time…