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

标签 assembly x86

假设我在 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在不更改其他寄存器的情况下(不计算 ripeflags ,因为那将是 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/

相关文章:

c++ - 如何用C++给定的地址覆盖汇编程序栈的返回地址?

c++ - 奇怪的 C++ 链表错误

assembly - 无法在 Linux NASM 中打印单个字符

c++ - 无法在 Visual Studio 中构建汇编语言程序

winapi - 错误 LNK2001 : unresolved external symbol _MessageBox

vim - 汇编vim语法高亮

string - dw 和 dd 与字符串的 db 指令有何不同?

assembly - NASM 汇编器 - 生成的机器代码中不需要的 66

assembly - 如何在没有 c 库中的 printf 的情况下在汇编级编程中打印整数? (itoa,整数到十进制的 ASCII 字符串)

x86 - x86 架构中的根联合体与系统代理是什么?