Assembly part 2 / C part 1 1 was it zero? was it negative? etc. addq, subq, imulq, etc. set by (almost) all arithmetic instructions x86 has condition codes condition codes 3 demo pre-quiz — before next lecture post-quiz — after this lecture reminder: quiz 2 condition codes — last arithmetic result if/do-while to assembly lea — mov , but don’t do memory access jmp * destination last AT&T syntax dynamic linking (briefmy) difgerent kinds of relocations — addresses versus ofgset to addresses linking extras: last time 4 O(B, I, S) — B + I × S + O store info about last arithmetic result
condition codes and jumps jg , jle , etc. read condition codes cmpq %rax, %rbx movq $20, %rbx condition codes example (2) 7 testq %rax, %rax — result is %rax similar test does bitwise-and then what is cmp, etc.? “last arithmetic result”??? condition codes and cmpq 6 jle foo // not taken; 30 > 0 // result > 0: %rbx was > %rax movq $20, %rbx condition codes example (1) 5 0: equal; negative: less than; positive: greater than 8 movq $ − 10, %rax named based on interpreting result of subtraction subq %rax, %rbx // %rbx - %rax = 30 movq $ − 10, %rax jle foo // not taken; %rbx - %rax > 0 cmp does subtraction (but doesn’t store result)
omitting the cmp testq %rax, %rax — result is %rax foo // not taken, %rbx - %rax > 0 -> %rbx > %rax movq $20, %rbx je foo // taken, result is 0 // x - y = 0 -> x = y 10 what sets condition codes most instructions that compute something set condition codes some instructions only set condition codes: some instructions don’t change condition codes: subq %rax, %rbx lea , mov control fmow: jmp , call , ret , jle , etc. 11 condition codes examples (4) movq $20, %rbx movq $1, %rax // irrelevant je foo // taken, result is 0 20 + -20 = 0 — SF = 0 (not negative), ZF = 1 (zero) movq $99, %r12 // register for x jle movq $20, %rbx start_loop: start_loop: call foo subq $1, %r12 cmpq $0, %r12 jge start_loop // r12 >= 0? // or result >= 0? movq $99, %r12 // register for x 12 call foo subq $1, %r12 jge start_loop // old r12 >= 1? // or result >= 0? 9 condition codes example (3) movq $ − 10, %rax // compute r12 - 0 + sets cond. codes addq $ − 20, %rbx // new r12 = old r12 - 1 + sets cond. codes addq $ − 20, %rbx // result is 0 cmp ∼ sub test ∼ and (bitwise and — later)
while-to-assembly (1) start_loop: jmp start_loop 14 while exercise while ( b < 10) { foo (); b += 1; } Assume b is in callee-saved register %rbx. Which are correct assembly translations? // version A start_loop: call foo addq $1, %rbx cmpq $10, %rbx jl start_loop // version B cmpq $10, %rbx call foo jge end_loop call foo addq $1, %rbx jmp start_loop end_loop: // version C start_loop: movq $10, %rax subq %rbx, %rax jge end_loop call foo addq $1, %rbx jmp start_loop end_loop: subq $1, %r12 jl end_loop // jump if r12 - 0 >= 0 while ( x >= 0) { } foo () x --; } start_loop : if ( x < 0) goto end_loop ; foo () x --; goto start_loop : end_loop : 13 while-to-assembly (1) while ( x >= 0) { foo () x --; start_loop : cmpq $0, %r12 if ( x < 0) goto end_loop ; foo () x --; goto start_loop : end_loop : 13 while-to-assembly (2) start_loop : if ( x < 0) goto end_loop ; foo () x --; goto start_loop : end_loop : start_loop: 15
b += 1; while to assembly (1) start_loop: ... ... end_loop: jmp start_loop addq $1, %rbx call foo jge end_loop cmpq $10, %rbx while — levels of optimization while ( b < 10) { foo (); b += 1; } ... 17 end_loop: movq $10, %rbx jne start_loop decq %rbx call foo start_loop: movq %rax, %rbx ... jge end_loop cmpq $10, %rbx jge end_loop end_loop: movq $10, %rbx jne start_loop decq %rbx call foo start_loop: movq %rax, %rbx subq %rbx, %rax movq $10, %rax cmpq $10, %rbx movq $10, %rax ... ... ... end_loop: jne start_loop cmpq $10, %rbx addq $1, %rbx call foo start_loop: subq %rbx, %rax jge end_loop while ( b < 10) { foo (); while ( b < 10) { foo (); b += 1; } while — levels of optimization 16 end_loop : goto start_loop ; foo (); start_loop : if ( b < 10) goto end_loop ; } while ( b < 10) { cmpq $10, %rbx while to assembly (1) 16 end_loop : goto start_loop ; foo (); start_loop : if ( b < 10) goto end_loop ; } foo (); cmpq $10, %rbx start_loop: jge end_loop call foo ... ... ... end_loop: jne start_loop cmpq $10, %rbx addq $1, %rbx call foo start_loop: jge end_loop cmpq $10, %rbx ... ... ... ... end_loop: jmp start_loop addq $1, %rbx 17 b += 1; b += 1; b += 1;
while — levels of optimization set by cmp, test, arithmetic decq %rbx jne start_loop movq $10, %rbx end_loop: 17 condition codes: closer look x86 condition codes: (“carry fmag”) — did computation overfmow (as unsigned)? (“overfmow fmag”) — did computation overfmow (as signed)? (and some more, e.g. to handle overfmow) GDB: part of “efmags” register 18 start_loop: condition codes example (2) movq $20, %rbx cmpq %rax, %rbx %rbx - %rax = 30 — SF = 0 (not negative), ZF = 0 (not zero) 19 condition codes examples (4) movq $20, %rbx movq $1, %rax // irrelevant je foo // taken, result is 0 20 + -20 = 0 — SF = 0 (not negative), ZF = 1 (zero) while ( b < 10) { foo (); b += 1; } call foo movq %rax, %rbx subq %rbx, %rax start_loop: cmpq $10, %rbx jge end_loop call foo addq $1, %rbx jmp start_loop end_loop: ... ... ... ... cmpq $10, %rbx jge end_loop start_loop: call foo movq $10, %rax jge end_loop cmpq $10, %rbx ... ... ... end_loop: cmpq $10, %rbx jne start_loop addq $1, %rbx 20 ZF (“zero fmag”) — was result zero? (sub/cmp: equal) SF (“sign fmag”) — was result negative? (sub/cmp: less) movq $ − 10, %rax addq $ − 20, %rbx // result is 0 jle foo // not taken; %rbx - %rax > 0
condition codes: closer look rax and rbx not equal 22 closer look: condition codes (1) movq $20, %rbx cmpq %rax, %rbx x86 condition codes: not zero 22 not zero closer look: condition codes (1) movq $20, %rbx cmpq %rax, %rbx // result = %rbx - %rax = 30 not zero rax and rbx not equal not negative rax and rbx not equal // result = %rbx - %rax = 30 22 cmpq %rax, %rbx (and one more) GDB: part of “efmags” register set by cmp, test, arithmetic 21 movq $20, %rbx closer look: condition codes (1) // result = %rbx - %rax = 30 movq $ − 10, %rax ZF (“zero fmag”) — was result zero? (sub/cmp: equal) SF (“sign fmag”) — was result negative? (sub/cmp: less) CF (“carry fmag”) — did computation overfmow (as unsigned)? OF (“overfmow fmag”) — did computation overfmow (as signed)? as signed: 20 − ( − 10) = 30 ❳❳❳❳❳❳ ✘ as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) ❳ ZF = 0 (false) movq $ − 10, %rax movq $ − 10, %rax as signed: 20 − ( − 10) = 30 as signed: 20 − ( − 10) = 30 ❳❳❳❳❳❳ ✘ ❳❳❳❳❳❳ ✘ as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) ❳ ❳ ZF = 0 (false) ZF = 0 (false) SF = 0 (false) rax < = rbx
closer look: condition codes (1) ? not negative no overfmow as signed correct for signed overfmow as unsigned 22 exercise: condition codes (2) // 2^63 - 1 movq $0x7FFFFFFFFFFFFFFF, %rax // 2^63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx cmpq %rax, %rbx // result = %rbx - %rax ? not zero ? ? 23 closer look: condition codes (2) // 2**63 - 1 movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx cmpq %rax, %rbx // result = %rbx - %rax not zero rax and rbx not equal rax and rbx not equal incorrect for unsigned 24 movq $20, %rbx movq $20, %rbx not zero not negative cmpq %rax, %rbx no overfmow as signed // result = %rbx - %rax = 30 correct for signed 22 // result = %rbx - %rax = 30 closer look: condition codes (1) cmpq %rax, %rbx rax and rbx not equal movq $ − 10, %rax movq $ − 10, %rax as signed: 20 − ( − 10) = 30 as signed: 20 − ( − 10) = 30 ❳❳❳❳❳❳ ✘ ❳❳❳❳❳❳ ✘ as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) ❳ ❳ ZF = 0 (false) ZF = 0 (false) SF = 0 (false) rax < = rbx SF = 0 (false) rax < = rbx OF = 0 (false) OF = 0 (false) CF = 1 (true) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ ZF = = ✘✘✘✘✘ ❳ SF = as unsigned: 2 63 − 2 63 − 1 � � = 1 OF = CF = ZF = 0 (false)
Recommend
More recommend