WeHack BBS
未定义行为之过量移位 - 可打印的版本

+- WeHack BBS (https://bbs.wehack.space)
+-- 版块: 计算机技术 (https://bbs.wehack.space/forum-5.html)
+--- 版块: 程序设计讨论区 (https://bbs.wehack.space/forum-14.html)
+--- 主题: 未定义行为之过量移位 (/thread-163.html)



未定义行为之过量移位 - vimacs - 05-26-2020

左移和右移是常见的运算,如果过量移位或发生什么?

我今天写模拟器的时候,模拟的程序有一个对32位整数进行右移32位的操作,结果我的模拟器模拟出来是没有移位。

于是我在自己的机器上测试了一下对 uint32_t 右移 32 位,结果果然是相当于没有移位,而右移 33 位相当于右移 1 位。反汇编程序发现用的就是 shr 指令,没什么特别的。

其实 Intel 的文档已经说明白了:

引用:The destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used). A special opcode encoding is provided for a count of 1.


就是说对一个 32 位整数进行移位,移位的位数只有低 5 位有效,所以 X86 的 shr 的行为就是我测试中表现的那样。

当然了,对 C 来说,因为过量移位的行为在不同的 ISA 下可能是不同的,因此算做未定义行为。UBSAN 可以在运行时查出来。


RE: 未定义行为之过量移位 - vimacs - 06-17-2021

C标准里面关于移位的未定义行为还有一条:有符号数左移结果不在数据类型的可表示范围内。例如 (1 << 31) 的结果 2^31 不在 int 的范围内,所以是未定义行为。