CS 208 w20 lecture 9 outline

1 Exercise

How do these instructions

:
    leaq (%rdx,%rcx,4), %rax
    movq (%rdx,%rcx,4), %rbx
    leaq (%rdx), %rdi
    movq (%rdx), %rsi

affect the registers and memory here?

2 Condition Codes

  • the basis for control flow within a program (i.e., determining which instruction gets executed next)
    • special %rip register stores instruction pointer
  • most useful codes:
    • CF: carry flag. Set when an operation generated a carry out of the most significant bit. Used to detect unsigned overflow
    • ZF: zero flag. Set when an operation yields 0
    • SF: sign flag. Set when an operation yields a negative value
    • OF: overflow flag. Set when an operation causes a two's complement overflow, negative or positive
  • all the standard arithmetic instructions set these flags except for leaq
  • cmp and test instructions set condition codes
    • cmp subtracts first operand from second
    • test ands operands (usually the same quantity is both operands, check if its zero, positive, negative)

2.1 Accessing the Condition Codes

  • class of set instructions to set a single byte to 1 or 0 based on one or more condition codes (figure 3.14, p. 203)
    • in the case where cmp b, a was executed
    • when \(a=b\), then \(a-b=0\), so ZF will be set
    • when \(a < b\), then \(a - b < 0\) (SF set) or \(a - b\) overflows so the result is positive and OF is set
      • but both SF and OF set would indicate \(a\) is positive and \(b\) is negative such that \(a-b\) would overflow to a negative value
      • hence, less than is detected when SF ^ OF
    • for unsigned \(a < b\), \(a - b\) would cause a carry out of the most significant bit, setting CF

2.2 Exercises

2.2.1 Which condition codes indicate \(a > b\)?

  • not less than and not equal
  • ~(SF ^ OF) and ~ZF
  • ~(SF ^ OF) & ~ZF

2.2.2 Translate this C code to assembly

int gt(long x, long y) {
    return x > y;
}
Register Use
%rdi 1st argument (x)
%rsi 2nd argument (y)
%rax return value
gt:
  cmpq   %rsi, %rdi
  setg   %al
  movzbl %al, %eax
  ret

2.2.3 movz and movs

  • when moving data from a smaller source to a larger destination, can specify zero extension or sign extension
    • destination must be a register
  • movzSD / movsSD
    • S is the size of the source (b or w)
    • D is the size of the destination (w, l, or q)

movz-example.png

3 Jump Instructions

  • class of jump instructions move program execution to specified instruction (figure 3.15, p. 206)
  • direct jumps encode the jump target in the instruction
  • indirect jumps read the jump target from register or memory
    • written with a * preceding the operand
  • conditional jumps (can only be direct) jump or continue the subsequent instruction based on some combination of condition codes

jumps.png

3.1 Implementing Conditional Branches with Conditional Control

if (<text-expr>)
    <then-statement>
else
    <else-statement>

becomes

    t = <test-expr>;
    if (!t)
        goto false;
    <then-statement>
    goto done;
false:
    <else-statement>
done:

3.1.1 Exercises

Register Use
%rdi 1st argument (x)
%rsi 2nd argument (y)
%rax return value

Exercise 1:

long absdiff(long x, long y) {
    long result;
    if (x > y)
        result = x-y;
    else
        result = y-x;
    return result;
}

Which pair of instructions should go on the two blank lines?

absdiff:
        __________________
        __________________
                          # x > y:
        movq %rdi, %rax
        subq %rsi, %rax
        ret
    .L4:                  # x <= y:
        movq %rsi, %rax
        subq %rdi, %rax
        ret
cmpq %rsi, %rdi
jle .L4

Exercise 2: compile this code to assembly

long wacky(long x, long y) {
    long result;
    if (x + y > 7) {
        result = x;
    } else {
        result = y + 2;
    }
    return result;
}
wacky:
  movq %rdi, %rax
  leaq (%rdi,%rsi), %rdx
  cmpq $7, %rdx
  jg .L2
  leaq 2(%rsi), %rax
.L2:
  rep ret

3.2 Jump Instruction Encodings

  • jump target encoded compactly with PC relative representation
    • specify offset to the address of the immediately following instruction
  • compile to binary and disassemble previous exercise (11010 checkbox on godbolt) for an example

3.3 Implementing Conditional Branches with Conditional Moves

  • class of cmov instructions copy source operand to destination register when the condition holds
    • same conditions as set and jump instructions
  • can be more efficient than conditional jumps because the sequence of intructions is predictable
    • memory may or may not be moved, but the subsequent instruction is executed regardless
    • processors pipeline instructions, meaning they process them in a series of stages (fetching instruction from memory, determining instruction type, reading from memory, performing arithmetic operation, writing to memory, updating program counter)
    • significant performance benefits from overlapping different stages of sequential instructions
    • pipelining in the presence of conditional jumps requires sophisticated branch prediction (modern processors aim for 90% accuracy)
  • turn on optimization for previous exercise (-O1 compiler flag) to see an example