diff options
author | FreeArtMan <dos21h@gmail.com> | 2021-05-27 20:06:47 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2021-05-27 20:06:47 +0100 |
commit | e63ed8a651e5246f8698a9c1c3e540029710d0e9 (patch) | |
tree | cfd58d80345f17dc9f458bad88181811a89b3592 /md/writeup/c_inline_assembler.md | |
parent | 9b9586b559edb387af804c52d2b593b711ce98be (diff) | |
download | md-content-e63ed8a651e5246f8698a9c1c3e540029710d0e9.tar.gz md-content-e63ed8a651e5246f8698a9c1c3e540029710d0e9.zip |
Update 10 articles from html to md
Diffstat (limited to 'md/writeup/c_inline_assembler.md')
-rw-r--r-- | md/writeup/c_inline_assembler.md | 105 |
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 |