Controlflow
ConditioncodesConditionalandunconditional jumpsLoopsSwitchstatements
1
Conditionals andControlFlowFamiliarCconstructs
l if elsel whilel do whilel forl breakl continue
Twokeypieces1. Comparisonsandtests:checkconditions2. Transfercontrol:choosenextinstruction
2
Condition codes (a.k.a.flags)1-bitregistersholdflagssetbylastALUoperation
ZeroFlag result==0
SignFlag result<0
CarryFlag carry-out/unsignedoverflow
OverflowFlag two'scomplementoverflow
ProcessorControl-FlowState
3
%eip Instructionpointer(a.k.a.programcounter)
registerholdsaddressofnextinstructiontoexecute
CF
ZF
SF
OF
1.compare and test: conditionscmpl b,a computes a - b, setsflags,discardsresult
Whichflagsindicatethata < b ?(signed?unsigned?)
testl b,a computes a & b, setsflags,discardsresult
Commonpattern:testl %eax, %eax
WhatdoZF andSF indicate?
5
ex
Aside:saveconditions
6
int gt (int x, int y) {return x > y;
}
movl 12(%ebp),%eax # eax = y
cmpl %eax,8(%ebp) # compare: x – y
setg %al # al = x > y
movzbl %al,%eax # zero rest of %eax
%eax %al%ah
Zero-extendfromByte(8bits)toLongword (32bits)
setg:setifgreaterstoresbyte:
0x01if~(SF^OF)&~ZF0x00otherwise
2.jump:choosenextinstructionJump/branch todifferentpartofcodebysetting%eip.
8
jX Condition Descriptionjmp 1 Unconditionalje ZF Equal/Zerojne ~ZF NotEqual/NotZerojs SF Negativejns ~SF Nonnegativejg ~(SF^OF)&~ZF Greater(Signed)jge ~(SF^OF) GreaterorEqual (Signed)jl (SF^OF) Less(Signed)jle (SF^OF)|ZF LessorEqual (Signed)ja ~CF&~ZF Above(unsigned)jb CF Below(unsigned)
Alwaysjump
Jumpiff condition
Jumpforcontrolflow
9
cmpl %eax,%ebxje label………addl %edx,%eaxlabel:
LabelNameforaddressoffollowinginstruction.
Jumpimmediately followscomparison/test.Together, theymakeadecision:"if%eax =%ebx ,jumptolabel."
Executed onlyif%eax ≠%ebx
ConditionalBranch Example
10
int absdiff(int x,int y) {int result;if (x > y) {
result = x-y;} else {
result = y-x;}return result;
} Body
Setup
Finish
Body
LabelsNameforaddress offollowinginstruction.
Howdidthecompilercreatethis?
absdiff:pushl %ebpmovl %esp, %ebpmovl 8(%ebp), %edxmovl 12(%ebp), %eaxcmpl %eax, %edxjle .L7subl %eax, %edxmovl %edx, %eax
.L8:leaveret
.L7:subl %edx, %eaxjmp .L8
Control-FlowGraph
int absdiff(int x, int y) {int result;if (x > y) {
result = x-y;} else {
result = y-x;}return result;
}
int result;if (x > y) else
result = x-y; result = y-x;
return result;
IntroducedbyFranAllen,etal.Wonthe2006TuringAwardforherworkoncompilers.
Nodes=BasicBlocks:Straight-linecodealwaysexecuted together inorder.
Edges=ControlFlow:Whichbasicblockexecutesnext(underwhatcondition).
Codeflowchart/directed graph.
then else
Choosealinearorderofbasicblocks.
int result;if (x > y) else
result = x-y;
result = y-x;
return result;
int result;if (!(x > y))
result = y-x;
result = x-y;
return result;
Choosealinearorderofbasicblocks.
int result;if (!(x > y))
result = x-y;
result = y-x;
return result;
Whymightthecompiler choosethisbasicblockorderinsteadofanothervalidorder?
Translatebasicblockswithjumps+labelspushl %ebpmovl %esp, %ebpmovl 8(%ebp), %edxmovl 12(%ebp), %eaxcmpl %eax, %edxjle Else
subl %eax, %edxmovl %edx, %eax
subl %edx, %eaxjmp End
leaveret
Else:
End:
int result;if (!(x > y))
result = x-y;
result = y-x;
return result;
Whymightthecompiler choosethisbasicblockorderinsteadofanothervalidorder?
Executeabsdiff
15
123
456
Returnaddr
…%ebp 0
4
8
12
Offsetfrom%ebp
…-4
…
…
(Address)
0x118
0x114
0x110
0x10c
0x108
0x104
0x100
%eax
%edx
%esp
%ebp 0x104
expushl %ebpmovl %esp, %ebpmovl 8(%ebp), %edxmovl 12(%ebp), %eaxcmpl %eax, %edxjle Else
subl %eax, %edxmovl %edx, %eax
subl %edx, %eaxjmp End
leaveret
Else:
End:Stophere.Whatisin%eax?
Starthere.
Memory
Registers
Note:CSAPPshowstranslationwithgoto
16
int goto_ad(int x, int y) {int result;if (x <= y) goto Else;result = x-y;
End:return result;
Else:result = y-x;goto End;
}
int absdiff(int x, int y) {int result;if (x > y) {
result = x-y;} else {
result = y-x;}return result;
}
Note:CSAPPshowstranslationwithgoto
17
int goto_ad(int x, int y) {int result;if (x <= y) goto Else;result = x-y;
End:return result;
Else:result = y-x;goto End;
}
absdiff:pushl %ebpmovl %esp, %ebpmovl 8(%ebp), %edxmovl 12(%ebp), %eaxcmpl %eax, %edxjle .L7subl %eax, %edxmovl %edx, %eax
.L8:leaveret
.L7:subl %edx, %eaxjmp .L8
Body
Setup
Finish
Body
Closetoassemblycode.
18
http://xkcd.com/292/
Butneverusegoto inyoursourcecode!
compile if-else ex
int wacky(int x, int y) {int result;if (x + y > 7) {
result = x;} else {
result = y + 2;}return result;
}
Assumexavailable in8(%ebp),yavailable in12(%ebp).
Placeresultin%eax.
PC-relativeaddressing
26
l Jumpinstructionencodesoffset fromnextinstructiontodestinationPC.
l (Nottheabsoluteaddressofthedestination.)l PCrelative branchesare relocatablel Absolutebranches arenot(or theytakealotworktorelocate)
0x100 cmp %eax, %ebx 0x10000x102 je 0x70 0x10020x104 … 0x1004… … …0x174 add %eax, %ebx 0x1074
PC-relativeaddressing00000000 <absdiff>:0: 55 push %ebp1: 89 e5 mov %esp,%ebp3: 83 ec 10 sub $0x10,%esp6: 8b 45 08 mov 0x8(%ebp),%eax9: 3b 45 0c cmp 0xc(%ebp),%eaxc: 7e 0b jle 19 <absdiff+0x19>e: 8b 45 08 mov 0x8(%ebp),%eax11: 2b 45 0c sub 0xc(%ebp),%eax14: 89 45 fc mov %eax,-0x4(%ebp)17: eb 09 jmp 22 <absdiff+0x22>19: 8b 45 0c mov 0xc(%ebp),%eax1c: 2b 45 08 sub 0x8(%ebp),%eax1f: 89 45 fc mov %eax,-0x4(%ebp)22: 8b 45 fc mov -0x4(%ebp),%eax25: c9 leave 26: c3 ret
Howarethejumptargetsencoded?Why?
objdump output:
Compiling Loops
HowtocompileotherloopsshouldbestraightforwardTheonlyslightlytrickypartistowhere toputtheconditionalbranch:toporbottomoftheloop
28
while ( sum != 0 ) {<loop body>
}
loopTop: cmpl $0, %eaxje loopDone
<loop body code>jmp loopTop
loopDone:
Machinecode:C/Javacode:
CCodeint fact_do(int x) {int result = 1;do {
result = result * x;x = x-1;
} while (x > 1);return result;
}
“Do-While”LoopExample
30
Keys:• Usebackwardbranch tocontinuelooping• Onlytakebranchwhen“while”conditionholds
int result = 1;
result = result*x;x = x-1;
(x > 1) ?
return result;
CCodeint fact_do(int x) {int result = 1;do {
result = result * x;x = x-1;
} while (x > 1);return result;
}
Goto Versionint fact_goto(int x) {int result = 1;
loop:result = result * x;x = x-1;if (x > 1) goto loop;return result;
}
“Do-While”LoopExample
31
Keys:• Usebackwardbranch tocontinuelooping• Onlytakebranchwhen“while”conditionholds
Goto Versionint fact_goto(int x) {int result = 1;
loop:result = result * x;x = x-1;if (x > 1)
goto loop;
return result;}
“Do-While”LoopCompilation
32
Register Variable%edx%eax
fact_goto:pushl %ebp # Setupmovl %esp,%ebp # Setupmovl $1,%eax # eax = 1movl 8(%ebp),%edx # edx = x
.L11:imull %edx,%eax # result *= xdecl %edx # x--cmpl $1,%edx # Compare x : 1jg .L11 # if > goto loop
movl %ebp,%esp # Finishpopl %ebp # Finishret # Finish
Assembly
Translation?Whyputthe loopcondition attheend?
Why?
CCodedo
Bodywhile (Test);
Goto Versionloop:
Bodyif (Test)goto loop
General“Do-While”Translation
Body:
Test returns integer=0interpreted asfalse≠ 0interpreted astrue
{Statement1;Statement2;
…Statementn;
}
33
CCodeint fact_while(int x) {int result = 1;while (x > 1) {
result = result * x;x = x-1;
}return result;
}
“While”LoopTranslation
34
Why?
int result = 1;
result = result*x;x = x-1;
(x > 1) ?
return result;
int result = 1;
result = result*x;x = x-1;
(x > 1) ?
return result;
CCodeint fact_while(int x) {int result = 1;while (x > 1) {
result = result * x;x = x-1;
}return result;
}
Goto Versionint fact_while_goto(int x) {int result = 1;goto middle;
loop:result = result * x;x = x-1;
middle:if (x > 1)
goto loop;return result;
}
“While”LoopTranslation
Thisorder isusedbyGCCforbothIA32andx86-64Testatend,firstiteration jumpsoverbody totest.
35
Why?
int result = 1;
result = result*x;x = x-1;
(x > 1) ?
return result;
int fact_while(int x) {int result = 1;while (x > 1) {
result = result * x;x = x - 1;
};return result;
}
# x in %edx, result in %eaxjmp .L34 # goto Middle
.L35: # Loop:imull %edx, %eax # result *= xdecl %edx # x--
.L34: # Middle:cmpl $1, %edx # x:1jg .L35 # if >, goto
# Loop
“While”LoopExample
36
int result = 1;
result = result*x;x = x-1;
(x > 1) ?
return result;
“For”LoopExample:Square-and-Multiply
AlgorithmExploitbitrepresentation: p = p0 + 2p1 + 22p2 + … 2n–1pn–1
Gives:xp = z0 · z12 · (z2
2) 2 · … · (…((zn –12) 2 )…) 2
zi = 1 whenpi = 0zi = x whenpi = 1
ComplexityO(log p) = O(sizeof(p))
/* Compute x raised to nonnegative power p */int power(int x, unsigned int p) {
int result;for (result = 1; p != 0; p = p>>1) {
if (p & 0x1) {result = result * x;
}x = x*x;
}return result;
}
n–1times
Example
310 = 32 *38
=32 *((32)2)2
37
xm *xn =xm+n
0 ...0 11 0 1 =1312^31 *...*116 *x8 * x4 *12 *x1 =x13
1=x0 x=x1
[optional]
power Computation/* Compute x raised to nonnegative power p */int power(int x, unsigned int p) {
int result;for (result = 1; p != 0; p = p>>1) {
if (p & 0x1) {result = result * x;
}x = x*x;
}return result;
}
beforeiteration result x=3 p=101 1 3 10=101022 1 9 5= 10123 9 81 2= 1024 9 6561 1= 125 59049 43046721 02
38
[optional]
“For”LoopExample
for (Initialize; Test; Update)Body
for (int result = 1; p != 0; p = p>>1) {if (p & 0x1) {
result = result * x;}x = x*x;
}
GeneralForm
Initresult = 1
Testp != 0
Updatep = p >> 1
Body{if (p & 0x1) {
result = result*x;}x = x*x;
} 39
“For”→ “While”
for (Initialize; Test; Update )
Body
Initialize;while (Test ) {
BodyUpdate ;
}
Initialize;goto middle;
loop:BodyUpdate ;
middle:if (Test)goto loop;
done:
WhileVersion
ForVersion
Goto Version
40
derive
For-Loop:Compilationfor (result = 1; p != 0; p = p>>1) {if (p & 0x1) {result = result * x;
}x = x*x;
}
result = 1;goto middle;
loop:if (p & 0x1)result *= x;
x = x*x;p = p >> 1;
middle:if (p != 0)goto loop;
done:41
for (Initialize; Test; Update )
Body
ForVersion
Initialize;goto middle;
loop:BodyUpdate ;
middle:if (Test)goto loop;
done:
Goto Version
derive
Review
ProcessorState
Memoryaddressingmodes(%eax)
17(%eax)
12(%edx, %eax)
2(%ebx, %ecx, 8)
Immediate(constant),Register,andMemoryOperandssubl %eax, %ecx # ecx = ecx + eax
sall $4,%edx # edx = edx << 4
addl 16(%ebp),%ecx # ecx = ecx + Mem[16+ebp]
imull %ecx,%eax # eax = eax * ecx
42
%eip
CurrentstacktopCurrentstackframe
Instructionpointer
CF ZF SF OF Conditioncodes
%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
Generalpurposeregisters
Review
Control1-bitconditioncode/flag registersSetbyarithmetic instructions (addl,shll,etc.), cmp, testAccess flagswithsetg, setle,…instructions
Conditional jumps use flagsfordecisions (jle .L4, je .L10, …)Unconditional jumps alwaysjump:jmpDirectorindirect jumps
Standard TechniquesLoopsconvertedtodo-whileformLargeswitchstatements usejumptables
43
CF ZF SF OFcarry signzero overflow
ReviewDo-Whileloop
While-Doloop
CCodedo
Bodywhile (Test);
Goto Versionloop:
Bodyif (Test)goto loop
Whileversionwhile (Test)Body
Do-WhileVersionif (!Test) goto done;
doBodywhile(Test);
done:
Goto Versionif (!Test)goto done;
loop:Bodyif (Test)goto loop;
done:
goto middle;loop:
Bodymiddle:if (Test)goto loop;
or
44
SwitchStatements
MultiplecaselabelsHere:5,6
FallthroughcasesHere:2
MissingcasesHere:4
Lotstomanage,weneedajumptable
long switch_eg (unsignedlong x, long y, long z) {long w = 1;switch(x) {case 1:
w = y*z;break;
case 2:w = y/z;/* Fall Through */
case 3:w += z;break;
case 5:case 6:
w -= z;break;
default:w = 2;
}return w;
}
45
JumpTableStructure
CodeBlock0
Targ0:
CodeBlock1
Targ1:
CodeBlock2
Targ2:
CodeBlockn–1
Targn-1:
•••
Targ0
Targ1
Targ2
Targn-1
•••
JTab:
target = JTab[x];goto target;
switch(x) {case val_0:
Block 0case val_1:
Block 1• • •
case val_n-1:Block n–1
}
SwitchForm
ApproximateTranslation
JumpTable JumpTargets
46
JumpTableStructure
switch(x) {case 1: <some code>
break;case 2: <some code>case 3: <some code>
break;case 5:case 6: <some code>
break;default: <some code>
}
47
65432
JumpTable
CodeBlocks
Memory
Wecanusethe jumptablewhenx <=6:
if (x <= 6)target = JTab[x];goto target;
elsegoto default;
Ccode:
10
JumpTable(IA32)
.section .rodata.align 4
.L62:.long .L61 # x = 0.long .L56 # x = 1.long .L57 # x = 2.long .L58 # x = 3.long .L61 # x = 4.long .L60 # x = 5.long .L60 # x = 6
Jumptableswitch(x) {case 1: // .L56
w = y*z;break;
case 2: // .L57w = y/z;/* Fall Through */
case 3: // .L58w += z;break;
case 5:case 6: // .L60
w -= z;break;
default: // .L61w = 2;
}
48
“long”asinmovl:4bytes
declaringdata,notinstructions
4-bytememoryalignment
SwitchStatementExample(IA32)
Setup: switch_eg:pushl %ebp # Setupmovl %esp, %ebp # Setuppushl %ebx # Setupmovl $1, %ebx # w = 1movl 8(%ebp), %edx # edx = xmovl 16(%ebp), %ecx # ecx = zcmpl $6, %edx # x:6ja .L61 # if > goto defaultjmp *.L62(,%edx,4) # goto JTab[x]
long switch_eg(unsigned long x, long y,long z) {long w = 1;switch(x) {
. . .}return w;
}
Translation? 49
Jumptable.section .rodata
.align 4.L62:
.long .L61 # x = 0
.long .L56 # x = 1
.long .L57 # x = 2
.long .L58 # x = 3
.long .L61 # x = 4
.long .L60 # x = 5
.long .L60 # x = 6
ex
SwitchStatementExample(IA32)
Setup: switch_eg:pushl %ebp # Setupmovl %esp, %ebp # Setuppushl %ebx # Setupmovl $1, %ebx # w = 1movl 8(%ebp), %edx # edx = xmovl 16(%ebp), %ecx # ecx = zcmpl $6, %edx # x:6ja .L61 # if > 6 goto
defaultjmp *.L62(,%edx,4) # goto JTab[x]
Indirectjump
Jumptable.section .rodata
.align 4.L62:
.long .L61 # x = 0
.long .L56 # x = 1
.long .L57 # x = 2
.long .L58 # x = 3
.long .L61 # x = 4
.long .L60 # x = 5
.long .L60 # x = 6
50
long switch_eg(unsigned long x, long y,long z) {long w = 1;switch(x) {
. . .}return w;
}
jumpabove(likejg,butunsigned)
AssemblySetupExplanation (IA32)TableStructure
Eachtarget requires 4bytesBaseaddressat.L62
JumptargetaddressmodesDirect: jmp .L61Jumptarget isdenotedbylabel.L61
Indirect: jmp *.L62(,%edx,4)Startofjumptable:.L62Mustscalebyfactorof4(labelsare32-bits=4bytesonIA32)Fetchtarget fromeffective address .L62 + edx*4
target = JTab[x]; goto target; (onlyfor0≤ x ≤ 6)
.section .rodata.align 4
.L62:.long .L61 # x = 0.long .L56 # x = 1.long .L57 # x = 2.long .L58 # x = 3.long .L61 # x = 4.long .L60 # x = 5.long .L60 # x = 6
Jumptable
51
CodeBlocks(Partial).L61: // Default case
movl $2, %ebx # w = 2jmp .L63
.L57: // Case 2:movl 12(%ebp), %eax # ycltd # Div prepidivl %ecx # y/z movl %eax, %ebx # w = y/z
# Fall through – no jmp.L58: // Case 3:
addl %ecx, %ebx # w+= zjmp .L63
...
.L63movl %ebx, %eax # return wpopl %ebxleaveret
switch(x) {. . .
case 2: // .L57w = y/z;/* Fall Through */
case 3: // .L58w += z;break;
. . .default: // .L61
w = 2;}return w;
52
CodeBlocks(Rest)
.L60: // Cases 5&6:subl %ecx, %ebx # w –= zjmp .L63
.L56: // Case 1:movl 12(%ebp), %ebx # w = yimull %ecx, %ebx # w*= zjmp .L63
...
.L63movl %ebx, %eax # return wpopl %ebxleaveret
switch(x) {case 1: // .L56
w = y*z;break;
. . .case 5:case 6: // .L60
w -= z;break;
. . .}return w;
53
CodeBlocks(Partial,returninlined).L61: // Default case
movl $2, %ebx # w = 2movl %ebx, %eax # Return wpopl %ebxleaveret
.L57: // Case 2:movl 12(%ebp), %eax # ycltd # Div prepidivl %ecx # y/z movl %eax, %ebx # w = y/z
# Fall through – no jmp.L58: // Case 3:
addl %ecx, %ebx # w+= zmovl %ebx, %eax # Return wpopl %ebxleaveret
switch(x) {. . .
case 2: // .L57w = y/z;/* Fall Through */
case 3: // .L58w += z;break;
. . .default: // .L61
w = 2;}
54
Thecompilermightchoose topull thereturnstatement intoeachrelevantcaseratherthanjumpingouttoit.
CodeBlocks(Rest,returninlined)
.L60: // Cases 5&6:subl %ecx, %ebx # w –= zmovl %ebx, %eax # Return wpopl %ebxleaveret
.L56: // Case 1:movl 12(%ebp), %ebx # w = yimull %ecx, %ebx # w*= zmovl %ebx, %eax # Return wpopl %ebxleaveret
switch(x) {case 1: // .L56
w = y*z;break;
. . .case 5:case 6: // .L60
w -= z;break;
. . .}
55
Thecompilermightchoose topull thereturnstatement intoeachrelevantcaseratherthanjumpingouttoit.
SwitchmachinecodeSetup
Label.L61willmeanaddress0x08048630Label.L62willmeanaddress0x080488dc
08048610 <switch_eg>:. . .08048622: 77 0c ja 8048630 08048624: ff 24 95 dc 88 04 08 jmp *0x80488dc(,%edx,4)
switch_eg:. . .ja .L61 # if > goto defaultjmp *.L62(,%edx,4) # goto JTab[x]
AssemblyCode
DisassembledObjectCode
56
SwitchmachinecodeJumpTable
Doesn’t showupindisassembled codeCaninspectusingGDBifweknowitsaddress.(gdb) x/7xw 0x080488dc
Examine7 hexadecimal format“words”(4byteseach)Usecommand“help x”togetformatdocumentation
0x080488dc:0x080486300x080486500x0804863a0x080486420x080486300x080486490x08048649
57
MatchingDisassembled Targets8048630: bb 02 00 00 00 mov8048635: 89 d8 mov8048637: 5b pop8048638: c9 leave8048639: c3 ret804863a: 8b 45 0c mov804863d: 99 cltd804863e: f7 f9 idiv8048640: 89 c3 mov8048642: 01 cb add8048644: 89 d8 mov8048646: 5b pop8048647: c9 leave8048648: c3 ret8048649: 29 cb sub804864b: 89 d8 mov804864d: 5b pop804864e: c9 leave804864f: c3 ret8048650: 8b 5d 0c mov8048653: 0f af d9 imul8048656: 89 d8 mov8048658: 5b pop8048659: c9 leave804865a: c3 ret
0x08048630
0x08048650
0x0804863a
0x08048642
0x08048630
0x08048649
0x08048649
58
0x080488dc:
¢ Wouldyouimplementthiswithajumptable?
¢ Probablynot:§ Don’twanta jumptablewith52001entries foronly4cases (toobig)§ about200KB=200,000bytes§ textofthisswitchstatement =about200bytes
Question
switch(x) {case 0: <some code>
break;case 10: <some code>
break;case 52000: <some code>
break;default: <some code>
break;}
59
ex