summaryrefslogtreecommitdiff
path: root/md/writeup/c_inline_assembler.md
diff options
context:
space:
mode:
Diffstat (limited to 'md/writeup/c_inline_assembler.md')
-rw-r--r--md/writeup/c_inline_assembler.md105
1 files changed, 105 insertions, 0 deletions
diff --git a/md/writeup/c_inline_assembler.md b/md/writeup/c_inline_assembler.md
new file mode 100644
index 0000000..5566192
--- /dev/null
+++ b/md/writeup/c_inline_assembler.md
@@ -0,0 +1,105 @@
+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 \ No newline at end of file