【发布时间】:2023-04-09 09:08:01
【问题描述】:
假设 AX 包含一个介于 0 和 15 之间的数字。现在必须对 BX 中的“AXth”位进行补码。
例如,AX 包含值6,则 BX 中的第 6 位应补码。
我怎样才能做到这一点?
【问题讨论】:
标签: assembly x86 bit-manipulation x86-16
假设 AX 包含一个介于 0 和 15 之间的数字。现在必须对 BX 中的“AXth”位进行补码。
例如,AX 包含值6,则 BX 中的第 6 位应补码。
我怎样才能做到这一点?
【问题讨论】:
标签: assembly x86 bit-manipulation x86-16
xor 操作非常适合此操作。
(英特尔语法中的所有代码。)
mov cl, al
将位的索引移动到cl; 8086 支持shl 一位或cl 位。
mov ax, 01h
设置ax 的第一位,同时清除所有其他位。
shl ax, cl
将设置位左移;在ax 中设置clth 位(如您的示例中的第6 位)。
xor bx, ax
补充(反转)bx 中的相应位。 xor 之所以有效是因为
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
请注意,对于 x86 处理器系列的后续处理器,有更短的变体可以实现这一点。
【讨论】:
您没有说过要支持 30 年前的硬件,所以我假设是现代 x86,即使您出于某种奇怪的原因在 16 位模式下对其进行编程。
btc bx, ax # bt / bts / btr / btc were new with 80386
它将bx & (1<<ax)的原始值存储到进位标志中,因此助记符:Bit Test and Complement。
此指令在使用内存操作数时速度较慢,但 btc reg, reg 和 btc reg, imm8 形式的单周期延迟和每时钟 2 个吞吐量。 (英特尔 Sandybridge 系列)。
内存操作数形式类似于bt insn,具有疯狂的 CISC 语义,将内存视为从给定地址开始的位串。因此,不是仅使用给定地址的 8 / 16 / 32 位值进行测试,高位位置实际上会影响不同字节中的位。为了处理这个古怪的要求,最近的英特尔设计将bt/btc mem, r 从微码解码为 10 uop,吞吐量为每 5 个时钟 1 个。 bt/r/s/c m,i 解码为 3 uop(或 2,对于仅读取的 bt),因此在位域中测试已知位置并不可怕。如果位位置可变,则分两步加载bt 寄存器会更快。
【讨论】: