Assuming AX contains a number between 0 and 15. Now the "AXth" bit in BX has to be complemented.
For example, AX contains the value 6
then the 6th bit in BX should be complemented.
How can I achieve that?
Assuming AX contains a number between 0 and 15. Now the "AXth" bit in BX has to be complemented.
For example, AX contains the value 6
then the 6th bit in BX should be complemented.
How can I achieve that?
The xor
operation is neatly fitted for that.
(All code in Intel syntax.)
mov cl, al
Moves the bit's index to cl
; the 8086 supports either shl
by one bit or by cl
bits.
mov ax, 01h
Sets first bit of ax
while clearing all other bits.
shl ax, cl
Shift the set bit to the left; sets the cl
th bit in ax
(as in your example, the 6th bit).
xor bx, ax
Complements (inverts) the corresponding bit in bx
. xor
works because
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
Note that for later processors of the x86 processor line there are shorter variants in order to accomplish that.
You didn't say anything about wanting to support hardware from 30 years ago, so I'll assume a modern x86, even if you're programming it in 16bit mode for some strange reason.
btc bx, ax # bt / bts / btr / btc were new with 80386
It stores the original value of bx & (1<<ax)
into the carry flag, hence the mnemonic: Bit Test and Complement.
This instruction is slow with a memory operand, but single-cycle latency and 2-per-clock throughput in the btc reg, reg
and btc reg, imm8
forms. (Intel Sandybridge family).
The memory-operand forms are like the bt
insn, with crazy CISC semantics that treat memory as a bit-string starting at the given address. So instead of just testing with the 8 / 16 / 32bit value at the given address, a high bit-position will actually affect a bit in a different byte. To handle this wacky requirement, recent Intel designs decode bt/btc mem, r
to 10 uops from microcode, with a throughput of one per 5 clocks. bt/r/s/c m,i
decodes to 3 uops (or 2, for bt
that only reads), so it's not terrible for testing a known position in a bitfield. It's faster to load an then bt
the register in 2 steps if the bit position is variable.