【问题标题】:Swap bits (or just access them) in assembly x86在汇编 x86 中交换位(或仅访问它们)
【发布时间】:2016-04-19 07:46:07
【问题描述】:

我要发表免责声明,说这是我的作业问题。所以我不一定要你解决它,我只是想澄清一下。

确切的问题是这样的:

编写一个函数,用最少的整数交换奇数位和偶数位 尽可能的指令(例如,位 0 和位 1 交换,位 2 和 位 3 被交换,依此类推)。

它还暗示不需要条件语句。

我进行了一番调查,发现如果我以某种方式将偶数位和奇数位分开,我可以使用移位来完成此操作。我不明白的是如何操作单个位。在 python(我习惯使用的编程语言)中,使用索引运算符很容易,因为您可以只执行 number[0],例如,您可以获得第一位。你如何为装配做这样的事情?

编辑: 所以@jotik,谢谢你的帮助。我实现了这样的东西:

mov edi, ebx
and edi, 0x5555555555555555
shl edi, 1
mov esi, ebx
and esi, 0xAAAAAAAAAAAAAAAA
shr esi, 1
or edi, esi
mov eax, edi

当我看到 |运算符,我在想 OR 是 ||。愚蠢的错误。

【问题讨论】:

  • 您需要的一切都在这里:en.wikipedia.org/wiki/Bitwise_operations_in_C。转换为 asm 很简单。
  • Stack Overflow 是一个 问答 网站,因此请从 question 中删除您的解决方案并将其发布为正确的answer i>.
  • 哪个32位寄存器可以存储0x5555555555555555这样的数字?

标签: assembly x86


【解决方案1】:

在汇编中可以使用bit masks 和其他bitwise operations 来存档您的结果。

result = ((odd-bit-mask & input) << 1) | ((even-bit-mask & input) >> 1)

其中odd-bit-mask 是一个所有奇数位都已设置 (1) 且偶数位未设置 (0) 的值; even-bit-mask 是一个所有偶数位都已设置 (1) 且奇数位未设置的值。对于 64 位值,奇数位掩码和偶数位掩码将分别为(以十六进制表示)0x0x55555555555555550xAAAAAAAAAAAAAAAA

因此,您的汇编算法的伪代码可能类似于以下内容:

oddbits  = input & 0x5555555555555555
oddbits  = oddbits << 1
evenbits = input & 0xAAAAAAAAAAAAAAAA
evenbits = evenbits >> 1
result   = oddbits | evenbits

其中&amp; 是按位与运算,| 是按位或运算,&lt;&lt;&gt;&gt; 分别是按位左移和按位右移。

PS:您可以在 Sean Eron Anderson 的 Bit Twiddling Hacks 网页上找到其他一些有用的位操作技巧。

【讨论】:

  • 好的,我看到了类似的东西,但那到底是什么?以及如何在汇编中实现它?作为旁注,|运算符只是神奇地将偶数位和奇数位按正确的顺序排列?
  • @user1157549 您在询问有关编程的非常基本的问题。这可以在介绍性书籍中找到,并且很可能在您学校的第一堂课中教授。当然,这些不是魔术运算符,而是位移位和按位逻辑运算符。为了理解它们,您可能需要在互联网上进行更多研究,并尝试在纸上解决一些练习。这些运算符对于硅计算机来说是非常自然的,并且在几乎任何组装中都有直接的类似物。
  • 在按位移位之前,偶数位与输入异或奇数位相同,这是一条较小的指令。无论如何,我认为您可以仅使用 ebx 和 eax 将其减少到最多 6 条指令,因为 ebx 不必保持不变。
【解决方案2】:

这里有一些提示:

  • 按位布尔运算(这些在汇编中通常具有 1:1 对应物,但如果其他一切都失败了,您可以通过巧妙地组合多个 XOR 调用来构造它们)

    • 按位与:0b10110101 & 0b00011000 → 0b00010000
    • 按位或:0b10110101 & 0b00011000 → 0b10111101
    • 按位异或:0b10110101 & 0b00011000 → 0b10101101
  • 位移

    • 将 x 向左移动 n 位 (x
    • 将 x 向右移动 n 位 (x >> n):0b00100001 >> 3 → 0b00000100

还有旋转位移,其中“移出”的位出现在另一侧,但这在硬件中没有得到广泛支持。

【讨论】:

    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2011-02-15
    • 2017-12-26
    • 1970-01-01
    相关资源
    最近更新 更多