在程序集x86中交换位(或只是访问它们)

时间:2016-04-19 07:46:07

标签: assembly x86

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

确切的问题是:

  

写一个函数来交换整数中的奇数和偶数位   尽可能多的指令(​​例如,位0和位1交换,位2和   第3位被交换,依此类推。)

它还暗示不需要条件陈述。

我有点调查它,我发现如果我以某种方式将偶数和奇数位分开,我可以使用移位来完成此操作。我不明白的是如何操纵个别位。在python(我习惯的编程语言)中,使用索引运算符很容易,因为你可以使用数字[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还是||。愚蠢的错误。

2 个答案:

答案 0 :(得分:4)

在汇编中,可以使用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

其中&是按位AND运算,|是按位OR运算,<<>>分别是向左移位和向右移位运算。< / p>

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

答案 1 :(得分:1)

以下是一些提示:

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

    • 按位AND:0b10110101&amp; 0b00011000→0b00010000
    • 按位OR:0b10110101&amp; 0b00011000→0b10111101
    • 按位XOR:0b10110101&amp; 0b00011000→0b10101101
  • 位移

    • 向左移位x位(x
    • 向右移位x位(x>&gt; n):0b00100001&gt;&gt; 3→0b00000100

还有旋转位移,其中位&#34;移出&#34;出现在另一边,但硬件并没有广泛支持。