Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GCC inline assembler require clobbering information, but MSVC doesn't

I don't understand how this is supposed to work.

GCC inline assembler is a pain to get right, but very specific about marking clobbering information, so that the compiler knows what you're doing.

Microsoft Visual C++'s inline assember is really easy to use (it always seems to Just Work), but I have no ideas what kinds of guarantees or assumptions it makes about your code.

Does VC++ try to "auto-detect" what registers are clobbered? How does it know how the registers and the stack pointer will be changed? Does it make any assumptions? If so, how do you get around those assumptions?

like image 582
user541686 Avatar asked May 08 '12 19:05

user541686


People also ask

Does GCC support inline assembly?

GCC provides two forms of inline asm statements. A basic asm statement is one with no operands (see Basic Asm), while an extended asm statement (see Extended Asm) includes one or more operands.

How does inline assembly work?

In computer programming, an inline assembler is a feature of some compilers that allows low-level code written in assembly language to be embedded within a program, among code that otherwise has been compiled from a higher-level language such as C or Ada.

What is clobber list in GCC?

Clobbers. A comma-separated list of registers or other values changed by the AssemblerTemplate , beyond those listed as outputs. An empty list is permitted.

When to use asm volatile?

If the C code that follows the asm makes no use of any of the output operands, use volatile for the asm statement to prevent the optimizers from discarding the asm statement as unneeded (see Volatile).


1 Answers

As for why GCC doesn't do it the way MSVC does, there are several reasons:

  1. GCC is a retargettable compiler, but the assembly syntax is just raw text. In order for the clobber detection to be automatic, GCC would have to parse the assembly language to understand what registers are being clobbered (including implicitly clobbered ones by instructions whose opcodes do not name a register). This would have to work across all architectures. Currently, GCC does not parse the assembly language; it just pastes it into the assembly output, after performing the % substitutions. The idea is to generate, and avoid parsing.

  2. In GCC inline assembly language, clobbering registers is the exception rather than the rule. The reason is that it is a more sophisticated language than that in MSVC. GCC's inline assembly language allocates registers for you. So you usually don't use something like %eax directly, but rather a code like %0 for which GCC substitutes an available register. (And to do that, the compiler doesn't have to understand the assembly language! you express the constraints which ensure that GCC substitutes an appropriate register for %0 which fits the usage.) You only need clobber if your assembly code is overwriting hard-coded registers, not if it is overwriting the output operands allocated for you by GCC.

Note that with GCC inline assembly, you don't have to write the code which loads your assembly language operands from the C expressions that produce their initial values, or which stores your result operands into the C destinations. For instance you just express that there is to be an input operand of type "r" (register) which is derived from the expression foo->bar + 1. GCC allocates the register and generates the code to load it from foo->bar + 1, and then replaces occurences of %0 in your assembly template with the name of that register.

like image 145
Kaz Avatar answered Oct 13 '22 23:10

Kaz