【问题标题】:Left bitwise rotation on variable without carry?没有进位的变量左按位旋转?
【发布时间】:2011-04-07 20:36:58
【问题描述】:

让我们有一个任务是在 C++ 中对变量 a 进行左按位旋转而不进位。我认为,使用内联汇编来执行这个例程会更好,不是吗?

例如,如果我们有a == 100 == 0b<a bunch of zeros>1100100a LR 1 应该提供0b1001001 == 73(即不是0b11001000 == 200)。

那么,问题是:应该如何重写下面的代码以适应上面的任务?

#include <stdio.h>

int main()
{
  long long a = 0;

  scanf("%ld", &a);

  // Here the left-shifting should be replaced with left-rotating
  printf("%ld\n", a << 1);

  return 0;
}

【问题讨论】:

  • 这几乎肯定不会更好。 a &lt;&lt; 1 将映射到您可以编写的完全相同的程序集(或者,至少,等效程序集 - 例如寄存器可能不同)。
  • 您想转移到哪里?您的样本显示只是很长。如果这就是您的意思,a
  • 我认为现有的班次是无效的?
  • 抱歉,忘了说一个小因素 =)
  • @shybovycha:我认为您误解了进位在 ASM 级别的工作原理。它通常来自 MSb(位 31 或 63),或来自 lsb(位 0)

标签: c gcc bitwise-operators inline-assembly


【解决方案1】:

Shift-with-carry 在高级语言(甚至 C)中是没有意义的,因为除了更多的内联汇编之外,没有办法从这些语言中读取进位标志(以前是高位)。

另一方面,如果您将高位存储到另一个变量(并且还执行移位操作),编译器可能会生成一个带有进位的移位,然后是添加进位或 mov-carry 以将其到达那里。编译器也相当擅长将两条指令组合成乘加融合指令。


查看您修改后的问题,您尝试执行的操作与通用处理器上可用的任何带进位移位指令完全无关。由于您希望移动一位然后清除最高有效位,您可能会发现 bsr 指令很有帮助,许多编译器都有 intrinsic functions 让您可以从 C 代码中访问此指令。

【讨论】:

    【解决方案2】:

    使用内联汇编来做一些简单的事情,比如带进位的左移,当然不会更好。任何现代编译器都可以轻松处理该问题并生成与您手写的任何内容等效的程序集,而且还具有不依赖于平台的优势。

    【讨论】:

      【解决方案3】:

      如果您真的想要汇编程序,那么在 Visual C++ 中可能会出现将 64 位变量左旋转一位的方式(对于 GCC __asm 不同)。为了比较,还有 C++ 中的实现。当然这是 32 位汇编程序。

      unsigned long long rotate_left_64(unsigned long long n)
      {  
          return (n << 1) | (n >> 63);
      }
      
      int main()
      {
          unsigned long long a = 0xF0F0F0F0F0F0F0F0;
      
          std::cout << std::hex << rotate_left_64(a) << std::endl;
      
          __asm
          {
              lea ebx, a
              rol DWORD PTR [ebx], 1
              rcl DWORD PTR [ebx+4], 1
          }
          std::cout << std::hex << a << std::endl;
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 2017-03-05
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多