assembly part 1
play

Assembly (part 1) arrays include elements sizeof includes elements - PowerPoint PPT Presentation

Assembly (part 1) arrays include elements sizeof includes elements HW generally due next week at noon (partial credit on many labs is very generous) on future labs, please always submit what you have lab generally due after 11PM on the lab


  1. Assembly (part 1) arrays include elements — sizeof includes elements HW generally due next week at noon (partial credit on many labs is very generous) on future labs, please always submit what you have lab generally due after 11PM on the lab day logistics note: lab due times 2 standards and undefjned behavior like classes without methods structs in C misc. C features: goto, malloc/free, printf pointers are addresses — sizeof is size of address arrays are almost pointers 1 last time: C hodgepodge 1 4 September 2017: slide 25: %rbx is callee-saved, too 31 August 2017: slide 19: fjx extra junk in assembly 31 August 2017: slide 40: fjx typo in start_loop label 31 August 2017: slide 39-40: use r12 instead of rbx 31 August 2017: slide 26: put pushq for caller-saved right before call zero/positive/negative 31 August 2017: slide 34: split out from previous slide; clarify Corrections made in this version not seen in fjrst lecture: Changelog 3

  2. some lists 1 payload: 1 x ... } node ; short payload ; typedef struct node_t { 3 2 ptr: *x len: 3 x ... range x ; } range ; short * ptr ; unsigned int length ; short sentinel = -9999; x[3] ptr: or regs x callee saved x86-64 refresher 5 bar.a bar.b bar.c foo.a foo.b foo.c registers return address 4 … // bar is 4, 3, 3 // foo is 3, 3, 3 triple foo ; ... } triple ; long a ; long b ; long c ; typedef struct { structs aren’t references x[0] x[1] x[2] typedef struct range_t { ... range x ; typedef struct node_t { x [3] = sentinel ; 2 1 ptr: len: 3 x ... } range ; } node ; short * ptr ; unsigned int length ; typedef struct range_t { x[3] x[0] x[1] x[2] x ... x [3] = sentinel ; short * x ; short payload ; 3 6 ptr: some lists 4 on heap short * x ; short sentinel = -9999; on stack *x or regs payload: 1 x ... ← on stack on heap → 1 2 3 − 9999 1 2 3 − 9999 x = malloc (sizeof(short)*4); x = malloc (sizeof(short)*4); x . length = 3; x . length = 3; x . ptr = malloc (sizeof(short)*3); x . ptr = malloc (sizeof(short)*3); list * next ; list * next ; node * x ; node * x ; x = malloc (sizeof( node_t )); x = malloc (sizeof( node_t )); foo . a = foo . b = foo . c = 3; triple bar = foo ; bar . a = 4;

  3. AT&T versus Intel syntax (1) AT&T syntax example (1) () s represent value in memory constants start with $ registers start with % q (‘quad’) indicates length (8 bytes) l : 4; w : 2; b : 1 sometimes can be omitted 8 mov q $42, (%rbx) AT&T syntax: destination last () s represent value in memory constants start with $ registers start with % q (‘quad’) indicates length (8 bytes) l : 4; w : 2; b : 1 sometimes can be omitted destination last mov q $42, (%rbx) AT&T syntax example (1) mov q $42, (%rbx) movq $42, (%rbx) Intel syntax: mov QWORD PTR [rbx], 42 efgect (pseudo-C): memory[rbx] <- 42 7 AT&T syntax example (1) 8 destination last () s represent value in memory constants start with $ registers start with % q (‘quad’) indicates length (8 bytes) l : 4; w : 2; b : 1 sometimes can be omitted 8 // memory[rbx] ← 42 // memory[rbx] ← 42 // memory[rbx] ← 42

  4. AT&T syntax example (1) efgect (pseudo-C): 8 AT&T versus Intel syntax (2) AT&T syntax: movq $42, 100(%rbx,%rcx,4) Intel syntax: mov QWORD PTR [rbx+rcx*4+100], 42 memory[rbx + rcx * 4 + 100] <- 42 mov q $42, (%rbx) 9 AT&T versus Intel syntax (2) AT&T syntax: Intel syntax: mov QWORD PTR [rbx+rcx*4+100], 42 efgect (pseudo-C): sometimes can be omitted l : 4; w : 2; b : 1 9 sometimes can be omitted destination last () s represent value in memory constants start with $ registers start with % q (‘quad’) indicates length (8 bytes) registers start with % l : 4; w : 2; b : 1 8 AT&T syntax example (1) mov q $42, (%rbx) destination last () s represent value in memory constants start with $ // memory[rbx] ← 42 // memory[rbx] ← 42 q (‘quad’) indicates length (8 bytes) movq $42, 100(%rbx,%rcx,4) memory[rbx + rcx * 4 + 100] <- 42

  5. AT&T versus Intel syntax (2) AT&T syntax: subq %rax, %r8 AT&T syntax: sub r8, rax Intel syntax: AT&T versus Intel syntax (3) 10 memory[rcx + rbx * 8 + 100] 100(%rcx,%rbx,8) : 100(,%rbx,8) : memory[rbx * 8 + 100] 100(%rbx,8) : memory[rbx * 8 + 100] 100(%rbx) : memory[rbx + 100] AT&T syntax: addressing 9 efgect (pseudo-C): mov QWORD PTR [rbx+rcx*4+100], 42 Intel syntax: movq $42, 100(%rbx,%rcx,4) AT&T syntax: AT&T versus Intel syntax (2) 9 memory[rbx + rcx * 4 + 100] <- 42 efgect (pseudo-C): mov QWORD PTR [rbx+rcx*4+100], 42 Intel syntax: movq $42, 100(%rbx,%rcx,4) 11 memory[rbx + rcx * 4 + 100] <- 42 r8 ← r8 - rax same for cmpq

  6. AT&T syntax: addresses and/or omit base (defaults to 0 ) %rax is 0x1 ( not 0xFFFFFFFF00000001 ) movl $0x1, %eax movq $0xFFFFFFFFFFFFFFFF, %rax setting 32-bit registers — clears corresponding 64-bit register overlapping registers (1) 14 Figure: Immae via Wikipedia recall: x86-64 general purpose registers 13 plain number/label means value in memory $ means constant and/or scale (defualts to 1 ) omit disp (defaults to 0 ) addq 0x1000, %rax memory[disp + base + index * scale] disp(base, index, scale) same as () means value in memory destination last AT&T syntax in one slide 12 no $ — probably memory address // Intel syntax: add rax, 0x1000 addq $0x1000, %rax // Intel syntax: add rax, QWORD PTR [0x1000] 15 // rax ← rax + memory[0x1000] // rax ← rax + 0x1000

  7. overlapping registers (2) setting 8/16-bit registers: don’t clear 64-bit register “address of memory[rax + 4]” = rax + 4 skips the memory access — just uses the address syntax looks like a mov from memory, but… efgective address = computed address for memory access LEA = L oad E fgective A ddress on LEA 18 addq $label : use address as an integer constant addq label : read value at the address string" .ascii "a string: 20 // intel syntax: add rax, OFFSET label addq $string, %rax // intel syntax: add rax, QWORD PTR [label] addq string, %rax labels (2) 17 labels represent addresses labels (1) 16 %rax is 0xFFFFFFFFFFFFFF01 movb $0x1, %al movq $0xFFFFFFFFFFFFFFFF, %rax // rax ← rax + memory[address of "a string"] // rax ← rax + address of "a string" ␣ leaq 4(%rax), %rax ≈ addq $4, %rax

  8. on LEA ... return value in %rax don’t memorize: Figure 3.28 in book 22 x86-64 calling convention example int foo (int x , int y , int z ) { return 42; } ... foo (1, 2, 3); ... // foo(1, 2, 3) %r9 (or %r9d or %r9w , etc.) movl $1, %edi movl $2, %esi movl $3, %edx call foo // call pushes address of next instruction // then jumps to foo ... foo: movl $42, %eax rest on stack %r8 (or %r8d or %r8w , etc.), then LEA = L oad E fgective A ddress %rcx (or %ecx or %cx , etc.), then efgective address = computed address for memory access syntax looks like a mov from memory, but… skips the memory access — just uses the address “address of memory[rax + 4]” = rax + 4 20 LEA tricks leaq (%rax,%rax,4), %rax 23 leaq (%rbx,%rcx), %rdx 21 x86-64 calling convention registers for fjrst 6 arguments: %rdi (or %edi or %di , etc.), then %rsi (or %esi or %si , etc.), then %rdx (or %edx or %dx , etc.), then rax ← rax × 5 rax ← address-of(memory[rax + rax * 4]) leaq 4(%rax), %rax ≈ addq $4, %rax rdx ← rbx + rcx rdx ← address-of(memory[rbx + rcx])

  9. call/ret b. pushq $0x1 pushq $0x2 addq $0x3, 8(%rsp) popq %rax popq %rbx What is value of %rax and %rbx after this? a. %rax = 0x2 , %rbx = 0x4 %rax = 0x5 , %rbx = 0x1 26 c. %rax = 0x2 , %rbx = 0x1 d. the snippet has invalid syntax or will crash e. more information is needed f. something else? question popq %r11 call: callq foo ret: pop address from stack; jump 24 callee-saved registers functions must preserve these %rsp (stack pointer), %rbx , %rbp (frame pointer, maybe) %r12-%r15 25 caller/callee-saved foo: pushq %r12 // r12 is caller-saved ... use r12 ... popq %r12 ret ... other_function: ... pushq %r11 // r11 is caller-saved 27 push address of next instruction on the stack

  10. on %rip difgerent ways of writing address of label in machine code authoriative source 29 lots and lots of instructions segmentation (special registers: %ds, %fs, %gs, …) special registers: %xmm0 through %xmm15 fmoating point; vector operations (multiple values at once) things we won’t cover (today) 28 (with %rip — relative to next instruction) 30 %rip ( I nstruction P ointer) = address of next instruction movq 500(%rip), %rax %rip ( I nstruction P ointer) = address of next instruction on %rip 28 (with %rip — relative to next instruction) difgerent ways of writing address of label in machine code label label(%rip) movq 500(%rip), %rax rax ← memory[next instruction address + 500] rax ← memory[next instruction address + 500] label(%rip) ≈ label

  11. a += 10; if-to-assembly (1) jmp after_else } // a is in %rax, b is in %rbx cmpq $42, %rbx // computes rbx - 42 to 0 jl after_then // jump if rbx - 42 < 0 // AKA rbx < 42 addq $10, %rax after_then: if-to-assembly (2) imulq %rbx, %rax // rax = rax * rbx after_else: 32 condition codes x86 has condition codes set by (almost) all arithmetic instructions addq, subq, imulq, etc. was it zero? was it negative? etc. if ( b >= 42) { if ( b >= 42) { 31 after_else : } if ( b >= 42) goto after_then ; goto after_else ; after_then : a *= b ; after_else : 31 if-to-assembly (1) if ( b >= 42) { 33 after_then : a *= b ; } if ( b >= 42) goto after_then ; goto after_else ; a += 10; a += 10; } else { } else { a *= b ; a *= b ; a += 10; a += 10; } else { a *= b ; store info about last arithmetic result // a + = 1

Recommend


More recommend