Skip to content

Control

Condition Codes

NameSymbolBitUse
CarryCF0Used to indicate if the previous operation results in a carry
ParityPF2Used to indicate if the last byte has an even number of 1’s (even parity)
AdjustAF4Used to support Binary Coded Decimal
ZeroZF6Used to indicate if the previous operation resulted in a zero result
SignSF7Used to indicate if the previous operation resulted in a 1 in the MSB
DirectionDF10Used to specify the direction (increment or decrement) for some string operations
OverflowOF11Used to indicate if the previous operation resulted in an overflow
  • Example, the conditions code would be set according to the following C expressions:

    CF (unsigned) t < (unsigned) a Unsigned overflow
    ZF (t == 0) Zero
    SF (t < 0) Negative
    OF (a < 0 == b < 0) && (t < 0 != a < 0) Signed overflow
  • There are 2 instruction classes that set condition codes (ZF) without altering other registers:

    Comparison and Test

    • 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

Comparison and Test

  • 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)
    int comp(data_t a, data_t b)
    a in %rdi, b in %rsi
    comp:
    cmpq %rsi, %rdi Compare a:b
    setl %al Set low-order byte of %eax to 0 or 1
    movzbl %al, %eax Clear rest of %eax (and rest of %rax)
    ret

Approach 2: conditionally jump to some other part of the program

Approach 3: conditionally transfer data

Jump instructions

Jump Instructions

  • The jmp instruction jumps unconditionally.
    • Direct jump:
      movq $0,%rax Set %rax to 0
      jmp .L1 Goto .L1
      movq (%rax),%rdx Null pointer dereference (skipped)
      .L1:
      popq %rdx Jump target
    • Indirect jump (the jump target is read from a register or a memory location)
      jmp *%rax // uses the value in register %rax as the jump target
      jmp *(%rax) // uses the value in %rax as the read address
  • 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 and absolute address
  • Consider the following assembly code a function was generate by compiling a file branch.c.
movq %rdi, %rax
jmp .L2
.L3:
sarq %rax
.L2:
testq %rax, %rax
jq .L3
rep; ret

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):
0: 48 89 f8 mov %rdi,%rax
3: eb 03 jmp 8 <loop+0x8>
5: 48 d1 f8 sar %rax
8: 48 85 c0 test %rax,%rax
b: 7f f8 jg 5 <loop+0x5>
d: f3 c3 repz retq
  • The first jump target is encoded as 0x03. Adding this to 0x5 (the next instruction address) will result in 0x8, we get jump targe address 0x8, the address of the instruction on line 4.
  • The second jump target is encoded as 0xf8 (decimal -8), adding this to 0xd will result in 0x5, 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:
4004d0: 48 89 f8 mov %rdi,%rax
4004d3: eb 03 jmp 4004d8 <loop+0x8>
4004d5: 48 d1 f8 sar %rax
4004d8: 48 85 c0 test %rax,%rax
4004db: 7f f8 jg 4004d5 <loop+0x5>
4004dd: f3 c3 repz retq

Conditional branches with conditional control

  • Use conditional jumps and unconditional jumps to translate conditional expressions in C

Jump Instructions

Conditional branches with conditional moves

  • The conditional move instructions

Jump 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: Jump Instructions

Loop

Do-while

Jump Instructions