assembly / ISAs strategy — write with gotos fjrst leaq (%rax, %rax, 2), %rax subq %rsp, %rax # memory[%rsp] = %rax pushq %rax movq %rsp, %rax the quiz: ASM 2 …more detail today result = 0: equal; result positive: greater; result negative: less than names based on subtraction (cmp) used by conditional jump set by arithmetic instructions + cmp or test 1 condition codes C to assembly 5 September 2017: slide 14: fjx bugs in third version: compare to 10 Changelog Changes made in this version not seen in fjrst lecture: 5 September 2017: slide 3: lea destination should have been rax, not rsp mov RBX, QWORD PTR [RAX + RCX * 4] 5 September 2017: slide 12: changed version B and C to use jge 3 (not 9), end with %rbx set 8 September 2017: slide 11: use %rax, not %rbx 1 last time AT&T syntax movq (%rax,%rcx,4), %rbx = 5 September 2017: slide 10: signed result w/o truncation is − 2 64 + 1 , not − 2 64 − 1 # %rax ← %rsp = X # %rsp ← %rsp - 8 = X - 8 # %rax ← %rax - %rsp = X - (X - 8) = 8 # %rax ← %rax + %rax * 2 = 8 + 8 * 2 = 24
upcoming labs names based on subtraction (cmp) set by cmp, test, arithmetic GDB: part of “efmags” register (and one more we won’t talk about) x86 condition codes: condition codes: closer look 6 positive: greater than negative: less than zero: equal jg , jle , etc condition codes and jumps 5 this week: pointer-heavy code in C result = 0: equal; result positive: greater; result negative: less than …more detail today used by conditional jump last time use tool to fjnd malloc/free-related mistakes fjx broken circular doubly-linked list implementation next week: in-lab quiz implement library functions strlen/strsep no notes set by arithmetic instructions + cmp or test 4 AT&T syntax movq (%rax,%rcx,4), %rbx = mov RBX, QWORD PTR [RAX + RCX * 4] C to assembly strategy — write with gotos fjrst condition codes 7 ZF (“zero fmag”) — was result zero? (sub/cmp: equal) SF (“sign fmag”) — was result negative? (sub/cmp: less) named based on interpreting result of subtraction CF (“carry fmag”) — did computation overfmow (as unsigned)? OF (“overfmow fmag”) — did computation overfmow (as signed)?
closer look: condition codes (1) 8 8 closer look: condition codes (1) movq $20, %rbx cmpq %rax, %rbx not zero rax and rbx not equal not negative closer look: condition codes (1) not zero movq $20, %rbx cmpq %rax, %rbx // result = %rbx - %rax = 30 not zero rax and rbx not equal not negative no overfmow as signed correct for signed rax and rbx not equal // result = %rbx - %rax = 30 8 movq $20, %rbx movq $20, %rbx cmpq %rax, %rbx // result = %rbx - %rax = 30 rax and rbx not equal 8 closer look: condition codes (1) not zero cmpq %rax, %rbx // result = %rbx - %rax = 30 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) 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)
closer look: condition codes (1) // result = %rbx - %rax // result = %rbx - %rax ? ? ? ? 9 closer look: condition codes (2) // 2**63 - 1 movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx not zero movq $0x8000000000000000, %rbx rax and rbx not equal 10 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 cmpq %rax, %rbx cmpq %rax, %rbx // 2^63 (unsigned); -2**63 (signed) correct for signed movq $20, %rbx cmpq %rax, %rbx // result = %rbx - %rax = 30 not zero rax and rbx not equal movq $0x7FFFFFFFFFFFFFFF, %rax not negative no overfmow as signed 10 8 incorrect for unsigned overfmow as unsigned // 2^63 - 1 exercise: condition codes (2) movq $ − 10, %rax as signed: 20 − ( − 10) = 30 ZF = as unsigned: 20 − (2 64 − 10) = ✘✘✘✘✘✘ − 2 64 − 30 30 (overfmow!) ❳❳❳❳❳❳ ✘ SF = ❳ OF = ZF = 0 (false) CF = SF = 0 (false) rax < = rbx OF = 0 (false) CF = 1 (true) − 2 64 + 1 1 (overfmow) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ = ✘✘✘✘✘ ❳ ❳ as unsigned: 2 63 − 2 63 − 1 as unsigned: 2 63 − 2 63 − 1 � � � � = 1 = 1 ZF = 0 (false) ZF = 0 (false)
closer look: condition codes (2) // result = %rbx - %rax not zero rax and rbx not equal not negative // 2**63 - 1 overfmow as signed incorrect for signed 10 closer look: condition codes (2) // 2**63 - 1 movq $0x7FFFFFFFFFFFFFFF, %rax // 2**63 (unsigned); -2**63 (signed) movq $0x8000000000000000, %rbx cmpq %rax, %rbx not zero cmpq %rax, %rbx rax and rbx not equal not negative overfmow as signed incorrect for signed no overfmow as unsigned correct for unsigned 10 closer look: condition codes (3) movq addq // result = -3 not zero result not zero // result = %rbx - %rax 11 movq $0x8000000000000000, %rbx // 2**63 - 1 // 2**63 (unsigned); -2**63 (signed) // result = %rbx - %rax cmpq %rax, %rbx movq $0x8000000000000000, %rbx // 2**63 (unsigned); -2**63 (signed) not zero rax and rbx not equal not negative 10 closer look: condition codes (2) movq $0x7FFFFFFFFFFFFFFF, %rax movq $0x7FFFFFFFFFFFFFFF, %rax − 2 64 + 1 1 (overfmow) − 2 64 + 1 1 (overfmow) as signed: − 2 63 − 2 63 − 1 as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ = ✘✘✘✘✘ ❳ ❳ as unsigned: 2 63 − 2 63 − 1 as unsigned: 2 63 − 2 63 − 1 � � � � = 1 = 1 ZF = 0 (false) ZF = 0 (false) SF = 0 (false) rax < = rbx (if correct) SF = 0 (false) rax < = rbx (if correct) OF = 1 (true) $ − 1, %rax $ − 2, %rax as signed: − 1 + ( − 2) = − 3 − 2 64 + 1 1 (overfmow) as unsigned: (2 64 − 1) + (2 64 − 2) = ✘✘✘✘ 2 65 − 3 2 64 − 3 (overfmow) as signed: − 2 63 − 2 63 − 1 � � ❳❳❳❳❳ ✘ = ✘✘✘✘✘ ❳❳❳❳ ✘ ❳ ❳ as unsigned: 2 63 − 2 63 − 1 ZF = 0 (false) � � = 1 ZF = 0 (false) SF = 0 (false) rax < = rbx (if correct) OF = 1 (true) CF = 0 (false)
b += 1; closer look: condition codes (3) subq %rbx, %rax end_loop: jmp start_loop addq $1, %rbx call foo jge end_loop movq $10, %rax while to assembly (1) start_loop: // version C end_loop: jmp start_loop addq $1, %rbx call foo 12 foo (); while ( b < 10) { while ( b < 10) { end_loop : goto start_loop ; foo (); start_loop : if ( b < 10) goto end_loop ; } foo (); while to assembly (1) movq 13 end_loop : goto start_loop ; foo (); start_loop : if ( b < 10) goto end_loop ; } jge end_loop cmpq $10, %rbx start_loop: incorrect for unsigned addq // result = -3 not zero result not zero negative // version B no overfmow as signed correct for signed overfmow as unsigned result is negative 11 start_loop: jl start_loop cmpq $10, %rbx while exercise addq $1, %rbx call foo 13 while ( b < 10) { foo (); b += 1; } translations? Assume b is in callee-saved register %rbx. Which are correct assembly // version A $ − 1, %rax $ − 2, %rax as signed: − 1 + ( − 2) = − 3 as unsigned: (2 64 − 1) + (2 64 − 2) = ✘✘✘✘ 2 65 − 3 2 64 − 3 (overfmow) ❳❳❳❳ ✘ ❳ ZF = 0 (false) SF = 1 (true) OF = 0 (false) CF = 1 (true) b += 1; b += 1; b += 1;
while — levels of optimization jmp start_loop jne start_loop cmpq $10, %rbx addq $1, %rbx call foo start_loop: jge end_loop cmpq $10, %rbx ... ... ... ... end_loop: addq $1, %rbx ... call foo jge end_loop cmpq $10, %rbx start_loop: while ( b < 10) { foo (); b += 1; } while — levels of optimization 14 end_loop: movq $10, %rbx jne start_loop decq %rbx call foo start_loop: end_loop: ... subq %rbx, %rax case 1: ...; break; jmp code_for_default ... je code_for_3 cmpq $3, %rax je code_for_2 cmpq $2, %rax je code_for_1 cmpq $1, %rax // same as if statement? } default: ... ... case 2: ...; break; switch ( a ) { ... compiling switches (1) 14 end_loop: movq $10, %rbx jne start_loop decq %rbx call foo start_loop: movq %rax, %rbx subq %rbx, %rax movq $10, %rax jge end_loop cmpq $10, %rbx movq %rax, %rbx movq $10, %rax while ( b < 10) { foo (); b += 1; } call foo movq %rax, %rbx subq %rbx, %rax movq $10, %rax jge end_loop cmpq $10, %rbx ... ... ... end_loop: jne start_loop cmpq $10, %rbx addq $1, %rbx start_loop: call foo jge end_loop cmpq $10, %rbx ... ... ... ... end_loop: jmp start_loop addq $1, %rbx call foo jge end_loop cmpq $10, %rbx start_loop: start_loop: decq %rbx jge end_loop ... cmpq $10, %rbx ... ... ... end_loop: jne start_loop cmpq $10, %rbx addq $1, %rbx call foo start_loop: jge end_loop cmpq $10, %rbx ... ... jne start_loop ... end_loop: jmp start_loop addq $1, %rbx call foo jge end_loop cmpq $10, %rbx start_loop: while ( b < 10) { foo (); b += 1; } while — levels of optimization 14 end_loop: movq $10, %rbx 15
Recommend
More recommend