title:C inline assembler keywords:c,inline,assembler # C inline assembler There is long time since I wanted to learn "creepy" gcc inline assembly. Looking at manuals its not so hard and "creepy". Using it is more interesting and dissambly of compiled code is very nice looking. volatile puts our asm code where it is and don't optimize it without volatile it can optimize. What to write in __asm__ directive looks like this ```c __asm__ __volatile__("our_code":output:input:used) ``` as code to convert to inline asm we will use last post [2]. There is only one instruction that we using and it usage was ```c get_timer: rdtsc ret ``` its not very optimal and for 1 instruction writing whole function its not beautiful. We remember that returning result of this function is saved in eax register. ```c __asm__ __volatile__("rdtsc":"=a"(x)::) ``` code looks like this. But we can make it as define function ```c #define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::) ``` This code works fine and give 70058 ticks on cycle When adding option -O2 then result becomes wherry strange. As we remember that rdtsc return result in edx:eax then we add to used registers(clobber) %edx. ```c #define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::"%edx") ``` And also we can rewrite everything as inline function. ```c static inline unsigned int get_timeri() { unsigned int i; __asm__ __volatile__("rdtsc":"=a"(i)::); return i; } ``` Now this two functions works fine with -O options. When empty cycle is optimized then it becomes empty and resulting tick number is 32 for both inline function and define macro. It not working for his main purpose. When no optimization switched then get_timer works for some ticks faster then get_timeri. We can add attribute always inline and we will win some ticks and function will always inline regards optimization level ```c __attribute__((always_inline)) unsigned int get_timeri() ``` Too fix test cycle for our measurement we make it as object file and it will compiled without options. ```c void fixed_cycle() { int i; for (i=0;i<10000;i++) { } } ``` Now everything looks quite good and also inline assembly works as expected. For reference about inline asm you can go to [1] ## Links http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html ## Downloads asm_inline.zip - 3KiB - http://archive.main.lv/files/writeup/c_inline_assembler/asm_inline.zip dis_avr0.1.zip - 10KiB - http://archive.main.lv/files/writeup/c_inline_assembler/dis_avr0.1.zip