按位运算符(x86 程序集):二进制数据的其余部分在移位时去了哪里?
Bitwise operators (x86 Assembly): Where does the rest of the binary data go when shifting it?
我知道当我执行下面这行汇编 x86 代码时:
shrl , %eax
如果EAX有如下32位数据:
10000010000000000000000000000000
然后执行命令 shrl , %eax
结果:
00000000000000000000000000000001
但是,其他位 (000001
) 去了哪里?它们在内存中的确切位置?
这些位被丢弃,因为这就是将它们移出的意思,这就是您要求机器执行的操作。就像在 C 中一样,u32_var >>= 31;
不会神奇地更新一些其他位置并移出位。
如果你想让他们去某个地方,使用 shrd
(2 寄存器移位,虽然它只更新一个寄存器。要像 >>= 31
那样做一个 uint64_t
移位一对 32 位寄存器 (EDX:EAX),你需要 shrd , %edx, %eax
/ shr , %eax
)
移位寄存器会导致存储到内存的原因为零,这将是一个疯狂的设计。即使将它们转移到某个临时寄存器中也会很奇怪,并且需要更宽的桶形移位器才能有效地实现移位。 (x86 需要 shrd
,但其他带有移位指令的 ISA 并不总是具有双精度移位。当然,8086 没有 386 shrd,但它也没有桶形移位器:每个班次计数需要一个额外的周期。)
x86指令并非都是可逆的。许多(如超过 1 的班次)丢弃了一些信息。您可以很容易地询问在 sub %eax, %eax
或 xor %eax, %eax
将寄存器归零之后,或者在 or $-1, %eax
将其设置为全一之后这些位去了哪里。有些像 not
、neg
或 xor
(使用不同的寄存器)通过重复可逆,或者 add
/ sub
通过执行另一个可逆。 (不过,仍在销毁旧的 FLAGS。)
Shifts在CF中留下最后一个移出的位,因此它们总是破坏CF的旧内容(除非移位计数为0,则FLAGS未被修改。x86是这样CISC 它很痛。这就是为什么可变计数移位在 Intel CPU 上花费 3 微指令。>.<)
移位 1 会保留输入寄存器的所有原始位,并且可以通过另一个方向的循环进位(rcl
或 rcr
)撤消。
相关:https://en.wikipedia.org/wiki/Reversible_computing - information theory and thermodynamics. Specifically the Logical reversibility 部分讨论了如何在不丢弃任何位的情况下进行计算。
当然,我们目前的硅数字逻辑技术使用的功率远远超过信息理论的最小值,即使它们在计算过程中破坏的信息量也是如此(按 许多 命令量级)。因此,您选择的指令是否销毁信息与功耗完全无关。
我知道当我执行下面这行汇编 x86 代码时:
shrl , %eax
如果EAX有如下32位数据:
10000010000000000000000000000000
然后执行命令 shrl , %eax
结果:
00000000000000000000000000000001
但是,其他位 (000001
) 去了哪里?它们在内存中的确切位置?
这些位被丢弃,因为这就是将它们移出的意思,这就是您要求机器执行的操作。就像在 C 中一样,u32_var >>= 31;
不会神奇地更新一些其他位置并移出位。
如果你想让他们去某个地方,使用 shrd
(2 寄存器移位,虽然它只更新一个寄存器。要像 >>= 31
那样做一个 uint64_t
移位一对 32 位寄存器 (EDX:EAX),你需要 shrd , %edx, %eax
/ shr , %eax
)
移位寄存器会导致存储到内存的原因为零,这将是一个疯狂的设计。即使将它们转移到某个临时寄存器中也会很奇怪,并且需要更宽的桶形移位器才能有效地实现移位。 (x86 需要 shrd
,但其他带有移位指令的 ISA 并不总是具有双精度移位。当然,8086 没有 386 shrd,但它也没有桶形移位器:每个班次计数需要一个额外的周期。)
x86指令并非都是可逆的。许多(如超过 1 的班次)丢弃了一些信息。您可以很容易地询问在 sub %eax, %eax
或 xor %eax, %eax
将寄存器归零之后,或者在 or $-1, %eax
将其设置为全一之后这些位去了哪里。有些像 not
、neg
或 xor
(使用不同的寄存器)通过重复可逆,或者 add
/ sub
通过执行另一个可逆。 (不过,仍在销毁旧的 FLAGS。)
Shifts在CF中留下最后一个移出的位,因此它们总是破坏CF的旧内容(除非移位计数为0,则FLAGS未被修改。x86是这样CISC 它很痛。这就是为什么可变计数移位在 Intel CPU 上花费 3 微指令。>.<)
移位 1 会保留输入寄存器的所有原始位,并且可以通过另一个方向的循环进位(rcl
或 rcr
)撤消。
相关:https://en.wikipedia.org/wiki/Reversible_computing - information theory and thermodynamics. Specifically the Logical reversibility 部分讨论了如何在不丢弃任何位的情况下进行计算。
当然,我们目前的硅数字逻辑技术使用的功率远远超过信息理论的最小值,即使它们在计算过程中破坏的信息量也是如此(按 许多 命令量级)。因此,您选择的指令是否销毁信息与功耗完全无关。