The logic instructions work on each bit separately.
| Instruction | A bit of the result is 1 when... | Common use |
|---|---|---|
AND d, s | both bits are 1 | clear bits: keep only some (a mask) |
OR d, s | either bit is 1 | set bits |
XOR d, s | the bits differ | flip bits; XOR AX, AX clears AX |
NOT d | the bit was 0 | flip every bit |
TEST d, s | (like AND, but only the flags change) | is a bit set? |
AND, OR, XOR and TEST always clear CF and OF, and set ZF and SF from the result. NOT changes no flags.
Upper and lower case
In ASCII, a lower-case letter is its capital plus 20h: 'a' is 61h and 'A' is 41h. Only bit 5 (value 20h) differs, so:
| To | Do | Mask |
|---|---|---|
| upper case | clear bit 5 | AND AL, 11011111B (0DFh) |
| lower case | set bit 5 | OR AL, 00100000B (20h) |
| the other case | flip bit 5 | XOR AL, 20H |
; Read a letter and print it in the other case.
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AH, 1
INT 21H ; AL = the letter typed
MOV DL, AL
XOR DL, 20H ; flip bit 5: a <-> A
MOV AH, 2
INT 21H
TEST DL, 20H ; is bit 5 set now? (ZF = 0 means lower case)
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINInput used: q
TEST AL, 1 checks the lowest bit: ZF = 1 means the number is even.
Shifts and rotates
| Instruction | Moves the bits | The bit pushed out goes to |
|---|---|---|
SHL d, n | left, 0s come in: × 2ⁿ | CF |
SHR d, n | right, 0s come in: ÷ 2ⁿ (unsigned) | CF |
SAR d, n | right, copies of the sign bit come in: ÷ 2ⁿ (signed) | CF |
ROL d, n / ROR d, n | round in a circle | CF (and back in at the other end) |
RCL d, n / RCR d, n | round in a circle through CF | CF |
On the 8086 the count n is 1 or the register CL: MOV CL, 3 then SHL AX, CL. (StepVioz also accepts a number, as later processors do.)
Shifting left one bit at a time pushes each bit into CF, top bit first: a way to print a number in binary.
; Print a byte in binary: shift each bit into CF, top bit first.
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV BL, 45 ; 45 = 00101101b
MOV CX, 8 ; eight bits
NEXTBIT:
MOV DL, '0'
SHL BL, 1 ; the top bit goes into CF
ADC DL, 0 ; '0' + CF: '0' or '1'
MOV AH, 2
INT 21H
LOOP NEXTBIT
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINADC DL, 0 adds CF to DL, turning '0' into '1' when the bit was 1, with no jump needed.
Common mistakes
- Using AND to set a bit (it can only clear) or OR to clear one (it can only set).
- Using SHR on a negative number to divide it: use SAR, which keeps the sign.
- Expecting
SHL AX, 3to work on a real 8086: useMOV CL, 3andSHL AX, CL. - Clearing bit 5 of a character that is not a letter: check that it is between 'a' and 'z' first.
Quick check
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.