C 左、右位移位31如何等于&;0x7FFF

C 左、右位移位31如何等于&;0x7FFF,c,assembly,C,Assembly,我正在将x86程序集转换为C代码,但无法理解为什么下面这两行代码等于C代码 汇编代码: sall $31, %eax sarl $31, %eax 等效C代码: int t = t & 0x7FFF; 其次,C代码的等效表达式是: t = t << 31; t = t >> 31; t=t>31; sall/sarl组合不等同于和0x7FFF。因为这是一个算术移位(与逻辑移位相反),所以当右移时,它用符号位的副本填充位。因此,如果eax在最左边的位中有零,它

我正在将x86程序集转换为C代码,但无法理解为什么下面这两行代码等于C代码

汇编代码:

sall $31, %eax
sarl $31, %eax
等效C代码:

int t = t & 0x7FFF;
其次,C代码的等效表达式是:

t = t << 31;
t = t >> 31;
t=t>31;

sall/sarl组合不等同于和0x7FFF。因为这是一个算术移位(与逻辑移位相反),所以当右移时,它用符号位的副本填充位。因此,如果eax在最左边的位中有零,它将变为零,如果有一个,它将变为0xFFFFFF

SALL行将寄存器几乎一直向左移动。最右边(第0位)变为最左边(第31位,也称为符号位)。然后向右移位将最左边的位移回最右边的位置,用其副本填充移位后的位


只要将t声明为带符号的数据类型(
int
默认情况下是带符号的),右组合就相当于。移动无符号数据类型不会对扩展进行签名;在汇编级别上,这是SHRL命令。

我很确定它们是不等效的……如果根据指令集进行旋转,它可能看起来像这样,但需要更多的指令来进行缩减。不要依赖“等效的C表达式”,这样的移位是未定义的行为。
sarl
是一种算术右移,因此复制符号位。因此,这并不等同于
&1
。在C中,有符号整数类型的符号位的移入和移出是未定义的行为。“
”组合不是等效的,它对于32位int是未定义的。请举出一个无法按预期工作的x86实现。:)如果这个行为不成立,C根本没有算术移位,整个问题也没有答案。