Lecture 09 Loops and Switches

Joseph Haugh

University of New Mexico

Learning Objectives

  • Describe and practice the translation of loops (do-while, while, and for) into assembly code. (Sec. 3.6.7)
  • Describe and practice the translation of the switch statement (Sec. 3.6.8)

Do-While Loop Example

long pcount_do (unsigned long x) {
  long result = 0;
  do {
    result += x & 0x1;
    x >>= 1;
  } while (x);
  return result;
}
long pcount_goto (unsigned long x) {
  long result = 0;
 loop:
  result += x & 0x1;
  x >>= 1;
  if(x) goto loop;
  return result;
}
  • Counts number of 1’s in argument x
  • Uses conditional branch to either continue looping or exit loop

Do-While Loop Computation

long pcount_goto 
  (unsigned long x) {

  long result = 0;
 loop:
  result += x & 0x1;
  x >>= 1;
  if(x) goto loop;
  return result;
}
Register Use
%rdi Argument x
%rax Result
   movl    $0, %eax		#  result = 0
.L2:			        #  loop:
   movq    %rdi, %rdx	
   andl    $1, %edx		#  t = x & 0x1
   addq    %rdx, %rax	#  result += t
   shrq    %rdi		    #  x >>= 1
   jne     .L2		    #  if (x) goto loop
   rep; ret             # p. 208 explains

General Do-While Loop Translation

do
  body-stmts
  while (text-expr);
loop:
  body-stmts
  if (test-expr)
    goto loop

General While Loop Translation 1

  • Jump-to-middle translation
  • Used with -Og
while (test-expr)
  body-stmts
goto test;
loop:
  body-stmts
test:
  if (test-expr)
    goto loop;
done:

While Loop Example 1

long pcount_while
  (unsigned long x) {

  long result = 0;
  while (x) {
    result += x & 0x1;
    x >>= 1;
  }
  return result;
}
long pcount_goto_jtm
  (unsigned long x) {

  long result = 0;
  goto test;
 loop:
  result += x & 0x1;
  x >>= 1;
 test:
  if(x) goto loop;
  return result;
}

General While Loop Translation 2

  • Guarded-do translation
  • Do-while conversion
  • Used with -O1
while (test-expr)
  body-stmts

Becomes

  if (!test-expr) 
    goto done;
  do
    body-stmts
    while(test-expr);
done:
  if (!Test)
    goto done;
loop:
  Body
  if (Test)
    goto loop;
done:

General While Loop Translation 2

long pcount_while
  (unsigned long x) {
    
  long result = 0;
  while (x) {
    result += x & 0x1;
    x >>= 1;
  }
  return result;
}
long pcount_goto_dw
  (unsigned long x) {

  long result = 0;
  if (!x) goto done;
 loop:
  result += x & 0x1;
  x >>= 1;
  if(x) goto loop;
 done:
  return result;
}
  • Compare to do-while version of function
  • Initial conditional guards entrance to the loop

Practice: Problem 3.24

long loop_while(long a, long b)
{
    long result = __________;
    while (__________) {
        result = __________;
        a = __________;
    }
    return result;
}
	long loop_while(long a, long b)
	a in %rdi, b in %rsi
1	loop_while:
2	  movl	$1, %eax
3	  jmp	.L2
4	.L3:
5	  leaq	(%rdi,%rsi), %rdx
6	  imulq	%rdx, %rax
7	  addq	$1, %rdi
8	.L2:
9	  cmpq	%rsi, %rdi
10	  jl	.L3
11	  rep; ret

Practice: Problem 3.24

long loop_while(long a, long b)
{
	long result = 1;
	while (a < b) {
	  result = result * (a+b);
	  a = a+1;
	}
	return result;
}
	long loop_while(long a, long b)
	a in %rdi, b in %rsi
1	loop_while:
2	  movl	$1, %eax
3	  jmp	.L2
4	.L3:
5	  leaq	(%rdi,%rsi), %rdx
6	  imulq	%rdx, %rax
7	  addq	$1, %rdi
8	.L2:
9	  cmpq	%rsi, %rdi
10	  jl	.L3
11	  rep; ret

Practice: Problem 3.25

long loop_while2(long a, long b)
{
	long result = __________;
	while(__________) {
		result = __________;
		b = __________;
	}
	return result;
}
a in %rdi, b in %rsi
loop_while2:
   testq %rsi, %rsi
   jle   .L8
   movq  %rsi, %rax
.L7:
   imulq  %rdi, %rax
   subq   %rdi, %rsi
   testq  %rsi, %rsi
   jg     .L7
   rep;  ret
.L8:
   movq   %rsi, %rax
   ret

Practice: Problem 3.25

long loop_while2(long a, long b)
{
	long result = b;
	while(b > 0) {
		result = result * a;
		b = b - a;
	}
	return result;
}
a in %rdi, b in %rsi
loop_while2:
   testq %rsi, %rsi
   jle   .L8
   movq  %rsi, %rax
.L7:
   imulq  %rdi, %rax
   subq   %rdi, %rsi
   testq  %rsi, %rsi
   jg     .L7
   rep;  ret
.L8:
   movq   %rsi, %rax
   ret

More Practice

  • Problem 3.26

General For Loop Conversion

Switch Statement Example

long switch_eg (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;
}
  • Multiple case labels
    • Here: 5 & 6
  • Fall through cases
    • Here: 2
  • Missing cases
    • Here: 4
  • Commonly translated into a jump table instead of a sequence of if/else statements

Jump Table Structure

  • Switch General Form

    switch(x) {
    case val_0:
        Block 0
    case val_1:
        Block 1
        • • •
    case val_n-1:
        Block n–1
    }
  • Translation

    goto *JTab[x];

Switch Statement Example

long switch_eg(long x, long y, long z)
{
    long w = 1;
    switch(x) {
      . . .
    }
    return w;
}
Register Use
%rdi Argument x
%rsi Argument y
%rdx Argument z
%rax Return Value
switch_eg:
    movq    %rdx, %rcx
    cmpq    $6, %rdi   # x:6
    ja      .L8
    jmp     *.L4(,%rdi,8)
.section	.rodata
	.align 8
.L4:
	.quad	.L8	# x = 0
	.quad	.L3	# x = 1
	.quad	.L5	# x = 2
	.quad	.L9	# x = 3
	.quad	.L8	# x = 4
	.quad	.L7	# x = 5
	.quad	.L7	# x = 6

Jump Table

  • Table Structure:
    • Each target requires 8 bytes
    • Base address at .L4
  • Jumping:
    • Direct: jmp .L8
    • Jump target is denoted by label .L8
    • Indirect: jmp *.L4(,%rdi,8)
    • Start of jump table: .L4
    • Must scale by factor of 8 (addresses are 8 bytes)
    • Fetch target from effective Address .L4 + x*8
      • Only for 0 ≤ x ≤ 6
.section	.rodata
	.align 8
.L4:
	.quad	.L8	# x = 0
	.quad	.L3	# x = 1
	.quad	.L5	# x = 2
	.quad	.L9	# x = 3
	.quad	.L8	# x = 4
	.quad	.L7	# x = 5
	.quad	.L7	# x = 6

Jump Table