假设我在 AL 中有这个字节:01100001
申请后 镜子函数我希望字节为 10000110
.
我提出的所有想法都必须使用其他寄存器,但是我很好奇是否有一种方法可以在不使用任何其他寄存器的情况下镜像一个字节?
最佳答案
“在代码中立即存储”变体:
mirror_bits:
; handle bits 0 and 7
TEST al,0x81
JPE bits07same
XOR al,0x81
bits07same:
; handle bits 1 and 6
TEST al,0x42
JPE bits16same
XOR al,0x42
bits16same:
; handle bits 2 and 5
TEST al,0x24
JPE bits25same
XOR al,0x24
bits25same:
; handle bits 3 and 4
TEST al,0x18
JPE bits34same
XOR al,0x18
bits34same:
RET
编辑:关于我在问题下的评论和一般答案是否有办法。
你应该总是先问数学理论。在您的情况下,您正在确定性地将 8 位信息更改为其他 8 位信息结果,并且所需的最小修改步骤是“交换两位”,如果没有第三位临时存储,这是不可能的,所以您现在正在寻找一个无需额外寄存器即可补充临时存储的方法(我确实添加了“和内存”)。
因此,如果您想镜像
al
在不更改其他寄存器的情况下(不计算 rip
和 eflags
,因为那将是 99% 完全不可能的),您需要在其他地方“借用”这个额外的位。由于数字计算机是类似图灵的机器,您可以使用代码指令位交换寄存器/存储中丢失的位,因此理论上可以 => QED。
在问题的基本“验证”之后,只是找出什么样的代码结构确实提供了额外的信息位存储和交换位的问题。
最直接的残酷方法是对每个位值进行分支,即。
test al,0x01
jz bit_0_clear
; else bit_0_set branch follows
(然后每个分支都可以正确设置/重置目标位,使其看起来好像确实交换了它们)......我不敢写这样的完整代码(太长,太乏味),但这是上述解决方案的一个根源。解决方案的另一个根源是将此代码思想与“必须 真正 完成的事情”相对,即“在特定位置交换位”。但这可以优化,当位已经具有相同的值时=不需要交换。并且可以通过简单的
xor
来实现“交换”两个不同的位。翻转他们两个。在我将所有这些想法列车合并到单一解决方案后,我得到了上面的内容,然后我只是稍微清理了一下(就像弄清楚“两位相同”测试可以简化为单个
test + jpe
)并验证有用。但是每当有疑问时,只要记住图灵机的工作原理:)))(半开玩笑,我真的不想用类似图灵机的语言编写任何中等大小的算法,即使是一个简短的算法也可能会很烦人)用于复杂的机器/语言,如 x86 或 C++。但在基本级别验证任务仍然很好,无论它是否在图灵方面有意义)。
关于assembly - 如何在不使用其他寄存器的情况下镜像一个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42245263/