Boolean logical instructions
CPU status flags:
Boolean
instructions affect the Zero, Carry, Sign, Overflow, and Parity flags. Here’s a
quick review of their meanings:
• The Zero flag is set when the result of an operation equals zero.
• The Zero flag is set when the result of an operation equals zero.
The Carry flag
is set when an operation generates a carry out of the highest bit of the
destination operand.
• The Sign
flag is a copy of the high bit of the destination operand, indicating that it
is negative if set and positive if clear. (Zero is assumed to be positive.)
• The Overflow
flag is set when an instruction generates a result that is outside the signed
range of the destination operand.
• The Parity
flag is set when an instruction generates an even number of 1 bit in the low
byte of the destination operand.
AND instruction
The AND instruction performs a Boolean
(bitwise) AND operation between each pair of matching bits in two operands and
places the result in the destination operand:
AND destination, source
The following operand combinations are
permitted
AND reg,reg
AND reg,mem
AND reg,imm
AND mem,reg
AND mem,imm
The operands can be 8 or 16 bits, and they must be the same size. For each matching bit in the two operands, the following rule applies: If both bits equal 1, the result bit is 1; otherwise, it is 0. The following truth table from Chapter 1 labels the input bits’ x and y. The third column shows the value of the expression x ∧ y:
AND reg,mem
AND reg,imm
AND mem,reg
AND mem,imm
The operands can be 8 or 16 bits, and they must be the same size. For each matching bit in the two operands, the following rule applies: If both bits equal 1, the result bit is 1; otherwise, it is 0. The following truth table from Chapter 1 labels the input bits’ x and y. The third column shows the value of the expression x ∧ y:
The AND
instruction lets you clear 1 or more bits in an operand without affecting other
bits. The technique is called bit masking, much as you might use masking tape
when painting a house to cover areas (such as windows) that should not be
painted. Suppose, for example, that a control byte is about to be copied from
the AL register to a hardware device. Further, we will assume that the device
resets itself when bits 0 and 3 are cleared in the control byte. Assuming that
we want to reset the device without modifying any other bits in AL, we can
write the following:
and AL,11110110 b; clear bits 0 and 3, leave others
unchanged
For example, suppose AL is
initially set to 10101110 binaries. After ANDing it with 11110110, AL equals
10100110:
mov al,10101110b
and al,11110110b; result in AL = 10100110
Flags
The AND instruction always clears
the Overflow and Carry flags. It modifies the Sign, Zero, and Parity flags in a
way that is consistent with the value assigned to the destination operand. For
example, suppose the following instruction results in a value of Zero in the AX
register. In that case, the Zero flag will be set:
and ax,1Fh
Converting Characters to Upper case
The AND instruction provides an
easy way to translate a letter from lowercase to uppercase. If we compare the
ASCII codes of capital A and lowercase a, it becomes clear that only bit 5 is different:
0 1 1 0 0 0 0 1 = 61h ('a')
0 1 0 0 0 0 0 1 = 41h ('A')
The rest of the alphabetic characters have the same relationship. If we AND any character with 11011111 binary, all bits are unchanged except for bit 5, which is cleared.
OR instruction
The OR
instruction performs a Boolean OR operation between each pair of matching bits
in two operands and places the result in the destination operand:
OR destination, source
The OR instruction uses the same operand combinations as the
AND instruction:
OR reg, reg
OR reg, mem
OR reg, immediate
OR mem, reg
OR mem, immediate
The operands can
be 8 or 16 bits, and they must be the same size. For each matching bit in the
two operands, the output bit is 1 when at least one of the input bits is 1. The
following truth table describes the Boolean expression x ∨
y:
The OR
instruction is particularly useful when you need to set 1 or more bits in an
operand without affecting any other bits. Suppose, for example, that your
computer is attached to a servo motor, which is activated by setting bit 2 in
its control byte. Assuming that the AL register contains a control byte in which
each bit contains some important information, the following code only sets the
bit in position 2:
or AL,00000100b; set bit 2, leave others unchanged
For example, if AL is initially equal to 11100011 binary and
then we OR it with 00000100, the
result equals 11100111:
mov al,11100011b
or al,00000100b; result in AL = 11100111
Flags
The OR
instruction always clears the Carry and Overflow flags. It modifies the Sign, Zero,
and Parity flags in a way that is consistent with the value assigned to the
destination operand.
For example,
you can OR a number with itself (or zero) to obtain certain information about its
value:
or al, al
or al, al
XOR destination, source
The XOR
instruction performs a Boolean exclusive-OR operation between each pair of
matching bits in two operands and stores the result in the destination operand:
XOR destination,
source
The XOR
instruction uses the same operand combinations and sizes as the AND and OR instructions.
For each matching bit in the two operands, the following applies: If both bits
are the same (both 0 or both 1), the result is 0; otherwise, the result is 1.
The following truth table describes the Boolean expression x ⊕
y:
A bit exclusive-ORed with 0 retains its value, and a bit
exclusive-ORed with 1 is toggled (complemented). XOR reverses itself when
applied twice to the same operand. The following truth table shows that when
bit x is exclusive-ORed with bit y twice, it reverts to its original value:
As you will find
out in Section 6.3.4, this “reversible” property of XOR makes it an ideal tool
for a simple form of symmetric encryption.
Flags
The XOR instruction always clears the Overflow and Carry flags. XOR modifies
the Sign, Zero, and Parity flags in a way that is consistent with the value
assigned to the destination operand.
Checking the
Parity Flag Parity checking is a function performed on a binary number that
counts the number of 1 bits contained in the number; if the resulting count is
even, we say that the data has even parity; if the count is odd, the data has
odd parity. In x86 processors, the Parity flag is set when the lowest byte of
the destination operand of a bitwise or arithmetic operation has even parity.
Conversely, when the operand has odd parity, the flag is cleared. An effective
way to check the parity of a number without changing its value is to
exclusive-OR the number with zero:
mov al,10110101b; 5 bits = odd parity
xor al,0; Parity flag clear (odd)
mov al,11001100b; 4 bits = even parity
xor al,0; Parity flag set (even)
NOT destination
The NOT instruction toggles (inverts) all bits in an operand.
The result is called the one’s complement. The following operand types are
permitted:
NOT reg
NOT mem
For example, the one’s complement of F0h is 0Fh:
mov al,11110000b
not al ; AL = 00001111b
Flags No flags are affected by the NOT instruction.
NOT reg
NOT mem
For example, the one’s complement of F0h is 0Fh:
mov al,11110000b
not al ; AL = 00001111b
Flags No flags are affected by the NOT instruction.
Test destination, source
The TEST
instruction performs an implied AND operation between each pair of matching
bits in two operands and sets the Sign, Zero, and Parity flags based on the
value assigned to the destination operand. The only difference between TEST and
AND is that TEST does not modify the destination operand. The TEST instruction
permits the same operand combinations as the AND instruction. TEST is
particularly valuable for finding out whether individual bits in an operand are
set.
Example: Testing
Multiple Bits The TEST instruction can check several bits at once. Suppose we
want to know whether bit 0 or bit 3 is set in the AL register. We can use the
following
instruction to find this out:
test al,00001001b; test bits 0 and 3
(The value 00001001 in this example is called a bit mask.)
From the following example data sets, we can infer that the Zero flag is set only when all tested bits are clear:
From the following example data sets, we can infer that the Zero flag is set only when all tested bits are clear:
0 0 1 0 0 1 0 1 <- input value
0 0 0 0 1 0 0 1 <- test value
0 0 0 0 0 0 0 1 <- result: ZF = 0
0 0 1 0 0 1 0 0 <- input value
0 0 0 0 1 0 0 1 <- test value
0 0 0 0 0 0 0 0 <- result: ZF = 1
Flags The TEST instruction always clears the
Overflow and Carry flags. It modifies the Sign, Zero, and Parity flags in the
same way as the AND instruction.
No comments:
Post a Comment