Gcc Inline Asm - HsuJv/Note GitHub Wiki

Gcc Inline Asm

Overview

  • In many senses that we are developing some system or kernel modules, the high-level programming language cannot take the place of assembly. But on the other hand, it's hard for us to give up the advance and the convenience of the high-level programming language.
  • Thus we need a solution to combine the C (or any other high-level programming language) with assembly. And the GCC inline ASM mechanism do this work helpfully.
  • GCC has provided keywords to combine inline assembly statements. For example #define nop() __asm__ __volatile__ ("nop \n\t")

Inline Assembly Expression

  • Inline assembly in GNU C consists of four components, split by :
    • instruction:output:input:clobbered register
    • Instruction: the assembly itself, the format is similar to AT&T assembly. Assembly instructions are enclosed in pairs of quotation. If two or more instructions in one pair, \n or ; is needed to separate them, otherwise \t is needed if in different pairs. Another % is needed before registers, e.g. "movl $1, %%eax \n\t"
    • Output: the output part of the instruction. Format as "constraint"(expression), split by a comma. constraint: can be decorated by both = or +, = means that this is a pure output, and + means that this is used both for output and input. For more details, see Constraints and Decorations
    • Input: the input part of the instruction. Format as "constraint"(expression), split by a comma. The = and + are prohibited in the input constraint, thus this part is read-only.
    • clobbered register: declaim the registers, memory, and flags that will be modified in the instructions
      • registers: list the registers that neither input nor output but uses in the instructions. Then the compiler will protect them in the inline process.
      • memory: if the constructions have modified the memory, "memory" should be declaimed to trigger a write-through
      • flags: use "cc" if the rflags register has changed.

Constraints and Decorations

  • Every expression of input and output should specify their constraints. Constraint can be subdivided into register constraints, memory constraints, and immediate constraints
    • register constraints: the carrier of the expression is a register. This register can be specified explicitly or be assigned by the compiler.
      Table of Common Constraints
      short description short description
      r any input/output registers d rdx/edx/dx/dl
      q eax/ebx/ecx/edx D rdi/edi/di
      g any registers or memory S rsi/esi/si
      m memory f xmms
      a rax/eax/ax/al i an immediate integer
      b rbx/ebx/bx/bl f an immediate float
      c rcx/ecx/cx/cl
    • memory constraints: the carrier of the expression should be a memory, use m.
    • immediate constraints: the expression is an imeediate and should not be store in any registers and memory.
  • Decorations can be used only in the output part. Apart from + and =, there is &, which ought to after the + or =. The decoration & tells the compiler that this output expression should be assigned a register ahead of any input expression. Otherwise, the compiler will first assign register for input expressions.
  • Ordered Placeholder: Use %0 to specify the first output expression, %1 to the second and so on. The input expressions are numbered straightly after the output expressions.
⚠️ **GitHub.com Fallback** ⚠️