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

Control flow - cs.wellesley.educs240/s17/slides/x86-control.pdf · Control flow Condition codes Conditional and unconditional jumps Loops Switch statements 1. Conditionals and Control

  • Upload
    others

  • View
    18

  • Download
    0

Embed Size (px)

Citation preview

  • Controlflow

    ConditioncodesConditionalandunconditionaljumpsLoopsSwitchstatements

    1

  • 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

  • 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

  • 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

  • 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

  • Jumpforcontrolflow

    7

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

    LabelNameforaddressof

    followingitem.

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

    Executedonlyif%rax ≠%rcx

  • 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

  • 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

  • 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;

    elseelsethen then

  • Choosealinearorderofbasicblocks.

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

    result = x-y;

    result = y-x;

    return result;

    Whymightthecompilerchoosethisbasicblockorderinsteadofanothervalidorder?

  • 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?

  • Executeabsdiff

    13

    %rax

    %rdi

    %rsi

    exRegisters

    cmpq %rsi, %rdijle Else

    subq %rsi, %rdimovq %rdi, %rax

    retq

    Else:

    End:

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

  • Note:CSAPPshowstranslationwithgoto

    14

    long goto_ad(long x,long y){int result;if (x y) {

    result = x-y;} else {

    result = y-x;}return result;

    }

  • Note:CSAPPshowstranslationwithgoto

    15

    long goto_ad(long x, long y){long result;if (x

  • 16

    http://xkcd.com/292/

    Butneverusegoto inyoursourcecode!

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

  • 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

  • CompilingLoops

    CompilationofotherloopsshouldbestraightforwardInterestingpart:puttheconditionalbranchat toporbottomofloop?

    20

    while ( sum != 0 ) {

    }

    loopTop: testq %rax, %raxje loopDone

    jmp loopTop

    loopDone:

    Machinecode:C/Javacode:

  • 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

  • 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

  • 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

  • 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

  • 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

  • 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 y ? x-y : y-x;

    }

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

    result = x-y;} else {

    result = y-x;}

    }

  • ExpensiveComputations

    (Aside)BadCasesforConditionalMove

    36

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

    RiskyComputationsval = p ? *p : 0;

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

  • 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

  • JumpTableStructure

    switch(x) {case 1:

    break;case 2: case 3:

    break;case 5:case 6:

    break;default:

    }

    38

    65432

    JumpTable

    CodeBlocks

    Memory

    Wecanusethejumptablewhenx

  • 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

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

  • 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

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

  • 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

  • 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

  • switch machinecodeSetup

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

    45

    00000000004004f6 :. . .4004fd: 77 2b ja 40052a 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 0x400506 0x4005e0: 0x40050e 0x400518

    0x4005f0: 0x40052a 0x400521 0x400600: 0x400521

  • 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 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:

  • ¢ Wouldyouimplementthiswithajumptable?

    ¢ Probablynot:§ Don’twanta jumptablewith52001entriesforonly4cases(toobig)§ about200KB=200,000bytes§ textofthisswitchstatement=about200bytes

    Question

    switch(x) {case 0:

    break;case 10:

    break;case 52000:

    break;default:

    break;}

    48

    ex