control flow - cs.wellesley.edu

36
Control flow Condition codes Conditional and unconditional jumps Loops Switch statements 1

Upload: others

Post on 18-Jan-2022

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Control flow - cs.wellesley.edu

Controlflow

ConditioncodesConditionalandunconditionaljumpsLoopsSwitchstatements

1

Page 2: Control flow - cs.wellesley.edu

ConditionalsandControlFlowTwokeypieces

1. Comparisonsandtests:checkconditions2. Transfercontrol:choosenextinstruction

FamiliarCconstructsl if elsel whilel do whilel forl breakl continue

2

Instructionpointer(a.k.a.programcounter)

registerholdsaddressofnextinstructiontoexecute

Conditioncodes (a.k.a.flags)1-bitregistersholdflagssetbylastALUoperation

ZeroFlag result==0

SignFlag result<0

CarryFlag carry-out/unsignedoverflow

OverflowFlag two'scomplementoverflow

%rip

CF

ZF

SF

OF

ProcessorControl-FlowState

Page 3: Control flow - cs.wellesley.edu

1.compare and test: conditionscmpq b,a computes a - b, setsflags,discardsresult

Whichflagsindicatethata < b ?(signed?unsigned?)

testq b,a computes a & b, setsflags,discardsresult

Commonpattern:testq %rax, %rax

WhatdoZF andSF indicate?

3

ex

Page 4: Control flow - cs.wellesley.edu

Aside:saveconditions

4

long gt(int x, int y) {return x > y;

}

cmpq %rdi,%rsi # compare: x – y

setg %al # al = x > y

movzbq %al,%rax # zero rest of %rax

Zero-extendfromByte(8bits)toQuadword (64bits)

setg:setifgreaterstoresbyte:

0x01if~(SF^OF)&~ZF0x00otherwise

%rax %eax %al%ah

Page 5: Control flow - cs.wellesley.edu

2.jump:choosenextinstructionJump/branch todifferentpartofcodebysetting%eip.

6

j__ 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

Page 6: Control flow - cs.wellesley.edu

Jumpforcontrolflow

7

cmpq %rax,%rcxje label………addq %rdx,%raxlabel:

LabelNameforaddressof

followingitem.

Jumpimmediatelyfollowscomparison/test.Together,theymakeadecision:"if%rax =%rcx ,jumptolabel."

Executedonlyif%rax ≠%rcx

Page 7: Control flow - cs.wellesley.edu

ConditionalBranch Example

8

long absdiff(long x,long y) {long result;if (x > y) {

result = x-y;} else {

result = y-x;}return result;

}

LabelsNameforaddressof

followingitem.

Howdidthecompilercreatethis?

absdiff:cmpq %rsi, %rdijle .L7subq %rsi, %rdimovq %rdi, %rax

.L8:retq

.L7:subq %rdi, %rsijmp .L8

Page 8: Control flow - cs.wellesley.edu

Control-FlowGraph

long absdiff(long x, long y){long result;if (x > y) {

result = x-y;} else {

result = y-x;}return result;

}

long result;if (x > y) else

result = x-y; result = y-x;

return result;

IntroducedbyFranAllen,etal.Wonthe2006TuringAwardforherworkoncompilers.

Nodes=BasicBlocks:Straight-linecodealwaysexecutedtogetherinorder.

Edges=ControlFlow:Whichbasicblockexecutesnext(underwhatcondition).

Codeflowchart/directedgraph.

then else

Page 9: Control flow - cs.wellesley.edu

Choosealinearorderofbasicblocks.

long result;if (x > y) else

result = x-y;

result = y-x;

return result;

long result;if (!(x > y))

result = y-x;

result = x-y;

return result;

elseelsethenthen

Page 10: Control flow - cs.wellesley.edu

Choosealinearorderofbasicblocks.

long result;if (!(x > y))

result = x-y;

result = y-x;

return result;

Whymightthecompilerchoosethisbasicblockorderinsteadofanothervalidorder?

Page 11: Control flow - cs.wellesley.edu

Translatebasicblockswithjumps+labels

cmpq %rsi, %rdijle Else

subq %rsi, %rdimovq %rdi, %rax

subq %rdi, %rsimovq %rsi, %raxjmp End

retq

Else:

End:

long result;if (!(x > y))

result = x-y;

result = y-x;

return result;

Whymightthecompilerchoosethisbasicblockorderinsteadofanothervalidorder?

Page 12: Control flow - cs.wellesley.edu

Executeabsdiff

13

%rax

%rdi

%rsi

exRegisters

cmpq %rsi, %rdijle Else

subq %rsi, %rdimovq %rdi, %rax

retq

Else:

End:

subq %rdi, %rsimovq %rsi, %raxjmp End

Page 13: Control flow - cs.wellesley.edu

Note:CSAPPshowstranslationwithgoto

14

long goto_ad(long x,long y){int result;if (x <= y) goto Else;result = x-y;

End:return result;

Else:result = y-x;goto End;

}

long absdiff(long x,long y){int result;if (x > y) {

result = x-y;} else {

result = y-x;}return result;

}

Page 14: Control flow - cs.wellesley.edu

Note:CSAPPshowstranslationwithgoto

15

long goto_ad(long x, long y){long result;if (x <= y) goto Else;result = x-y;

End:return result;

Else:result = y-x;goto End;

}

Closetoassemblycode.

cmpq %rsi, %rdijle Else

subq %rsi, %rdimovq %rdi, %rax

retq

Else:

End:

absdiff:

subq %rdi, %rsimovq %rsi, %raxjmp End

Page 15: Control flow - cs.wellesley.edu

16

http://xkcd.com/292/

Butneverusegoto inyoursourcecode!

Page 16: Control flow - cs.wellesley.edu

compileif-else ex

long wacky(long x, long y){int result;if (x + y > 7) {

result = x;} else {

result = y + 2;}return result;

}

Assumexavailablein%rdi,yavailablein%rsi.

Placeresultin%rax.

Page 17: Control flow - cs.wellesley.edu

EncodingJumps:PC-relativeaddressing

18

l PC-relativeoffsets supportrelocatablecode.l Absolutebranchesdonot(orit'shard).

0x100 cmpq %rax, %rbx 0x10000x102 je 0x70 0x10020x104 … 0x1004… … …0x174 addq %rax, %rbx 0x1074

Page 18: Control flow - cs.wellesley.edu

CompilingLoops

CompilationofotherloopsshouldbestraightforwardInterestingpart:puttheconditionalbranchat toporbottomofloop?

20

while ( sum != 0 ) {<loop body>

}

loopTop: testq %rax, %raxje loopDone

<loop body code>jmp loopTop

loopDone:

Machinecode:C/Javacode:

Page 19: Control flow - cs.wellesley.edu

CCodelong fact_do(long x) {

long result = 1;do {

result = result * x;x = x-1;

} while (x > 1);return result;

}

do while loopexample

21

Keys:• Usebackwardbranchtocontinuelooping• Onlytakebranchwhen“while”conditionholds

long result = 1;

result = result*x;x = x-1;

(x > 1) ?

return result;

YesNo

Page 20: Control flow - cs.wellesley.edu

do while looptranslation

22

Register Variable%rdi%rax

fact_do:movq $1,%rax

.L11:imulq %rdi,%raxdecq %rdicmpq $1,%rdijg .L11

retq

Assembly

Whyputtheloopconditionattheend?

Why?

long result = 1;

result = result*x;x = x-1;

(x > 1) ?

return result;

YesNo

Page 21: Control flow - cs.wellesley.edu

CCodelong fact_while(long x){

long result = 1;while (x > 1) {

result = result * x;x = x-1;

}return result;

}

while looptranslation

23

Why?

long result = 1;

result = result*x;x = x-1;

(x > 1) ?

return result;

long result = 1;

result = result*x;x = x-1;

(x > 1) ?

return result;

ThisorderisusedbyGCCforx86-64

YesNo

YesNo

Page 22: Control flow - cs.wellesley.edu

int fact_while(int x) {int result = 1;while (x > 1) {

result = result * x;x = x - 1;

};return result;

}

movq $1, %raxjmp .L34

.L35:imulq %rdi, %raxdecq %rdi

.L34:cmpq $1, %rdijg .L35

while loopexample

25

int result = 1;

result = result*x;x = x-1;

(x > 1) ?

return result;

YesNo

Page 23: Control flow - cs.wellesley.edu

for (result = 1; p != 0; p = p>>1) {if (p & 0x1) {

result = result * x;}x = x*x;

}

for looptranslation

31

for (Initialize; Test; Update)Body

ForVersion

Initialize;while (Test) {

Body ;Update;

}

WhileVersion

Initialize

BodyUpdate

Test ? YesNo

result = 1;

if (p & 0x1) {result = result*x;

}x = x*x;p = p>>1;

(p != 0) ? YesNo

Page 24: Control flow - cs.wellesley.edu

cmov src,dest if (Test) Destß SrcWhy?Branchpredictioninpipelined/OoO processors.

(Aside)ConditionalMove

35

absdiff:movq %rdi, %rax # xsubq %rsi, %rax # result = x-ymovq %rsi, %rdxsubq %rdi, %rdx # else_val = y-xcmpq %rsi, %rdi # x:ycmovle %rdx, %rax # if <=, result = else_valret

long absdiff(long x, long y) {return x>y ? x-y : y-x;

}

long absdiff(long x, long y) {long result;if (x>y) {

result = x-y;} else {

result = y-x;}

}

Page 25: Control flow - cs.wellesley.edu

ExpensiveComputations

(Aside)BadCasesforConditionalMove

36

val = Test(x) ? Hard1(x) : Hard2(x);

RiskyComputationsval = p ? *p : 0;

Computationswithsideeffectsval = x > 0 ? x*=7 : x+=3;

Page 26: Control flow - cs.wellesley.edu

long switch_eg (unsigned long 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;

}

switch statements

Fallthroughcases

Missingcases

Multiplecaselabels

Lotstomanage,let'suseajumptable

37

Page 27: Control flow - cs.wellesley.edu

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>

}

38

65432

JumpTable

CodeBlocks

Memory

Wecanusethejumptablewhenx <=6:

if (x <= 6)target = JTab[x];goto target;

elsegoto default;

Ccode:

10

Page 28: Control flow - cs.wellesley.edu

JumpTable

39

.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

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;

}

“quad”asin41978-era16-bitwords

declaringdata,notinstructions

8-bytememoryalignment

Page 29: Control flow - cs.wellesley.edu

switch statementexample

switch_eg:movq %rdx, %rcxcmpq $6, %rdija .L8jmp *.L4(,%rdi,8)

long switch_eg(long x, long y, long z) {long w = 1;switch(x) {

. . .}return w;

}

40

Jumptable.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

Indirectjump

Jumpifabove(likejg,butunsigned)

ex

butthisissigned...

Page 30: Control flow - cs.wellesley.edu

CodeBlocks(x==1)

.L3:movq %rsi, %rax # yimulq %rdx, %rax # y*zret

switch(x) {case 1: // .L3

w = y*z;break;

. . .}return w;

41

Compilerhas"inlined"thereturn.

Register Use(s)

%rdi Argumentx

%rsi Argumenty

%rdx Argumentz

%rax Returnvalue

Page 31: Control flow - cs.wellesley.edu

HandlingFall-Through

long w = 1;switch (x) {. . .case 2: // .L5

w = y/z;/* Fall Through */

case 3: // .L9w += z;break;

. . .}

case 3:w = 1;

case 2:w = y/z;goto merge;

merge:w += z;

42

Compilerhasinlined "w=1"onlywherenecessary.

Page 32: Control flow - cs.wellesley.edu

CodeBlocks(x==2,x==3)

.L5: # Case 2movq %rsi, %rax # y in raxcqto # Div prepidivq %rcx # y/zjmp .L6 # goto merge

.L9: # Case 3movl $1, %eax # w = 1

.L6: # merge:addq %rcx, %rax # w += zret

long w = 1;switch (x) {. . .

case 2: // .L5w = y/z;/* Fall Through */

case 3: // .L9w += z;break;

. . .}

43

Compilerhasinlined "w=1"onlywherenecessary.

Aside: movl isusedbecause1isasmallpositivevaluethatfitsin32bits.Highorderbitsof%rax getsettozeroautomatically.Ittakesonelessbytetoencodeamovl thanamovq.

Register Use(s)

%rdi Argumentx

%rsi Argumenty

%rdx Argumentz

%rax Returnvalue

Page 33: Control flow - cs.wellesley.edu

CodeBlocks(x==5,x==6,default)

.L7: # Case 5,6movl $1, %eax # w = 1subq %rdx, %rax # w -= zret

.L8: # Default:movl $2, %eax # 2ret

long w = 1;switch (x) {

. . .case 5: // .L7case 6: // .L7

w -= z;break;

default: // .L8w = 2;

}

44

Register Use(s)

%rdi Argumentx

%rsi Argumenty

%rdx Argumentz

%rax Returnvalue

Page 34: Control flow - cs.wellesley.edu

switch machinecodeSetup

Label.L8: 0x000000000040052a Label.L4: 0x00000000004005d0

45

00000000004004f6 <switch_eg>:. . .4004fd: 77 2b ja 40052a <switch_eg+0x34>4004ff: ff 24 fd d0 05 40 00 jmpq *0x4005d0(,%rdi,8)

switch_eg:. . .ja .L8jmp *.L4(,%rdi,8)

AssemblyCode

DisassembledObjectCode

InspectjumptableusingGDB.Examinecontentsas7 addressesUsecommand“help x”togetformatdocumentation

(gdb) x/7a 0x00000000004005d00x4005d0: 0x40052a <switch_eg+52> 0x400506 <switch_eg+16>0x4005e0: 0x40050e <switch_eg+24> 0x400518 <switch_eg+34>

0x4005f0: 0x40052a <switch_eg+52> 0x400521 <switch_eg+43>0x400600: 0x400521 <switch_eg+43>

Page 35: Control flow - cs.wellesley.edu

MatchingDisassembledTargets

47

400506: 48 89 f0 mov %rsi,%rax400509: 48 0f af c2 imul %rdx,%rax40050d: c3 retq40050e: 48 89 f0 mov %rsi,%rax400511: 48 99 cqto400513: 48 f7 f9 idiv %rcx400516: eb 05 jmp 40051d <switch_eg+0x27>400518: b8 01 00 00 00 mov $0x1,%eax40051d: 48 01 c8 add %rcx,%rax400520: c3 retq400521: b8 01 00 00 00 mov $0x1,%eax400526: 48 29 d0 sub %rdx,%rax400529: c3 retq40052a: b8 02 00 00 00 mov $0x2,%eax40052f: c3 retq

0x40052a0x4005060x40050e0x4005180x40052a0x4005210x400521

0x4005d0:

Sectionofdisassembledswitch_eg:

Jumptablecontents:

Page 36: Control flow - cs.wellesley.edu

¢ Wouldyouimplementthiswithajumptable?

¢ Probablynot:§ Don’twanta jumptablewith52001entriesforonly4cases(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;}

48

ex