Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>That inline assembly is buggy:</p> <ol> <li>It uses multi-line strings which effectively concatenate. Without <code>\n</code> all appears on one line. Whether your assembler <em>accepts</em> statements separated by semicolons makes all the difference there ... some may not.</li> <li>It specifies the same variable as input/output constraint instead of using <code>"+r"(value)</code> as ordinarily suggested for this situation.</li> </ol> <p>Without seeing the rest of the code it's not quite clear why the inline assembly statement looks the way it does; Personally, I'd suggest to write it like:</p> <pre><code>asm("ror %%cl, %0" : "+r"(value) : "c"((((uintptr_t)address) &amp; 3) &lt;&lt; 3))); </code></pre> <p>because there's little need to do the calculation itself in assembly. The <code>uintptr_t</code> (from <code>&lt;stdint.h&gt;</code>) cast makes this 32/64bit agnostic as well.</p> <p><strong>Edit:</strong></p> <p>If you want it for a <em>different</em> CPU but x86 / x64, then it obviously needs to be different ... For ARM (<em>not</em> Thumb2), it'd be:</p> <pre><code>asm("ROR %0, %0, %1" : "+r"(value) : "r"((((uintptr_t)address) &amp; 3) &lt;&lt; 3))); </code></pre> <p>since that's how the rotate instruction there behaves.</p> <p><strong>Edit (add reference):</strong></p> <p>Regarding the operation performed here as such, <a href="http://chsc.wordpress.com/2010/01/13/compiler-optimization/" rel="nofollow">this blog post</a> gives an interesting perspective - namely, that the compiler is quite likely to create the same output for:</p> <pre><code>(a &gt;&gt; shift | a &lt;&lt; (8 * sizeof(a) - shift)) </code></pre> <p>as for the x86 inline</p> <pre><code>asm("ror %%cl, %0" : "+r"(a) : "c"(shift)) </code></pre> <p>Testing this:</p> <pre><code>#include &lt;stdint.h&gt; int main(int argc, char **argv) { unsigned int shift = (int)((((uintptr_t)argv) &amp; 3) &lt;&lt; 3); unsigned int a = argc; #ifdef USE_ASM /* * Mark the assembly version with a "nop" instruction in output */ asm("nop\n\t" "ror %%cl, %0" : "+r"(a) : "c"(shift)); return a; #else return (a &gt;&gt; shift | a &lt;&lt; (8 * sizeof(a) - shift)); #endif } </code></pre> <p>Compile / disassemble it:</p> <pre>$ gcc -DUSE_ASM -O8 -c tf.c; objdump -d tf.o tf.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 : 0: 83 e6 03 and $0x3,%esi 3: 8d 0c f5 00 00 00 00 lea 0x0(,%rsi,8),%ecx a: 90 nop b: d3 cf ror %cl,%edi d: 89 f8 mov %edi,%eax f: c3 retq $ gcc -O8 -c tf.c; objdump -d tf.o tf.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 : 0: 83 e6 03 and $0x3,%esi 3: 8d 0c f5 00 00 00 00 lea 0x0(,%rsi,8),%ecx a: d3 cf ror %cl,%edi c: 89 f8 mov %edi,%eax e: c3 retq</pre> <p>Ergo, this inline assembly is unnecessary.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload