x86 中的 BEXTR 指令是如何工作的
Posted
技术标签:
【中文标题】x86 中的 BEXTR 指令是如何工作的【英文标题】:How does the BEXTR instruction in x86 work 【发布时间】: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。
【参考方案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。
【讨论】:
以上是关于x86 中的 BEXTR 指令是如何工作的的主要内容,如果未能解决你的问题,请参考以下文章