如何在不使用其他寄存器的情况下镜像字节?

时间:2017-02-15 09:23:31

标签: assembly x86

我们说我在AL中有这个字节:01100001 应用镜像函数后,我希望字节为10000110

我提出的所有想法都必须使用其他寄存器,但我很好奇是否有办法镜像一个字节而不使用任何其他寄存器?

1 个答案:

答案 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而不改变其他寄存器(不计算ripeflags,因为那将是99%完全不可能),你需要“借”这个在其他地方多了一点。

由于数字计算机是类似图灵的机器,您可以通过使用代码指令位来交换寄存器/存储器中的缺失位,因此理论上可以使用=> QED。

在对问题进行基本的“验证”之后,问题就在于找出,什么样的代码结构确实提供额外的信息位存储和交换位。

最直接的野蛮方式是每比特值分支,即。 test al,0x01 jz bit_0_clear ; else bit_0_set branch follows(每个分支都可以对目标位进行正确的设置/重置,使其看起来像是交换了它们)...我不敢写这样的完整代码(太长,太乏味),但这是上述解决方案的一个根源。

解决方案的另一个根源是将这个代码理念与“必须真正完成”的内容相对应,即“在特定位置上交换位”。但是,当位已经具有相同的值=无需交换时,可以优化出来。并且当它们不同时“交换”两个位可以通过简单的xor翻转它们来实现。

在我将所有这些想法训练合并到单一解决方案之后,我得到了上面几乎所有的东西,然后我稍微清理了一下(就像弄清楚“两位相同”测试可以简化为单{{1} }}并验证它有效。

但是,无论什么时候有疑问,只记得图灵机如何工作:)))(半开玩笑,我真的不想在图灵机器式语言中编写任何中型算法,即使很短的也可能在习惯复杂的机器/语言(例如x86或C ++)之后很烦人。但是在基础级别验证任务仍然很好,这是否有意义。)