CS 208 w20 lecture 10 outline

1 Review

  • write one sentence on the difference between lea and mov instructions

2 Practice

Translate assembly to C

f(long, long):
        subq    %rsi, %rdi
        jne     .L3
        movq    %rdi, %rax
        ret
.L3:
        movq    %rsi, %rax
        ret
long f(long x, long y) {
    long z = x - y;
    if (z == 0) {
        return z;
    }
    return y;
}
f(long, long):
        cmpq    $2, %rdi
        setle   %dl
        cmpq    %rsi, %rdi
        sete    %al
        testb   %al, %dl
        je      .L3
        movl    $1, %eax
        ret
.L3:
        movl    $2, %eax
        ret
long f(long x, long y) {
    if (x < 3 && x == y) {
        return 1;
    } else {
        return 2;
    }
}
f(long *p):
        testq   %rdi, %rdi
        je      .L4
        movq    (%rdi), %rax
        leaq    -10(%rax), %rdx
        testq   %rdx, %rdx
        jle     .L3
        addq    %rax, %rax
        ret
.L3:
        addq    $1, %rax
        ret
.L4:
        movl    $0, %eax
        ret
#include <stdlib.h>
long f(long *p) {
    if (p == NULL) {
        return 0;
    }
    if (*p - 10 > 0) {
        return *p + *p;
    } else {
        return *p + 1;
    }
}

3 Loops

3.1 do-while loops

do
    <body-statement>
    while (<test-expr>);

becomes

loop:
    <body-statement>
    t = <test-expr>
    if (t)
        goto loop;

3.2 while loops

while (<test-expr>)
    <body-statement>

becomes

    goto test;
loop:
    <body-statement>
test:
    t = <test-expr>
    if (t)
        goto loop;
  • note the jump-to-the-middle approach to loop implementation
  • On higher optimization settings, while loops get translated into a guarded-do form
    • a conditional branch followed by a do-while loop
    • can allow the initial check to be optimized away if the compiler can determine the condition will always hold
long fact_while(long x){
    long result = 1;
    while (x > 1) {
        result = result * x;
        x = x - 1;
    }
    return result;
}
fact_while:
        movl    $1, %eax
        jmp     .L2
.L3:
        imulq   %rdi, %rax
        subq    $1, %rdi
.L2:
        cmpq    $1, %rdi
        jg      .L3
        rep ret

3.3 for loops

  • C language standard states that in the absence of continue
for (<init-expr>; <test-expr>; <update-expr>)
    <body-statement>

is equivalent to

<init-expr>;
while (<test-expr>) {
    <body-statement>
    <update-expr>;
}
  • hence, a for loop is then translated using jump-to-the-middle or guarded-do depending on the optimization level

4 Switch

  • can make code more readable
  • efficient implementation via a jump table
    • array where entry \(i\) is the address of the code to be executed when the switch value is \(i\)
    • time to perform switch is constant regardless of the number of cases (as opposed to series of if-else)
    • used when there are more than a few cases where the values are not too far apart
  • see figures 3.22 and 3.23 (p. 234-5) for example implementation
long switch_ex(long x, long y, long z) {
    long w = 1;
    switch(x) {
    case 1:
        w = y * z;
        break;
    case 2:
        w = y + z;
    case 3:
        w += z;
        break;
    case 5:
    case 6:
        w -= z;
        break;
    default:
        w = 2;
    }
    return w;
}

switch-jump-table.png

switch_ex(long, long, long):
        cmpq    $6, %rdi
        ja      .L8
        jmp     *.L4(,%rdi,8)
.L4:
        .quad   .L8
        .quad   .L3
        .quad   .L5
        .quad   .L9
        .quad   .L8
        .quad   .L7
        .quad   .L7
.L3:
        movq    %rsi, %rax
        imulq   %rdx, %rax
        ret
.L5:
        leaq    (%rsi,%rdx), %rax
        jmp     .L6
.L9:
        movl    $1, %eax
.L6:
        addq    %rdx, %rax
        ret
.L7:
        movl    $1, %eax
        subq    %rdx, %rax
        ret
.L8:
        movl    $2, %eax
        ret

5 gdb