0% found this document useful (0 votes)
32 views

Machine-Level Programming II: Control Flow: Topics

This document discusses machine-level programming topics related to control flow, including condition codes, setting and testing condition codes, and conditional branching. It provides examples of how conditional branching can be used to implement if-then-else statements and loops like do-while loops in assembly language using condition codes and jump instructions. Key concepts covered include implicit and explicit setting of condition codes, reading condition codes using set instructions, and conditional branch instructions like jg and jle.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

Machine-Level Programming II: Control Flow: Topics

This document discusses machine-level programming topics related to control flow, including condition codes, setting and testing condition codes, and conditional branching. It provides examples of how conditional branching can be used to implement if-then-else statements and loops like do-while loops in assembly language using condition codes and jump instructions. Key concepts covered include implicit and explicit setting of condition codes, reading condition codes using set instructions, and conditional branch instructions like jg and jle.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 35

CS 367

Machine-Level Programming II:


Control Flow

Topics
 Condition Codes
 Setting
 Testing
 Control Flow
 If-then-else
 Varieties of Loops
 Switch Statements

lecture9.ppt
Condition Codes
Single Bit Registers
CF Carry Flag SF Sign Flag
ZF Zero Flag OF Overflow Flag

Implicitly Set By Arithmetic Operations


addl Src,Dest
C analog: t = a + b
 CF set if carry out from most significant bit
 Used to detect unsigned overflow
 ZF set if t == 0
 SF set if t < 0
 OF set if two’s complement overflow
(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)

Not Set by leal instruction


–2– CS 367
Setting Condition Codes (cont.)
Explicit Setting by Compare Instruction
cmpl Src2,Src1
 cmpl b,a like computing a-b without setting destination
 CF set if carry out from most significant bit
 Used for unsigned comparisons
 ZF set if a == b
 SF set if (a-b) < 0
 OF set if two’s complement overflow
(a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0)

–3– CS 367
Setting Condition Codes (cont.)
Explicit Setting by Test instruction
testl Src2,Src1
 Sets condition codes based on value of Src1 & Src2
 Useful to have one of the operands be a mask
 testl b,a like computing a&b without setting destination
 ZF set when a&b == 0
 SF set when a&b < 0

–4– CS 367
Reading Condition Codes
SetX Instructions
 Set single byte based on combinations of condition codes

SetX Condition Description


sete ZF Equal/Zero
setne ~ZF N ot Equal/N otZero
sets SF N egative
setns ~SF N onnegative
setg ~(SF^OF)&~ZF G reater (Signed)
setge ~(SF^OF) G reater or Equal(Signed)
setl (SF^OF) Less (Signed)
setle (SF^OF)|ZF Less or Equal(Signed)
seta ~CF&~ZF A bove (unsigned)
setb CF B elow (unsigned)
–5– CS 367
Reading Condition Codes (Cont.)
SetX Instructions
 Set single byte based on
combinations of condition codes %eax %ah %al
 One of 8 addressable byte registers %edx %dh %dl
 Embedded within first 4 integer
registers %ecx %ch %cl
 Does not alter remaining 3 bytes %ebx %bh %bl
 Typically use movzbl to finish job
%esi
int gt (int x, int y)
{ %edi
return x > y;
%esp
}
Body %ebp
movl 12(%ebp),%eax # eax = y
cmpl %eax,8(%ebp) # Compare x : y Note
setg %al # al = x > y inverted
movzbl %al,%eax # Zero rest of %eax ordering!
–6– CS 367
Jumping
jX Instructions
 Jump to different part of code depending on condition codes
jX Condition Description
jmp 1 U nconditional
je ZF Equal/Zero
jne ~ZF N ot Equal/N otZero
js SF N egative
jns ~SF N onnegative
jg ~(SF^OF)&~ZF G reater (Signed)
jge ~(SF^OF) G reater or Equal(Signed)
jl (SF^OF) Less (Signed)
jle (SF^OF)|ZF Less or Equal(Signed)
ja ~CF&~ZF A bove (unsigned)
jb CF B elow (unsigned)
–7– CS 367
Conditional Branch Example

_max:
pushl %ebp Set
movl %esp,%ebp Up
int max(int x, int y)
{ movl 8(%ebp),%edx
if (x > y) movl 12(%ebp),%eax
return x; cmpl %eax,%edx Body
else jle L9
return y; movl %edx,%eax
} L9:

movl %ebp,%esp
popl %ebp Finish
ret

–8– CS 367
Conditional Branch Example (Cont.)
int goto_max(int x, int y)
{
int rval = y;  C allows “goto” as means
int ok = (x <= y); of transferring control
if (ok)
 Closer to machine-level
goto done;
rval = x; programming style
done:  Generally considered bad
return rval; coding style
}

movl 8(%ebp),%edx # edx = x


movl 12(%ebp),%eax # eax = y
cmpl %eax,%edx # x : y
jle L9 # if <= goto L9
movl %edx,%eax # eax = x Skipped when x  y
L9: # Done:

–9– CS 367
“Do-While” Loop Example

C Code Goto Version


int fact_do int fact_goto(int x)
(int x) {
{ int result = 1;
int result = 1; loop:
do { result *= x;
result *= x; x = x-1;
x = x-1; if (x > 1)
} while (x > 1); goto loop;
return result; return result;
} }

 Use backward branch to continue looping


 Only take branch when “while” condition holds

– 10 – CS 367
“Do-While” Loop Compilation

Goto Version Assembly


int fact_goto _fact_goto:
(int x) pushl %ebp # Setup
{ movl %esp,%ebp # Setup
int result = 1; movl $1,%eax # eax = 1
loop: movl 8(%ebp),%edx # edx = x
result *= x;
x = x-1; L11:
if (x > 1) imull %edx,%eax # result *=
goto loop; x
return result; decl %edx # x--
} cmpl $1,%edx # Compare x : 1
jg L11 # if > goto loop

Registers movl %ebp,%esp # Finish


%edx x popl %ebp # Finish
ret # Finish
%eax result
– 11 – CS 367
General “Do-While” Translation
C Code Goto Version
do loop:
Body Body
while (Test); if (Test)
goto loop

 Body can be any C statement


 Typically compound statement:

{
Statement1;
Statement2;

Statementn;
}
 Test is expression returning integer
= 0 interpreted as false 0 interpreted as true

– 12 – CS 367
“While” Loop Example #1
C Code First Goto Version
int fact_while int fact_while_goto
(int x) (int x)
{ {
int result = 1; int result = 1;
while (x > 1) { loop:
result *= x; if (!(x > 1))
x = x-1; goto done;
}; result *= x;
return result; x = x-1;
} goto loop;
done:
return result;
}

 Is this code equivalent to the do-while version?


 Must jump out of loop if test fails

– 13 – CS 367
Actual “While” Loop Translation

C Code Second Goto Version


int fact_while(int x) int fact_while_goto2
{ (int x)
int result = 1; {
while (x > 1) { int result = 1;
result *= x; if (!(x > 1))
x = x-1; goto done;
}; loop:
return result; result *= x;
} x = x-1;
if (x > 1)
goto loop;
 Uses same inner loop done:
as do-while version return result;
 Guards loop entry with }
extra test

– 14 – CS 367
General “While” Translation
C Code
while (Test)
Body

Do-While Version Goto Version


if (!Test)
if (!Test)
goto done;
goto done;
loop:
do
Body
Body
if (Test)
while(Test);
goto loop;
done:
done:

– 15 – CS 367
“For” Loop Example
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned p) {
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
}
return result;
}

Algorithm
 Exploit property that p = p0 + 2p1 + 4p2 + … 2n–1pn–1
 Gives: xp = z0 · z1 2 · (z2 2) 2 · … · (…((zn –12) 2 )…) 2
zi = 1 when pi = 0
zi = x when pi = 1
 Complexity O(log p)
Example
n–1 times
310 = 32 * 38
= 32 * ((32)
– 16 – )2
2
CS 367
ipwr Computation
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned p) {
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
}
return result;
}

result x p
1 3 10
1 9 5
9 81 2
9 6561 1
531441 43046721 0

– 17 – CS 367
“For” Loop Example
General Form
int result;
for (result = 1; for (Init; Test; Update )
p != 0;
p = p>>1) { Body
if (p & 0x1)
result *= x;
x = x*x;
}

Init Test Update


result = 1 p != 0 p = p >> 1

{
Body if (p & 0x1)
result *= x;
x = x*x;
}
– 18 – CS 367
“For” “While”
For Version While Version
for (Init; Test; Update ) Init;
while (Test ) {
Body
Body
Update ;
}
Do-While Version
Init; Goto Version
if (!Test)
goto done; Init;
do { if (!Test)
Body goto done;
Update ; loop:
} while (Test) Body
done: Update ;
if (Test)
goto loop;
done:
– 19 – CS 367
“For” Loop Compilation
Goto Version result = 1;
Init; if (p == 0)
if (!Test) goto done;
goto done; loop:
loop: if (p & 0x1)
Body result *= x;
Update ; x = x*x;
if (Test) p = p >> 1;
goto loop; if (p != 0)
done: goto loop;
done:
Init Test
result = 1
Body
p != 0
{
if (p & 0x1)
Update result *= x;
p = p >> 1 x = x*x;
}
– 20 – CS 367
typedef enum Switch
{ADD, MULT, MINUS, DIV, MOD, BAD}
op_type; Statements
Implementation Options
char unparse_symbol(op_type op)
{
 Series of conditionals
switch (op) {  Good if few cases
case ADD :  Slow if many
return '+';  Jump Table
case MULT:  Lookup branch target
return '*';
 Avoids conditionals
case MINUS:
 Possible when cases are
return '-';
case DIV: small integer constants
return '/';  GCC
case MOD:  Picks one based on case
return '%'; structure
case BAD:
return '?';
 Bug in example code
}  No default given
}

– 21 – CS 367
Jump Table Structure
Switch Form Jump Table Jump Targets
switch(op) { jtab: Targ0 Targ0: Code Block
case val_0: 0
Targ1
Block 0
case val_1: Targ2
Targ1: Code Block
Block 1 •
• • • 1

case val_n-1: •
Block n–1 Targ2: Code Block
Targn-1
} 2


Approx. Translation •
target = JTab[op]; •
goto *target;
Targn-1: Code Block
n–1

– 22 – CS 367
Switch Statement Example
Branching Possibilities
Enumerated Values
typedef enum ADD 0
{ADD, MULT, MINUS, DIV, MOD, BAD} MULT 1
op_type; MINUS 2
DIV 3
char unparse_symbol(op_type op) MOD 4
{ BAD 5
switch (op) {
• • •
}
}

unparse_symbol:
pushl %ebp # Setup
movl %esp,%ebp # Setup
movl 8(%ebp),%eax # eax = op
Setup: cmpl $5,%eax # Compare op : 5
ja .L49 # If > goto done
jmp *.L57(,%eax,4) # goto
– 23 – Table[op] CS 367
Assembly Setup Explanation
Symbolic Labels
 Labels of form .LXX translated into addresses by assembler

Table Structure
 Each target requires 4 bytes
 Base address at .L57

Jumping
jmp .L49
 Jump target is denoted by label .L49
jmp *.L57(,%eax,4)
 Start of jump table denoted by label .L57
 Register %eax holds op
 Must scale by factor of 4 to get offset into table
 Fetch target from effective Address .L57 + op*4
– 24 – CS 367
Jump Table
Table Contents Targets & Completion
.section .rodata .L51:
.align 4 movl $43,%eax # ’+’
.L57: jmp .L49
.long .L51 .L52:
#Op = 0 movl $42,%eax # ’*’
.long .L52 jmp .L49
#Op = 1 .L53:
.long .L53 movl $45,%eax # ’-’
#Op = 2 jmp .L49
.long .L54 .L54:
Enumerated
#Op = 3 Values movl $47,%eax # ’/’
ADD 0
.long .L55 jmp .L49
#Op MULT
= 4 1 .L55:
MINUS 2
.long .L56 movl $37,%eax # ’%’
#Op DIV
= 53 jmp .L49
MOD 4 .L56:
BAD 5 movl $63,%eax # ’?’
# Fall Through to .L49
– 25 – CS 367
Switch Statement Completion
.L49: # Done:
movl %ebp,%esp # Finish
popl %ebp # Finish
ret # Finish

Puzzle
 What value returned when op is invalid?

Answer
 Register %eax set to op at beginning of procedure
 This becomes the returned value

Advantage of Jump Table


 Can do k-way branch in O(1) operations
– 26 – CS 367
Object Code
Setup
 Label .L49 becomes address 0x804875c
 Label .L57 becomes address 0x8048bc0
08048718 <unparse_symbol>:
8048718: 55 pushl %ebp
8048719: 89 e5 movl %esp,%ebp
804871b: 8b 45 08 movl 0x8(%ebp),%eax
804871e: 83 f8 05 cmpl $0x5,%eax
8048721: 77 39 ja 804875c
<unparse_symbol+0x44>
8048723: ff 24 85 c0 8b jmp *0x8048bc0(,%eax,4)

– 27 – CS 367
Object Code (cont.)
Jump Table
 Doesn’t show up in disassembled code
 Can inspect using GDB
gdb code-examples
(gdb) x/6xw 0x8048bc0
 Examine 6 hexadecimal format “words” (4-bytes each)
 Use command “help x” to get format documentation

0x8048bc0 <_fini+32>:
0x08048730
0x08048737
0x08048740
0x08048747
0x08048750
0x08048757
– 28 – CS 367
Extracting Jump Table from Binary
Jump Table Stored in Read Only Data Segment (.rodata)
 Various fixed values needed by your code

Can examine with objdump


objdump code-examples –s –-section=.rodata
 Show everything in indicated segment.

Hard to read
 Jump table entries shown with reversed byte ordering
Contents of section .rodata:
8048bc0 30870408 37870408 40870408 47870408 [email protected]...
8048bd0 50870408 57870408 46616374 28256429 P...W...Fact(%d)
8048be0 203d2025 6c640a00 43686172 203d2025 = %ld..Char = %

 E.g., 30870408 really means 0x08048730


– 29 – CS 367
Disassembled Targets
8048730:b8 2b 00 00 00 movl $0x2b,%eax
8048735:eb 25 jmp 804875c <unparse_symbol+0x44>
8048737:b8 2a 00 00 00 movl $0x2a,%eax
804873c:eb 1e jmp 804875c <unparse_symbol+0x44>
804873e:89 f6 movl %esi,%esi
8048740:b8 2d 00 00 00 movl $0x2d,%eax
8048745:eb 15 jmp 804875c <unparse_symbol+0x44>
8048747:b8 2f 00 00 00 movl $0x2f,%eax
804874c:eb 0e jmp 804875c <unparse_symbol+0x44>
804874e:89 f6 movl %esi,%esi
8048750:b8 25 00 00 00 movl $0x25,%eax
8048755:eb 05 jmp 804875c <unparse_symbol+0x44>
8048757:b8 3f 00 00 00 movl $0x3f,%eax

 movl %esi,%esi does nothing


 Inserted to align instructions for better cache performance

– 30 – CS 367
Matching Disassembled Targets

8048730:b8 2b 00 00 00 movl
8048735:eb 25 jmp
Entry 8048737:b8 2a 00 00 00 movl
0x08048730 804873c:eb 1e jmp
804873e:89 f6 movl
0x08048737 8048740:b8 2d 00 00 00 movl
0x08048740 8048745:eb 15 jmp
0x08048747 8048747:b8 2f 00 00 00 movl
0x08048750 804874c:eb 0e jmp
804874e:89 f6 movl
0x08048757
8048750:b8 25 00 00 00 movl
8048755:eb 05 jmp
8048757:b8 3f 00 00 00 movl

– 31 – CS 367
Sparse Switch Example
/* Return x/111 if x is multiple  Not practical to use
&& <= 999. -1 otherwise */ jump table
int div111(int x)  Would require 1000
{
entries
switch(x) {
case 0: return 0;  Obvious translation into
case 111: return 1; if-then-else would have
case 222: return 2; max. of 9 tests
case 333: return 3;
case 444: return 4;
case 555: return 5;
case 666: return 6;
case 777: return 7;
case 888: return 8;
case 999: return 9;
default: return -1;
}
}
– 32 – CS 367
Sparse Switch Code
movl 8(%ebp),%eax # get x  Compares x to possible
cmpl $444,%eax # x:444 case values
je L8
jg L16
 Jumps different places
cmpl $111,%eax # x:111 depending on outcomes
je L5
jg L17 . . .
testl %eax,%eax # x:0 L5:
je L4 movl $1,%eax
jmp L14 jmp L19
L6:
. . . movl $2,%eax
jmp L19
L7:
movl $3,%eax
jmp L19
L8:
movl $4,%eax
jmp L19
– 33 – . . . CS 367
Sparse Switch Code Structure
444
< >
=
4
111 777
< > < >
= =
1 7
0 222 555 888
 =  < >
= =  =
-1 0 2 5 8
333 666 999
 =  =  =
-1 3 -1 6 -1 9

 Organizes cases as binary tree


 Logarithmic performance

– 34 – CS 367
Summarizing
C Control Standard Techniques
 if-then-else  All loops converted to do-while
 do-while form
 while
 Large switch statements use jump
tables
 switch
Conditions in CISC
Assembler Control  CISC machines generally have
 jump condition code registers
 Conditional jump
Conditions in RISC
Compiler  Use general registers to store
 Must generate assembly condition information
code to implement more  Special comparison instructions
complex control  E.g., on Alpha:
cmple $16,1,$1
 Sets register $1 to 1 when
Register $16 <= 1

– 35 – CS 367

You might also like