Experiment 3 - Logical Operations
In this experiment, we will explore the Intel 8080's ability to perform bit-wise logic operations including NOT, OR, AND, and XOR (exclusive OR). Like the ADD/SUB group, logic operations are performed on the A register with the result in A. Also, as before, one operand is always in A; the other is either in a working register or an immediate (following) data byte.
Logic basics for the Intel 8080.
Before proceeding, let's review four common logical operators. Below are truth tables that define operator results (T True or F False) for given operands "p" and "q".
|
|
|
|
Describing the operations in words is helpful.
NOT - The result is the negation or complement of the operand; that is, a one becomes zero and a zero becomes one Sometimes we say that the NOT operator "flips a bit".
OR - The result is True if either or both operands are True. A different but equally useful way of saying it is this: the result is False only if both operands are False.
AND - The result is True only if both operands are True. Saying it differently, the result is False if either of the operands is False.
XOR - The result is True only if the operands are different. Again said differently, the result is False only if the operands are the same.
For our digital logic applications, True is taken as logic 1 and False as logic 0. "Bit-wise" means that Intel 8080 logic instructions operate individually on each bit of the A register with the result in the corresponding bit of A. The Intel 8080 directly implements OR, AND, and XOR. NOT is implemented using the XOR instruction. Listed below are the Intel 8080 logic instructions.
Note: In the descriptions below, r is the Register Reference Number and v is an 8-bit data value.
ORI v OR Immediate v with A. The value in A is OR'ed
bit-wise with the value v with result in A. The code byte for ORI is 366Q followed by
a data byte v.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry are cleared (made zero).
ORA r OR contents of register r
with A. The value in A is OR'ed bit-wise with the value in
register r with result in A. The octal
byte code for ORA is 26r. For
example, ORA H
is 264Q. "4" is the Register Reference Number for register H.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry are cleared (made zero).
ANI v AND Immediate v with A. The value in
A is AND'ed
bit-wise with the value v with result in A. The code byte for ANI is 346Q followed by
a data byte of value v.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry are cleared (made zero).
ANA r AND contents of register r
with A
The value in A is AND'ed bit-wise with the value in register r with result in A. The octal
code byte for ANA is 24r. For
example, ANA H
is 244Q. "4" is the Register Reference Number for register H.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry arecleared (made zero).
XRI v XOR Immediate v with A. The value in
A is XOR'ed
bit-wise with the value v with result in A. The code byte for XRI is 356Q followed by
a data byte of value v.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry are cleared (made zero)o.
XRA r XOR contents of register r
with A The value in A is XOR'ed bit-wise with the value in
register r
with result in A. The octal code byte for XRA is 25r. For
example, ORA H
is 254Q. "4" is the Register Reference Number for register H.
Status bits affected
- Sign, Zero, Parity. Carry and Auxiliary Carry are cleared (made zero).
Logical operators are useful in manipulating, masking, and testing bits. The examples below will demonstrate each application.
Try it!
Example 1 - Create and test code that performs each logic operation (OR, AND, and XOR) on the A register using an immediate data value. Assume A is 10101010B and the immediate value is 00001111B.
000 000 076 MVI A,
10101010B 10101010BgA
000 001 252
10101010B = 252Q
000 002 366 ORI 00001111B
A OR 00001111BgA
000 003 017
00001111B = 017Q
000 004 166 HLT Halt execution
a) Enter the code above. Click Reset and Single Step through the program.
Click "Stop" and use the Display A button to check the value in the accumulator.
Use the Display Status button to display the status bits. The table below gives
the position of the status bits in the Data LEDs. Compare the result
against the table below for the OR example.
b) Repeat part a for AND by changing address 000 002Q to 346Q.
c) Repeat part a for XOR by changing address 000 002Q to 356Q.
d) Change address 000 002Q & 000 003Q to ANI 10000000B. Single step through, and compare with the table below.
e) Change the immediate value at address 000 001Q to 00101010B and repeat.
Part | Logical Operation | Result (Binary) |
Processor Status Word | |||||||
S | Z | x | AC | x | P | x | C | |||
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |||
a | 10101010 OR 00001111 | 10101111 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
b | 10101010 AND 00001111 | 00001010 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
c | 10101010 XOR 00001111 | 10100101 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
d | 10101010 AND 10000000 | 10000000 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
e | 00101010 AND 10000000 | 00000000 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 |
The "x" columns in the Processor Status Word are not significant and always have the values indicated.
Using a logic operator to manipulate data bits.
Logical operators can be used to manipulate bits. Consider the results of a) and b) in the table above and assume the bits in the accumulator represent logical data to be manipulated by the immediate operand.
Force bits to "1": The OR operator forces bits 0-3 to "1" leaving bits 4-7 unchanged. OR'ing with "1" results in a "1" regardless of the original value of the data bit. OR'ing with "0" leaves data bit unchanged.
Force bits to "0": The AND operator forces bits 4-7 to "0" leaving bits 0-3 unchanged. AND'ing with "0" results in a "0" regardless of the original value of the data bit. AND'ing with "1" leaves data bit unchanged.
Flip bits: The XOR operator complements (negates) bits 0-3 leaving bits 4-7 unchanged. XOR'ing with "1" flips the data bit. XOR'ing with "0" leaves data bit unchanged.
Individual bits within a data byte are often used to control external devices. By choosing the appropriate operator (OR, AND, or XOR) and operand, individual bits on an I/O ports can be manipulated without affecting other bits.
Try it!
Example 2 - In a security application, assume that the lower 6 bits of a output port control outdoor lights. Setting a bit to one turns on a light; clearing a bit to zero turns the light off. The table below shows the association of lights with particular bits.
Light | Bit |
Front Porch | 0 |
Back Porch | 1 |
West Front Flood | 2 |
East Front Flood | 3 |
West Back Flood | 4 |
East Back Flood | 5 |
Assuming all lights are off, create and test code
that turns all lights on?
Let register A represent the light control byte. If the lights are
turned off, then all bits in A will be zero. We can turn on all the
bits using OR immediate (ORI) with 00111111B.
000 000 076 MVI A,
00000000B 00000000B gA
000 001 000
00000000B = 000Q
000 002 366 ORI 00111111B
A OR 00111111BgA
000 003 077
00111111B = 077Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display A
button to check that the value in the accumulator is 00111111B. All
lights are turned on.
Assuming all lights are off, turn on the front and back porch lights?
OR immediate (ORI) with 00000011B to turn on porch lights.
Let register A represent the light control byte. If the lights are
turned off, then all bits in A are zero. The front and back porch
lights are bits 0 and 1 respectively. We can turn just these bits on
using OR immediate (ORI) with 00000011B.
000 000 076 MVI A,
00000000B 00000000B gA
000 001 000
00000000B = 000Q
000 002 366 ORI 00000011B A OR 00000011BgA
000 003 003
00111111B = 003Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display A
button to check that the value in the accumulator is 00000011B.
Assuming all lights are on, turn off all but
the front and back porch.
Let A represent the light control byte. If all lights are turned on,
then A is 00111111B. We can turn off bits all except 0 and 1 using AND
immediate (ANI) with 00000011B. Bits 2 to 5 will be cleared leaving
bits 0 and 1 unchanged.
000 000 076 MVI A,
00111111B 00111111B gA
000 001 077
00111111B = 077Q
000 002 346 ANI 00000011B
A AND 00000011BgA
000 003 003
00000011B = 003Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display A
button to check that the value in the accumulator is 00000011B.
Regardless of the state of the lights, turn all
lights off?
Assume A has some lights on (A = 00101010B). AND immediate (ANI) with 00000000B
clears all bits and turns all lights off.
000 000 076 MVI A,
000101010B 00101010B gA
000 001 052
00101010B = 052Q
000 002 346 ANI 00000000B
A AND 00000000BgA
000 003 000
00000000B = 000Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display A
button to check that the value in the accumulator is 00000000B.
Using a logic operator to mask data bits.
Logical operators can be used to mask groups of bits within a data byte. Consider the result of b) and the AND operator in the table above. The effect of AND'ing with groups of 0's and 1's is to "mask off" the four upper bits leaving the four lower bits unchanged. Suppose the four lower bits represents a four bit binary value while the four upper bits represent unrelated data of some sort. The masking operation isolates the lower bits ready for further processing.
Try it!
Example 3. Suppose that the lower five bits of a data byte indicate room temperature in degrees C (0 to 31 °C) . Suppose further that the upper three bits indicate which room's temperature is in the lower five bits. Up to eight rooms (0 to 7) can be designated. Use masking to isolate the two distinct pieces of data.
Assume room 2 with a temperature of 27 °C is in register A;
then A is 01011011. To get the temperature, we mask off (AND immediate)
the upper three bits with 00011111B.
000 000 076 MVI A, 01011011B
01011011BgA
000 001 133
01011011B = 133Q
000 002 346 ANI 00011111B
A AND 00011111BgA
000 003 037
00011111B = 037Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display A
button to check that the value in the accumulator is 00011011B or 27.
Similarly, the room number can be isolated by masking off the lower five bits.
To get the room number, we mask off (AND immediate) the lower five bits with
11100000B.
000 000 076 MVI A, 01011011B
01011011BgA
000 001 133
01011011B = 133Q
000 002 346 ANI 11100000B
A AND 11100000BgA
000 003 340
11100000B = 340Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use the
Display A button
to check that the value in the accumulator is 01000000B or 64. To get the
actual room number, we need a way to divide by 32 or by 2 five times. In
Experiment 2 we saw that ADD A multiplies by 2. Looking ahead, the Intel
8080 has an instruction RRC (017Q) that rotates the A register contents once to
the right, essentially dividing by 2. Five RRCs will divide by 32 and give
us the desired result. Here is the code.
000 000 076 MVI A, 01011011B
01011011BgA
000 001 133
01011011B = 133Q
000 002 346 ANI 11100000B
A AND 11100000BgA
000 003 340
11100000B = 340Q
000 004 017 RRC
A/2gA
000 005 017 RRC
A/2gA
000 006 017 RRC
A/2gA
000 007 017 RRC
A/2gA
000 010 017 RRC
A/2gA
000 011 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use the
Display A button
to check that the value in the accumulator is 00000010B or 2, the room number.
Using a logic operator to test data bits.
Look closely at the results of Example 1 parts d and e above. In part d, we ANDed 10101010B with 10000000B. We have, in effect, tested bit 7 of the first byte; that is, the result reflects the state of bit 7 ignoring the other bits. Now look at the Z (Zero) status bit. It is zero because the logical operation produced a non-zero result. Consider part e. Bit 7 of the data byte is zero, so ANDing with 10000000B results in 00000000B and the now the Z (Zero) status bit is a one. By ANDing with 10000000B, we are "testing" bit 7 with the result indicated by the Z (ZERO) status bit. Later, in Experiment 4, we will use the status of the zero or other PSW bits in selection structures to execute different blocks of code. As we will see in the example below, testing with the AND need not be limited to a single bit.
Try it!
Example 4. Suppose that the lower six bits of a data byte indicate the status of a vehicle's four doors, its cargo door, and its hood. A zero bit value indicates the door is closed while a one indicates the door is open. The chart below shows the specific association with particular bits.
Door | Bit |
Front Driver | 0 |
Front Passenger | 1 |
Rear Driver | 2 |
Rear Passenger | 3 |
Cargo | 4 |
Hood | 5 |
Is the cargo door open?
First, let's assume that front doors are both open, but the cargo door is
closed. Register A is then 00000011B. To test the cargo door, AND
immediate with bit 4 a one or 00010000B.
000 000 076 MVI A, 00000011B
00000011BgA
000 001 003
00000011B = 003Q
000 002 346 ANI 00010000B
A AND 00010000BgA
000 003 020
000100000B = 020Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display
Status button to check that the Z status bit LED (D6) is on indicating a Z
(Zero) condition. Note that other bit being one does not matter. Only
bit 4, the cargo door bit, affects the result.
Change register A to 00010011B and test the cargo door again.
000 000 076 MVI A, 00010011B
00010011BgA
000 001 023
00010011B = 023Q
000 002 346 ANI 00010000B
A AND 00010000BgA
000 003 020
000100000B = 020Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display
Status button to check that the Z status bit LED (D6) is not on indicating a
NZ (Not Zero) condition and that the cargo door is open!
Is any door open?
Assuming again that only the front doors are both open, register A is then
00000011B. To test if any door is open,
AND immediate with 00111111B.
000 000 076 MVI A,
00000011B 00000011B gA
000 001 003
00000011B = 003Q
000 002 346 ANI 00010000B
A AND 00111111BgA
000 003 020
00111111B = 077Q
000 004 166 HLT Halt execution
Click Reset and Single Step through the program. Click "Stop" and use
the Display
Status button to check that the Z status bit LED (D6) is not on indicating a
NZ (Not Zero) condition and that at least one door is open. We can say
which one, but further programming could ferret this out.
Continue to next Experiment -
Click Here