GCC inline assembly

Here is attempt to make best notes about gcc inline asm. As this is just small operator that is for long time, i dont thing there is some full guide how to use it lets do it here for wisdom of internet.

Inline assembly syntax

asm [volatile] ( 
        AssemblerTemplate
        : OutputOperands
        [ : InputOperands
        [ : Clobbers ] ]
)

Output operands

Option Note
"=r" Write output to register

Input operands

Option Note
"r" Input to register

Clobbers

Clobbers used to tell GCC that registers are used.

Clobber option Note
"0" map to register "0" same register

Modifiers

Modifier Specifies
= Write-only operand, usually used for all output operands
+ Read-write operand, must be listed as an output operand
& A register that should be used for output only

Table of register names

Table of AMD64 register names

+---+--------------------+  
| r |    Register(s)     |  
+---+--------------------+  
| a |   %eax, %ax, %al   |  
| b |   %ebx, %bx, %bl   |  
| c |   %ecx, %cx, %cl   |  
| d |   %edx, %dx, %dl   |  
| S |   %esi, %si        |  
| D |   %edi, %di        |  
+---+--------------------+
Register Name
rax %%rax
rbx %%rbx
rcx %%rcx
rdx %%rdx
rdi %%rdi
rsi %%rsi
rbp %%rbp
rsp %%rsp
r8 %%r8
r9 %%r9
r10 %%r10
r11 %%r11
r12 %%r12
r13 %%r13
r14 %%r14
r15 %%r15

Syscall calling convention

Intel AMD64 Linux

Param Register
1th rdi
2th rsi
3th rdx
4th rcx
5th r8
6th r9
syscall number rax

Example

AMD64 Add two numbers

int32_t a=1,b=2,c=-1;
asm(    
    "movl %1, %0\n\t"
    "addl %2, %0\n\t"
    :"=r"(c)
    :"r"(a),"r"(b)
    :"0");

a,b - use regisers and save result c to register, make to use for c same register by mentioning "0" in clobber register

Output

    movl %edx, %edx
    addl %ecx, %edx
int32_t a=1,b=2,c=-1;
asm(    
    "movl %1, %0\n\t"
    "addl %2, %0\n\t"
    :"=r"(c)
    :"g"(a),"g"(b)
    :"0");

Output

    movl -4(%rbp), %edx
    addl -8(%rbp), %edx

AMD64 Call linux syscall mmap with inline asm

long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off)
{
    long ret;
    asm(
        "mov %p6, %%r9\n\t"
        "mov %p5, %%r8\n\t"
        "mov %p4, %%r10\n\t"
        "mov %p3, %%rdx\n\t"
        "mov %p2, %%rsi\n\t"
        "mov %p1, %%rdi\n\t"
        "mov $9, %%rax\n\t"
        "syscall\n\t"
        :"=a"(ret)
        :[p1]"m"(addr),[p2]"m"(len),[p3]"m"(prot),[p4]"m"(flags),[p5]"m"(fd),[p6]"m"(off));
    return ret;
}

Put result of execution to ret, all paramters in memory

Intel random number with RDRAND

uint64_t get_hw_rand()
{
    uint64_t ret;
    int i=0;
    const int timeout = 10;
    while (i<timeout)
    {
        asm("rdrand %0\n\t"
            :"=a"(ret)::);
        if (ret) break;
        i++;
    }
    return ret;
}

Switching on of intel/att syntax

Inline assembler for GCC by default uses AT&T syntax. There is possible to turn on/off intel syntax.

asm(".intel_syntax noprefix");
asm("mov eax, 1");
asm(".att_syntax prefix");

Asm goto

Links

  1. https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
  2. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
  3. https://en.wikipedia.org/wiki/Inline_assembler
  4. http://www.ethernut.de/en/documents/arm-inline-asm.html
  5. http://wiki.osdev.org/Inline_Assembly
  6. http://asm.sourceforge.net/articles/rmiyagi-inline-asm.txt
  7. http://wiki.osdev.org/Inline_Assembly/Examples
  8. http://wiki.osdev.org/Calling_Conventions