我们说我在AL中有这个字节:01100001
应用镜像函数后,我希望字节为10000110
。
我提出的所有想法都必须使用其他寄存器,但我很好奇是否有办法镜像一个字节而不使用任何其他寄存器?
答案 0 :(得分:10)
“通过代码立即存储”变体:
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
翻转它们来实现。
在我将所有这些想法训练合并到单一解决方案之后,我得到了上面几乎所有的东西,然后我稍微清理了一下(就像弄清楚“两位相同”测试可以简化为单{{1} }}并验证它有效。
但是,无论什么时候有疑问,只记得图灵机如何工作:)))(半开玩笑,我真的不想在图灵机器式语言中编写任何中型算法,即使很短的也可能在习惯复杂的机器/语言(例如x86或C ++)之后很烦人。但是在基础级别验证任务仍然很好,这是否有意义。)