【问题标题】:How does the BEXTR instruction in x86 workx86 中的 BEXTR 指令是如何工作的
【发布时间】:2022-01-09 11:50:38
【问题描述】:

正如标题中提到的,我在 x86 程序集上遇到了 BEXTR(位提取)指令,但我似乎无法理解它是如何工作的。

在网上找了一段时间后,我什至发现了一个假定的 C 等效 (src >> start) & ((1 << len) -1),我似乎也无法理解。

谁能向我解释 BEXTR 指令的工作原理?比特是如何提取的?

【问题讨论】:

  • 这个公式几乎说明了它的作用。它从start 开始提取源的length 位。
  • 如果您不理解移位和掩码等价物,也许英特尔手册的位范围表示法会有所帮助:felixcloutier.com/x86/bextr。但实际上你应该学习基本的位操作,比如 2 的幂减一 => 位掩码。有关介绍,请参阅catonmat.net/low-level-bit-hacks

标签: assembly x86 bit-manipulation


【解决方案1】:

比特是如何提取的?

我们真的不需要知道这些位是如何提取的,因为这可能因实现而异。我们只需要知道提取了哪些位。

一般来说,位域是位域之前和之后可能被不需要的位包围的连续位集。因此,我们的想法是删除那些不需要的位,并将感兴趣的位域的顺序位移动到右对齐。

C 公式分解成如下组件:

首先,src >> start 将位 start 移动到位位置 0,有效地右对齐感兴趣的位字段。这既将感兴趣的位域移动到正确的右对齐位置,也消除了不感兴趣的较低位(重要性较低的位,即低于所需的位域)。

剩下要做的就是从length 上方去除任何不需要的位。为此,该公式创建了我们所说的掩码。首先,1<<len 通过将 1(2 的最低幂)向左移动来生成 2 的幂。因此,数字看起来像 1 后跟 len 零个数(例如,对于 len=3,然后是 ..001000)。从 2 的幂中减去 1 会得到一个连续 1 的掩码(例如 001000-1=000111),这里的计数为 len 位为 1。该掩码应用于移位结果,以删除不在感兴趣的位字段中的任何不需要的高位(具有较高重要性的位)。


C 中的另一种方法是左移左对齐位域,然后右移右对齐位域。这种移位消除了任何不需要的高位和低位,同时使位域右对齐,因为这是最后一次移位。这种方法还可以提取有符号和无符号位字段,方法是进行右移算术与逻辑运算。

【讨论】:

    【解决方案2】:

    图片可能会有所帮助。假设起始位为 5,长度为 9。那么如果我们有

    Input : 11010010001110101010110011011010 = 0xd23aacda
                              |-------|
                                  \
                                   \
                                    \
                                     v
                                   |-------|
    Output: 00000000000000000000000101100110 = 0x00000166
    

    所需的位块进入输出的最低有效位,输出的其余位变为 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 2012-05-27
      • 2019-06-20
      相关资源
      最近更新 更多