【问题标题】:How to mirror a byte without using other registers?如何在不使用其他寄存器的情况下镜像一个字节?
【发布时间】:2017-02-15 09:23:31
【问题描述】:

假设我在 AL 中有这个字节:01100001 应用 mirror 函数后,我希望字节为10000110

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

【问题讨论】:

  • 当您说“其他寄存器”时,您是否包括 AH、AX、EAX 和 RAX 作为其他寄存器? - 我认为这可能需要几个操作(除非BSWAP AL 有效?)但由于您只使用单个字节,您可以使用 AH 存储来自 AL 的操作结果,从而充分利用单个寄存器(斧头)
  • @series0ne OP 说反转位,而不是反转字节
  • 您基本上有两种主要方式......要么从额外的代码指令中“借出”存储空间,用指令中编码的立即值替换“其他寄存器”,或者您可以使用进位标志(或其他标志)用于存储空间。起初我认为有一些 ROL/RCR 的组合可以优雅地利用 CF,但经过短暂的思考,到目前为止我一直没有想到,虽然直接的变体有点明显,但编写起来很乏味(很多代码行)。无论如何,你肯定必须有至少 1 位的额外存储空间,如果没有第三个没有“交换”指令,你就不能交换两位。
  • 哦,当然 256 字节长的 LUT(查找表)也可以工作...... :D 我怎么忘了提到这个...... :)))(基本在 8 位时代“计算”任何东西的方法)

标签: assembly x86


【解决方案1】:

“代码立即存储”变体:

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翻转它们来实现。

在我将所有这些idea-trains 合并到单个解决方案之后,我几乎得到了上面的内容,然后我只是稍微清理了一下(比如弄清楚“两位相同”的测试可以简化为单个test + jpe ) 并验证它有效。

但每当有疑问时,请记住图灵机的工作原理 :)))(半开玩笑,我真的不想用类似图灵机的语言编写任何中等规模的算法,即使是简短的也可能习惯了 x86 或 C++ 之类的复杂机器/语言后很烦人。但在基础级别验证任务仍然很好,无论在图灵方面是否有意义)。

【讨论】:

  • 漂亮,我不经常看到奇偶标志在起作用
  • 真正优雅的解决方案
  • 感谢您的详细解答。太棒了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2017-04-09
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
相关资源
最近更新 更多