05-26-2020, 11:30 AM
左移和右移是常见的运算,如果过量移位或发生什么?
我今天写模拟器的时候,模拟的程序有一个对32位整数进行右移32位的操作,结果我的模拟器模拟出来是没有移位。
于是我在自己的机器上测试了一下对 uint32_t 右移 32 位,结果果然是相当于没有移位,而右移 33 位相当于右移 1 位。反汇编程序发现用的就是 shr 指令,没什么特别的。
其实 Intel 的文档已经说明白了:
就是说对一个 32 位整数进行移位,移位的位数只有低 5 位有效,所以 X86 的 shr 的行为就是我测试中表现的那样。
当然了,对 C 来说,因为过量移位的行为在不同的 ISA 下可能是不同的,因此算做未定义行为。UBSAN 可以在运行时查出来。
我今天写模拟器的时候,模拟的程序有一个对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 可以在运行时查出来。