GCC’s inline assembler syntax is very powerful and is the best mechanism I know of to mix assembly code and optimized C/C++ code. It lets you take advantage of assembly features like add-with-carry or direct calls into the kernel without losing optimizations. I don’t know of any other approach which supports that.
That said, the inline assembler syntax is also a set of traps for the unwary. Because the compiler applies optimizations around the assembler code, the inline assembler construct must precisely describe what the inline assembler code does. This is done by using constraints and by listing registers and memory that are clobbered—changed in a way which can not be easily described. Constraints are underdocumented, machine specific, and easy to get wrong.
For a complex and underdocumented construct like inline assembler, it is naturally tempting to simply copy some existing example. Unfortunately, even minor changes to the assembler code can require changes to the constraints. Unfortunately, there is no automated way to check whether you got them right. Unfortunately, it is common for incorrect constraints to work fine in simple cases and break in complex one, or to work fine with one gcc release and break with another.
So using inline assembler really requires reading and understanding the documentation. In particular the = and & constraints must be used correctly. On non-orthogonal machines like the x86 the register class constraints must be used correctly. In many cases it will be better to simply write the assembler code in a separate file and call it.
Several years ago I sketched out a different approach that might be easier to use in some cases. However, actually implementing something along those lines requires embedded the assembler into the compiler. This is unlikely to ever actually happen. I’m certainly not working on it.
Leave a Reply
You must be logged in to post a comment.