补第i位

Complementing ith bit

假设AX包含0到15之间的数字。现在BX中的"AXth"位必须被补充。
例如,AX 包含值 6 那么 BX 中的第 6 位应该被补。

我怎样才能做到这一点?

xor 操作非常适合。

(所有代码均采用 Intel 语法。)

mov cl, al

将该位的索引移动到 cl; 8086 支持 shl 一位或 cl 位。

mov ax, 01h

设置 ax 的第一位,同时清除所有其他位。

shl ax, cl

将设置的位左移;在 ax 中设置第 cl 位(如您的示例中的第 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)的原始值存储到进位标志中,因此助记符:位测试和补码。

此指令对于内存操作数来说很慢,但在 btc reg, regbtc reg, imm8 形式中具有单周期延迟和每时钟 2 个吞吐量。 (英特尔 Sandybridge 系列)。

内存操作数形式类似于 bt insn,具有疯狂的 CISC 语义,将内存视为从给定地址开始的位串。因此,不仅仅是在给定地址处使用 8 / 16 / 32 位值进行测试,高位位置实际上会影响不同字节中的位。为了处理这个古怪的要求,最近的 Intel 设计从微码解码 bt/btc mem, r 到 10 微指令,吞吐量为每 5 个时钟一个。 bt/r/s/c m,i 解码为 3 微指令(或 2,对于仅读取的 bt),因此测试位域中的已知位置并不可怕。如果位位置可变,那么 bt 分两步加载寄存器会更快。