1. Instruction Overview
Starting from the Intel 80386 processor, the instruction set introduced a very useful set of conditional byte set instructions (<span>SETcc</span>). The function of this set of instructions is not to perform program flow jumps, but to set a byte value to 1 or 0 based on the current state of the CPU status flags. This provides powerful support for implementing conditional assignments without using branch jumps, which can simplify code, avoid the overhead of branch prediction failures, and achieve efficient Boolean logic.
2. Instruction Format and Operands
The general format of the <span>SETcc</span> instruction is as follows:
SETcc OPRD
-
**
<span>cc</span>**: - This is part of the instruction mnemonic, representing condition.
- These condition codes (such as
<span>Z</span>,<span>NZ</span>,<span>G</span>,<span>L</span>, etc.) are exactly the same as the conditions used in conditional jump instructions (<span>Jcc</span>). It determines which flags the CPU will test and the logic of the tests. -
**
<span>OPRD</span>**: - This is the destination operand, used to store the test result (1 or 0).
- It can only be an 8-bit register (such as
<span>AL</span>,<span>BL</span>,<span>CL</span>,<span>DL</span>,<span>AH</span>,<span>BH</span>,<span>CH</span>,<span>DH</span>) or a byte-sized memory unit. - It cannot be an immediate value or a register larger than 8 bits.
3. Instruction Functionality
The functionality of the <span>SETcc</span> instruction is very straightforward:
- The CPU checks the condition specified by
<span>cc</span>in the instruction. - If the condition is “true”, the destination operand
<span>OPRD</span>is set to 1. - If the condition is “false”, the destination operand
<span>OPRD</span>is set to 0.
After the execution of this instruction, the value of <span>OPRD</span> will be a Boolean result (<span>0x00</span> or <span>0x01</span>), which can be used for subsequent arithmetic operations, logical judgments, or storage.
4. List of Instructions and Test Conditions
The table below lists commonly used <span>SETcc</span> instructions and their test conditions:
| Instruction Format | Test Condition | Function Description (When Condition is True, OPRD=1) |
|---|---|---|
<span>SETZ</span> / <span>SETE</span> |
<span>ZF = 1</span> |
Equal to Zero (Zero) / Equal (Equal) |
<span>SETNZ</span> / <span>SETNE</span> |
<span>ZF = 0</span> |
Not Equal to Zero (Not Zero) / Not Equal (Not Equal) |
<span>SETS</span> |
<span>SF = 1</span> |
Negative (Sign) |
<span>SETNS</span> |
<span>SF = 0</span> |
Positive (Not Sign) |
<span>SETO</span> |
<span>OF = 1</span> |
Overflow (Overflow) |
<span>SETNO</span> |
<span>OF = 0</span> |
No Overflow (Not Overflow) |
<span>SETP</span> / <span>SETPE</span> |
<span>PF = 1</span> |
Parity Even (Parity Even) |
<span>SETNP</span> / <span>SETPO</span> |
<span>PF = 0</span> |
Parity Odd (Parity Odd) |
| Unsigned Comparison | ||
<span>SETB</span> / <span>SETNAE</span>/ <span>SETC</span> |
<span>CF = 1</span> |
Below (Below) / Not Above or Equal / Carry (Carry) |
<span>SETNB</span> / <span>SETAE</span>/ <span>SETNC</span> |
<span>CF = 0</span> |
Not Below (Not Below) / Above or Equal / No Carry (No Carry) |
<span>SETBE</span> / <span>SETNA</span> |
<span>(CF OR ZF) = 1</span> |
Below or Equal (Below or Equal) / Not Above (Not Above) |
<span>SETNBE</span> / <span>SETA</span> |
<span>(CF OR ZF) = 0</span> |
Not Below or Equal (Not Below or Equal) / Above (Above) |
| Signed Comparison | ||
<span>SETL</span> / <span>SETNGE</span> |
<span>(SF != OF)</span> (SF XOR OF = 1) |
Less (Less) / Not Greater or Equal (Not Greater or Equal) |
<span>SETNL</span> / <span>SETGE</span> |
<span>(SF == OF)</span> (SF XOR OF = 0) |
Not Less (Not Less) / Greater or Equal (Greater or Equal) |
<span>SETLE</span> / <span>SETNG</span> |
<span>((SF != OF) OR ZF) = 1</span> |
Less or Equal (Less or Equal) / Not Greater (Not Greater) |
<span>SETNLE</span> / <span>SETG</span> |
<span>((SF != OF) OR ZF) = 0</span> |
Not Less or Equal (Not Less or Equal) / Greater (Greater) |
5. Impact on Flags
All <span>SETcc</span> instructions do not affect any CPU status flags.
Code Examples
The following examples demonstrate the application of <span>SETcc</span> instructions in various scenarios.
Example 1: Basic Flag Check
MOV AL, 100
ADD AL, 28 ; AL = 128 (-128 signed), will cause overflow (OF=1) and sign (SF=1)
SETO BL ; Because OF=1, BL is set to 1
SETNS CL ; Because SF=1 (negative), the condition "Not Sign (NS)" is false, CL is set to 0
; After execution: BL = 1, CL = 0
Example 2: Implementing Boolean Result of Unsigned Comparison
MOV AX, 100
MOV BX, 200
CMP AX, BX ; Compare 100 and 200 (unsigned)
SETA CL ; If AX > BX (100 > 200 is false), then set CL=1. Here the condition is false, CL=0
SETB DL ; If AX < BX (100 < 200 is true), then set DL=1. Here DL=1
; After execution: CL = 0, DL = 1
Example 3: Implementing Boolean Result of Signed Comparison
MOV AX, -10
MOV BX, 5
CMP AX, BX ; Compare -10 and 5 (signed)
SETL CL ; If AX < BX (-10 < 5 is true), then set CL=1. Here CL=1
SETG CH ; If AX > BX (-10 > 5 is false), then set CH=1. Here CH=0
; After execution: CL = 1, CH = 0
Example 4: Checking if Character is a Digit (‘0’-‘9’)
.DATA
char DB '7'
.CODE
MOV AL, char
CMP AL, '0' ; Compare AL and '0'
SETB BL ; If AL < '0', BL=1
CMP AL, '9'
SETA BH ; If AL > '9', BH=1
OR BL, BH ; If either BL or BH is 1 (i.e., out of range), the result is non-zero
JZ Is_Digit ; If result is 0, it is a digit
; ... handle non-digit ...
JMP Done
Is_Digit:
; ... handle digit ...
Done:
Example 5: Storing Comparison Result in Memory
.DATA
Result DB ?
.CODE
MOV EAX, 5000
MOV EBX, 5000
CMP EAX, EBX ; Compare two numbers
SETE Result ; If equal, Result = 1, otherwise Result = 0
; Now the comparison result is stored in the memory variable Result (in this case, 1)
User Provided Example Analysis:
SETO AL ; Test overflow flag OF. If OF=1 (overflow occurred), then AL=1, otherwise AL=0.
SETNC CH ; Test carry flag CF. If CF=0 (no carry), then CH=1, otherwise CH=0.
; (The comment in the user example "when flag CF is cleared" is inaccurate, it should be "when flag CF is zeroed")
Conclusion
<span>SETcc</span> instruction set greatly enhances the ability of assembly language to handle conditional logic, allowing programmers to:
- Avoid Branching: By generating conditional values instead of jumps, performance on pipelined CPUs can be improved.
- Implement Boolean Algebra: Easily compute conditions as Boolean values (0 or 1).
- Simplify Complex Conditions: Achieve complex logical judgments by combining multiple
<span>SETcc</span>instructions and logical operations (<span>AND</span>,<span>OR</span>,<span>XOR</span>). - Generate Masks: Create bit masks based on conditions for subsequent bit operations.
These instructions are very useful when writing efficient, compact low-level code.