# 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 ```text +---+--------------------+ | 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 ## 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