Intel的移位指令存在的坑
2016-04-22 14:56
232 查看
前几天在调路由下发的时候碰到一个很诡异的错误,计算机执行的结果跟我手算的结果就是对不到一块儿,当时的代码是这样的
其中prefix_len的值为32。自己预想的结果应该是右移32bit让括号内变为0,然后在取反变成全1,最后调整调整字节序后结果也是全为1。但是很无奈,计算机算出来的结果就是0。
在纠结了半小时,突然想到以前看过一篇关于Intel的移位指令存在的缺陷的文章,http://blog.chinaunix.net/uid-23629988-id-127318.html这是文章的链接。这篇文章写了右移指令在碰到计数操作数大于31时就会发生意料之外的结果,在这里我想说不仅仅是右移有这个问题,左移同样存在这个问题。
下面这段代码是我的测试代码:
通过gcc编译产生一个可执行文件,执行的结果是:
当把prefix_len改为0-31时,移位是正常的,如:
咱们在来试试prefix_len=33和prefix_len=1的情况,
先是=33:
然后是=1:
所以以后在试用移位指令的时候自己多留个心眼吧,别超范围了。
ina.ifra_mask.sin_addr.s_addr = htonl(~(0xffffffffU >> prefix_len));
其中prefix_len的值为32。自己预想的结果应该是右移32bit让括号内变为0,然后在取反变成全1,最后调整调整字节序后结果也是全为1。但是很无奈,计算机算出来的结果就是0。
在纠结了半小时,突然想到以前看过一篇关于Intel的移位指令存在的缺陷的文章,http://blog.chinaunix.net/uid-23629988-id-127318.html这是文章的链接。这篇文章写了右移指令在碰到计数操作数大于31时就会发生意料之外的结果,在这里我想说不仅仅是右移有这个问题,左移同样存在这个问题。
下面这段代码是我的测试代码:
int prefix_len = 32; int y = htonl(~(0xffffffffU >> prefix_len)); printf("y is %x\n", y);
通过gcc编译产生一个可执行文件,执行的结果是:
当把prefix_len改为0-31时,移位是正常的,如:
咱们在来试试prefix_len=33和prefix_len=1的情况,
先是=33:
然后是=1:
所以以后在试用移位指令的时候自己多留个心眼吧,别超范围了。
相关文章推荐
- ListBox实现上移,下移,左移,右移的简单实例
- C语言中的左移与右移
- java的左移和循环左移的实现(右类似)
- 将数组中的所有元素依次循环右移k个位置
- 无符号右移,左移,右移操作
- 循环左移字符串
- 有关位运算的笔记
- 字符串循环右移
- 算法习题48:一个数组是由一个递减数列左移若干位形成的,在这种数组中查找某一个数。
- 位运算符
- 位运算
- C语言左移右移
- 无符号和有符号数的二进制数右移
- 将一个select中的内容移动到另一个select中
- 左移右移小总结
- 微机原理--第三章(6)移位指令
- 字符串循环左移问题
- C语言小知识点 汇总1
- 右移运算符总结
- Bestcoder Pro.ID 2001 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离。