9.2 Simple Inline Assembly

Here we introduce the syntax of asm assembler instructions with an x86 example to shift a value 8 bits to the right:

 
asm ("shrl $8, %0" : "=r" (answer) : "r" (operand) : "cc"); 

The keyword asm is followed by a parenthetic expression consisting of sections separated by colons. The first section contains an assembler instruction and its operands. In this example, shrl right-shifts the bits in its first operand. Its first operand is represented by %0. Its second operand is the immediate constant $8.

The second section specifies the outputs. The instruction's one output will be placed in the C variable answer, which must be an lvalue. The string "=r" contains an equals sign indicating an output operand and an r indicating that answer is stored in a register.

The third section specifies the inputs. The C variable operand specifies the value to shift. The string "r" indicates that it is stored in a register but omits an equals sign because it is an input operand, not an output operand.

The fourth section indicates that the instruction changes the value in the condition code cc register.

9.2.1 Converting an asm to Assembly Instructions

GCC's treatment of asm statements is very simple. It produces assembly instructions to deal with the asm's operands, and it replaces the asm statement with the instruction that you specify. It does not analyze the instruction in any way.

For example, GCC converts this program fragment

 
double foo, bar; 
asm ("mycool_asm %1, %0" : "=r" (bar) : "r" (foo)); 

to these x86 assembly instructions:

 
        movl -8(%ebp),%edx 
        movl -4(%ebp),%ecx 
#APP 
        mycool_asm %edx, %edx 
#NO_APP 
        movl %edx,-16(%ebp) 
        movl %ecx,-12(%ebp) 

Remember that foo and bar each require two words of stack storage on a 32-bit x86 architecture. The register ebp points to data on the stack.

The first two instructions copy foo into registers EDX and ECX on which mycool_asm operates. The compiler decides to use the same registers to store the answer, which is copied into bar by the final two instructions. It chooses appropriate registers, even reusing the same registers, and copies operands to and from the proper locations automatically.