Dont think code it

2010-2-23 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

__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


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.

__asm__ __volatile__("rdtsc":"=a"(x)::)

code looks like this. But we can make it as define function

#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.

#define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::"%edx")

And also we can rewrite everything as
inline function.

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

__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.

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]



asm_inline.zip3KiB dis_avr0.1.zip10KiB