C语言右移操作在汇编层面的相关解释

在 CSDN 看到帖子回复如下:

x=y>>2;
004122A8  mov         eax,dword ptr [y] 
004122AB  sar         eax,2 '算术移位 
004122AE  mov         dword ptr [x],eax 
x=((unsigned int)y)>>2;
0041228D  mov         eax,dword ptr [y] 
00412290  shr         eax,2 '逻辑移位
00412293  mov         dword ptr [x],eax 
x=(0x0|y)>>2;
00412296  mov         eax,dword ptr [y] 
00412299  sar         eax,2 '算术移位
0041229C  mov         dword ptr [x],eax 
x=(0xFFFFFFFF&y)>>2;
0041229F  mov         eax,dword ptr [y] 
004122A2  shr         eax,2 '逻辑移位
004122A5  mov         dword ptr [x],eax 

故有人问,为何 x=(0x0|y)>>2; 是算术移位,而 x=(0xFFFFFFFF&y)>>2; 是逻辑移位。

实际上,不难看出当 0x0 | y 时,将产生与 y 相同的表达式值,所以 (0x0 | y) >> 2 和 y >> 2 一样都是算术移位(它们都是 int 数据类型,有符号)

而当 0xFFFFFFFF & y 时,无论 y 的值为多少,0xFFFFFFFF 这个字面值(只要 int 数据类型的字面值超过 0x7FFFFFFF)会被编译器当做无符号数处理,所以 & 运算将进行无符号数的按位与运算,也会产生一个无符号数的结果,故最终进行无符号的移位(逻辑移位)

对于,0xFFFFFFFF 这样的字面值,可以用以下方式验证

它将产生这样的编译错误:

这说明了,编译器的确将 0xFFFFFFFF 这个字面值当成了无符号类型。

以上。

原文地址:https://www.cnblogs.com/yenyuloong/p/10232942.html