I ran into a problem with gcc-6.3 allocating registers for some asm code;
re-using a register that resulted in the code not working.
Before entering a bug report to gcc, I compiled the latest version, 8.2,
and tried that. Unfortunately, that version insists on inserting a
prologue to my _start routine, which means it will not work. The same
problem occurred with 6.3, at the beginning, but with the optimisation
level -Os, the prologue and epilogue are not generated.
The proper solution would be to have attribute(( naked )) implemented,
but that is not trivial.
However, when I was thinking of arguments why I wanted a "naked" attribute,
one of the reasons I thought of was that I didn't want to write loops in
assembler any more.
I suspect the register allocation code in 6.3 makes the assumption that
the assembler does not contain a loop, without which the re-use of the
register may have been acceptable.
Anyway, modifying the problem code to have C perform the loop and the
assembler code just linear means that the old compiler will generate
working code again.
I had a moan about this on iconbar.com, and got a very helpful reply.
https://www.iconbar.com/forums/viewthread.php?threadid=11474&page=1#124378
Long story short: the outputs should be labelled "early-clobber" ("=&r") so that they don't re-use input registers.
"The compiler does not analyse the text in the asm block at all. The compiler models the inline asm as a sequence of
So the writes of the output registers overwrite ("clobber") the previous content of the registers late in the process. Where there is a write before a read, it overwrites the previous value "early" in the process, hence "early clobber". "