Control
Condition Codes
Name | Symbol | Bit | Use |
---|---|---|---|
Carry | CF | 0 | Used to indicate if the previous operation results in a carry |
Parity | PF | 2 | Used to indicate if the last byte has an even number of 1’s (even parity) |
Adjust | AF | 4 | Used to support Binary Coded Decimal |
Zero | ZF | 6 | Used to indicate if the previous operation resulted in a zero result |
Sign | SF | 7 | Used to indicate if the previous operation resulted in a 1 in the MSB |
Direction | DF | 10 | Used to specify the direction (increment or decrement) for some string operations |
Overflow | OF | 11 | Used to indicate if the previous operation resulted in an overflow |
-
Example, the conditions code would be set according to the following C expressions:
-
There are 2 instruction classes that set condition codes (
ZF
) without altering other registers:- CMP subtracts the operands and sets the flags. Namely, it sets the zero flag if the difference is zero (operands are equal).
testq a,b
like computing a&b without setting destination- ZF set when a&b == 0
- SF set when a&b < 0
- Test for zero:
testq %rax, %rax
Accessing the condition codes
- Rather than reading the condition codes directly, there are three common ways of using the condition codes.
Approach 1: set a single byte to 0 or 1 depending on some combination of the condition codes
- A set instruction has either one of the low-order single-byte register elements or a single-byte memory location as its destination, setting this byte to either 0 or 1. To generate a 32-bit or 64-bit result, we must also clear the high-order bits
- Example: a function in C compute the expression a < b (long)
Approach 2: conditionally jump to some other part of the program
Approach 3: conditionally transfer data
Jump instructions
- The
jmp
instruction jumps unconditionally.- Direct jump:
- Indirect jump (the jump target is read from a register or a memory location)
- The remaining jump instructions in the table are conditional
Jump instructions encoding
- In assembly code, jump targets are written using symbolic labels. The assembler, and later the linker, generate the proper encodings of the jump targets.
- There are 2 commonly used method for encoding jump targets:
PC relative
andabsolute address
- Consider the following assembly code a function was generate by compiling a file
branch.c
.
PC relative (used by assembler)
- The disassembled version of the .o format generated by the assembler is as follows (use
objdump
to read .o file):
- The first jump target is encoded as
0x03
. Adding this to0x5
(the next instruction address) will result in0x8
, we get jump targe address0x8
, the address of the instruction on line 4. - The second jump target is encoded as
0xf8
(decimal -8), adding this to0xd
will result in0x5
, the address of the instruction on line 3
Absolute address (used by linker)
- Using 4 bytes to directly specify the target.
- The disassembled version of the program after linking:
Conditional branches with conditional control
- Use conditional jumps and unconditional jumps to translate conditional expressions in C
Conditional branches with conditional moves
- The conditional move instructions
-
The conditional branches with conditional control is simple, but it can be very inefficient on modern processors.
-
This approach computes both outcomes of a conditional operation and then selects one based on whether or not the condition holds
-
Example: