如何在C中执行旋转移位

Sum*_*Tea 9 c assembly

我有一个问题如下所述:如何在没有嵌入式装配的情况下在C中执行旋转移位.更具体一点,如何旋转32位移位int.

我现在在类型的帮助下解决这个问题long long int,但我觉得它有点难看,想知道是否有更优雅的方法.

亲切的问候.

Ber*_*ron 15

(警告未来的读者):维基百科的代码产生次优的asm(gcc包括分支或cmov).请参阅C++中循环移位(旋转)操作的最佳实践,以实现高效的无UB旋转.


来自维基百科:

unsigned int _rotl(unsigned int value, int shift) {
    if ((shift &= 31) == 0)
      return value;
    return (value << shift) | (value >> (32 - shift));
}

unsigned int _rotr(unsigned int value, int shift) {
    if ((shift &= 31) == 0)
      return value;
    return (value >> shift) | (value << (32 - shift));
}
Run Code Online (Sandbox Code Playgroud)

  • gcc -O3 (4.9.2) 编译这两个以使用轮换。不幸的是,它并没有消除条件!可读版本:https://goo.gl/ex5R7q。此处不可读的版本:`_rotr` -&gt; `movl %esi, %ecx / movl %edi, %eax / andl $31, %ecx / rorl %cl, %eax / testl %ecx, %ecx / cmove %edi, %eax / ret`(AMD64 ABI:`%rdi` 中的第一个 arg,`%rsi` 中的第二个,在 `%eax` 中返回)。即使使用 `-O0`,gcc 也会将这对移位转换为一个轮换 insn。 (3认同)
  • 如果要移位的变量已签名,则右移只应进行符号扩展.如果您的'value'变量已签名,则您需要将其转换为无符号以进行右移. (2认同)