C ++ /反汇编中的奇怪位操作结果?

时间:2016-12-14 10:31:55

标签: c++ gcc x86-64 disassembly

在C ++函数中,我有以下变量:

uint32_t buf = 229;  //Member variable
int bufSize = 0;     //Member variable
static constexpr const uint32_t all1 = ~((uint32_t)0);

这行代码:

uint32_t result = buf & (all1 >> (32-bufSize ));

然后result的值为229,既可以通过控制台输出,也可以通过使用gdb进行调试。预期值当然为0,任何试图重现问题的最小例子都失败了。

所以我去了反汇编并一步一步地执行它。位移操作在这里:

0x44c89e  <+0x00b4>        41 d3 e8                 shr    %cl,%r8d

调试器寄存器在指令之前显示rcx=0x20r8=0xFFFFFFFF

在说明之后,我们仍然有r8=0xFFFFFFFF

我对x86-64程序集的了解很少,但是这条指令应该是一个无符号的移位,那么为什么结果为0呢?

我正在使用mingw-gcc x86-64 4.9.1

1 个答案:

答案 0 :(得分:2)

在编译器上调用-Wall,你将遇到-Wshift-count-overflow问题,因为你使用32进行移位,这是unsigned int的大小。现在你可以做一件事只是为了了解它。将32更改为31并进行编译。然后比较生成的程序集,你就会知道出了什么问题。

最简单的解决方法是使用longall1的{​​{1}}数据类型。