10

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?

Mat
  • 202,337
  • 40
  • 393
  • 406
user541686
  • 205,094
  • 128
  • 528
  • 886

2 Answers2

22

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.

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
Kaz
  • 55,781
  • 9
  • 100
  • 149
  • 2
    +1, a very sophisticated answer to OP's follow up question :) – Niklas B. May 08 '12 at 20:08
  • #2 was a very useful comment, I had no idea about that! Thanks! :) – user541686 May 10 '12 at 22:05
  • in 1. above it says: *"The idea is to generate, and avoid parsing"* yet it seems to me that for the compiler receiving the info about clobbered items involves parsing anyway,right? Coming from the -possibly incorrect- impression that "inline assembly might has not the goal of increasing architecture independence, and will quite easily assembly be platform specific", it would be lovely that there was a dictionary to provide the clobbered information assisted from the compiler, instead to allow programmers to forget things. Has there been some development since the question was given 2012? – humanityANDpeace Jan 19 '17 at 14:29
  • @humanityANDpeace: the compiler has to know register names to parse the clobber list, but that's *all*. It doesn't need a full asm parser. And it doesn't need to know all instructions that implicitly write a register, like x86 `lodsd` is like `mov al, [rsi]` / `inc rsi` (or dec rsi if DF is set). The clobber list is in C syntax, so the C parser takes care of turning it into a list of string literals. Then the compiler just has to match sub-register like EAX to the full register RAX, or xmm0 to ymm0 / zmm0, for the purposes of its own register-allocation for the function. – Peter Cordes Jun 21 '19 at 17:10
  • @humanityANDpeace: re: checking: no gcc / clang don't have any warnings to help you detect missing clobbers for x86 or any other ISA. I'm not aware of any external tools that check the asm template against the clobber list either. https://gcc.gnu.org/wiki/DontUseInlineAsm unless you *have* to, and when possible wrap just a single instruction (which is what GNU C inline asm was designed to do efficiently). – Peter Cordes Jun 21 '19 at 17:13
6

Quote from the docs:

When using __asm to write assembly language in C/C++ functions, you don't need to preserve the EAX, EBX, ECX, EDX, ESI, or EDI registers. For example, in the POWER2.C example in Writing Functions with Inline Assembly, the power2 function doesn't preserve the value in the EAX register. However, using these registers will affect code quality because the register allocator cannot use them to store values across __asm blocks. In addition, by using EBX, ESI or EDI in inline assembly code, you force the compiler to save and restore those registers in the function prologue and epilogue.

You should preserve other registers you use (such as DS, SS, SP, BP, and flags registers) for the scope of the __asm block. You should preserve the ESP and EBP registers unless you have some reason to change them (to switch stacks, for example). Also see Optimizing Inline Assembly.

Community
  • 1
  • 1
Niklas B.
  • 92,950
  • 18
  • 194
  • 224
  • 1
    Kind of pops the question though: why doesn't GCC do this? – user541686 May 08 '12 at 19:30
  • 2
    To summarize for our other readers: "yes, MSVC does autodetect which registers are clobbered, whereas GCC requires you mark them explicitly." – Crashworks May 08 '12 at 19:30
  • 1
    @Crashworks: I'm not so sure that it's that simple. It seems like in [the linked example](http://msdn.microsoft.com/en-us/library/5sds75we(v=vs.80).aspx), the code modifies the EAX register to specify the return value of the function, for example. I consider the GCC approach a lot safer. – Niklas B. May 08 '12 at 19:34
  • @NiklasB. The GCC approach, by requiring to "explicitly name the correct clobbered items" , which can be forgotton is a lot safer, how so? – humanityANDpeace Jan 19 '17 at 14:22