1
votes

I was writing inline assembly code for an operating system assignment. I have some questions regarding inline assembly and its translation into machine code by the gcc compiler.

  1. asm binds input and output to registers. Do we need to save all the registers before doing any operation using asm and restore them back after the operation? Because if the bound register happens to be a register containing an important value in the program, that might be lost and the program might not behave in an expected manner.
  2. How is it decided which register will be bound to which input?
  3. Does asm save the registers used for input and output and restore them on its own?

Edit: Example code is as follows. Which register is top bound to? unsigned long long top; asm volatile("mov %0, %%rsp;" : :"r"(top) :"memory");

1
'asm volatile binds input and output to registers' umm... no. - Martin James
1) Volatile doesn't mean what you seem to think it means. Take a minute to read the gcc docs about inline asm. 2) If (for some reason) you must bind specific registers to inputs/outputs, look at either the x86 constraints or local register variables. There are no guarantees about which registers will get used except for these. 3) If your constraints say you will use a register, gcc makes it available. - David Wohlferd
@prl yeah sure. See the edit - atuly
The reason your question was confusing is that you seemed to be focused on ‘volatile’, which is actually not relevant to your question at all. I have edited the question. - prl
Notes regarding the example code: it is rarely if ever okay to change RSP in inline assembly code. It is rarely if ever okay to change any register without telling the compiler you are doing it. It is rarely useful to use inline assembly to do a ‘mov’ instruction. - prl

1 Answers

1
votes

The compiler has a complex register allocation strategy that it uses for inline asm just as it does for code it generates itself. It can use any registers or other locations for the asm parameters that meet the constraints, so it is difficult to predict which registers might be used and it is highly dependent on the surrounding code.

The compiler ensures that other values that are needed by the compiled code are preserved, by putting them in other registers or spilling to memory. The programmer doesn’t have to worry about that.