1 / 24

Machine-Level Representation of Programs (x86-64)

Machine-Level Representation of Programs (x86-64). Outline. x86-64 Machine-Level Programming Procedures and Stack Alignment Byte Ordering Suggested reading Chap 3.13. Example: swap(). swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax

verlee
Download Presentation

Machine-Level Representation of Programs (x86-64)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Machine-Level Representation of Programs (x86-64)

  2. Outline • x86-64 Machine-Level Programming • Procedures and Stack • Alignment • Byte Ordering • Suggested reading • Chap 3.13

  3. Example: swap() swap: pushl %ebp movl %esp,%ebp pushl %ebx movl 12(%ebp),%ecx movl 8(%ebp),%edx movl (%ecx),%eax movl (%edx),%ebx movl %eax,(%edx) movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp popl %ebp ret IA32 • void • swap(int *xp, int *yp) • { • int t0 = *xp; • int t1 = *yp; • *xp = t1; • *yp = t0; • } Setup Body Finish

  4. Example: swap() swap: movl (%rdi), %edx movl (%rsi), %eax movl %eax, (%rdi) movl %edx, (%rsi) retq x86-64 • void • swap(int *xp, int *yp) • { • int t0 = *xp; • int t1 = *yp; • *xp = t1; • *yp = t0; • }

  5. Example: swap() swap: movl (%rdi), %edx movl (%rsi), %eax movl %eax, (%rdi) movl %edx, (%rsi) retq • Operands passed in registers • First (xp) in %rdi • Second (yp) in %rsi • 64-bit pointers • No stack operation required • 32-bit data • Data held in register %eax and %edx • movl operation

  6. Example: swap() swap: movq (%rdi), %rdx movq (%rsi), %rax movq %rax, (%rdi) movq %rdx, (%rsi) retq Swap long int in 64-bit • void • swap(long int *xp, • long int *yp) • { • long int t0 = *xp; • long int t1 = *yp; • *xp = t1; • *yp = t0; • } • 64-bit data • Data held in registers %rax and %rdx • movq operation • “q” stands for quar-word

  7. Procedures - Stack • IA32/Linux Stack Frame • Caller Stack Frame • Arguments for this call • Return Address (pushed by “call”) • Callee Stack Frame • Old %ebp (saved by “push %ebp”) • Saved registers • Local variable s • Arguments for next call Arguments Ret Addr Old %ebp %ebp frame pointer Saved registers Local variables Arguments %esp stack pointer

  8. Procedures - Register Caller-Save • IA32/Linux Register Usage • %eax, %edx, %ecx • Caller saves prior the call if values are used by later • %eax • Return integer value • %ebx, %esi, %edi • Callee saves if want to used them • %esp, %ebp • special %eax %edx %ecx Callee-Save %ebx %esi %edi Special %esp %ebp

  9. Procedures - Register • X86-64/Linux Register Usage • Caller-Save • %rax %rcx %rdx %rsi %rdi %r8 %r9 • Callee-Save • %rbx %rbp %r10 • %r12 %r13 %r14 %r15 • Special • %rsp, %r11 %rax %rax %r8 %r8 %rbx %rbx %r9 %r9 %rcx %rcx %r10 %r10 %rdx %rdx %r11 %r11 %rsi %rsi %r12 %r12 %rdi %rdi %r13 %r13 %rsp %rsp %r14 %r14 %rbp %rbp %r15 %r15

  10. Procedures - Register • X86-64/Linux Register Usage • Arguments passed via regs • %rcx %rdx %rsi %rdi %r8 %r9 • If more than 6 integer parameters, then passrest on stack • Return value by %rax • No frame pointer • Special • %rsp stack pointer • %r11 used for linking %rax ret %rax %r8 arg#5 %r8 %rbx %r9 arg#6 %r9 %rcx arg#4 %rcx %r10 %rdx arg#3 %rdx %r11 link %r11 %rsi arg#2 %rsi %r12 %rdi arg#1 %rdi %r13 %rsp stack %rsp %r14 %rbp %r15

  11. Procedures - Stack • x86-64/Linux Stack Frame • Caller Stack Frame • Arguments passed via registers • Return Address (pushed by “call”) • Callee Stack Frame • Saved registers • Local variables Ret Addr Saved registers Local variables %rsp stack pointer

  12. X86-64 Swap • void swap(long *xp, long *yp) • { • long t0 = *xp; • long t1 = *yp; • *xp = t1; • *yp = t0; • } swap: movq (%rdi), %rdx movq (%rsi), %rax movq %rax, (%rdi) movq %rdx, (%rsi) ret • Operands passed in registers • First (xp) in %rdi, second (yp) in %rsi • No stack operations required (except ret) • Avoid stack • Can hold all local information in registers

  13. Local Variables in Stack • void swap_a(long *xp, long *yp) • { • volatile long loc[2]; • loc[0] = *xp; • loc[1] = *yp; • *xp = loc[1]; • *yp = loc[0]; • } swap_a: movq (%rdi), %rax movq %rax, -24(%rsp) movq (%rsi), %rax movq %rax, -16(%rsp) movq -16(%rsp), %rax movq %rax, (%rdi) movq -24(%rsp), %rax movq %rax, (%rsi) ret • Avoid Stack Pointer change • Can hold all information within small windows beyond stack pointer ret ptr %rsp -8 unused -16 loc[1] -24 loc[0]

  14. Without Stack Frame long scount = 0 void swap_b(long a[], int i) { swap(&a[i], &a[i+1]); scount++ } • No value held while swap being invoked • No callee save registers needed swap_b: movslq %esi,%rsi # sign extend leaq (%rdi,%rsi,8), %rdi # &a[i] leaq 8(%rdi,%rsi,8),%rsi # &a[i+1] call swap # swap() incq scount(%rip) # scount++; ret . . . ret ptr1 ret ptr2 %rsp execute in swap

  15. Call using Jump long scount = 0 void swap_c(long a[], int i) { swap(&a[i], &a[i+1]); } • Directly return from swap • Possible since swap is a “tail call “ swap_c: movslq %esi,%rsi # Sign extend leaq (%rdi,%rsi,8), %rdi # &a[i] leaq 8(%rdi, rsi,8), %rsi# &a[i+1] jmp swap # swap() . . . ret ptr1 %rsp execute in swap

  16. Stack Frame Example swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi call swap movq (%r12,%rbx,8), %rax addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret • long sum = 0 • void swap_d(long a[], int i) • { • swap(a[i], a[i+1]); • sum += a[i]; • } • Keep values of a and i in callee save registers • Must set up stack frame to save these registers

  17. Understanding x86-64 Stack Frame swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr %rsp # save %rbx %r12 -8 # save %r12 %rbx -16

  18. Understanding x86-64 Stack Frame swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr # save %rbx %r12 +8 # save %r12 %rbx %rsp # move stack frame # restore %rbx # restore %r12

  19. Understanding x86-64 Stack Frame swap_d: movq %rbx, -16(%rsp) movslq %esi,%rbx movq %r12, -8(%rsp) movq %rdi, %r12 leaq (%rdi,%rbx,8), %rdi subq $16, %rsp leaq 8(%rdi), %rsi . . . addq %rax, sum(%rip) movq (%rsp), %rbx movq 8(%rsp), %r12 addq $16, %rsp ret ret ptr %rsp # save %rbx %r12 -8 # save %r12 %rbx -16 # move stack frame # restore %rbx # restore %r12 # move stack frame

  20. Features of Stack Frame • Allocate entire frame at once • All stack accesses can be relative to %rsp • Do by decrementing stack pointer • Can delay allocation • Simple deallocation • Increment stack pointer • No base/frame pointer needed

  21. Alignment

  22. Example • struct s1 { • char c; • int i[2]; • double d; • } *p; • IA32 Linux • K = 4; double treated like a 4-byte data type • X86-64 or IA32 Windows: • K = 8; due to double element C 3bytes i[0] i[1] 4bytes d p+0 p+4 p+8 p+24 p+16 C 3bytes i[0] i[1] d p+0 p+4 p+8 p+20 p+12

  23. Byte Ordering IA32 (Little Endian) 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] S[0] S[1] S[2] S[3] LSB MSB LSB MSB I[0] I[1] LSB MSB L[0] Output on IA32 Characters 0-7 = [0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7] Shorts 0-3 = [0xf1f0,0xf3f2,0xf5f4,0xf7f6] Ints 0-1 = [0xf3f2f1f0,0xf7f6f5f4] Long 0 = [0xf3f2f1f0]

  24. Byte Ordering X86-64 (Little Endian) 0xf0 0xf1 0xf2 0xf3 0xf4 0xf5 0xf6 0xf7 C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] S[0] S[1] S[2] S[3] LSB MSB LSB MSB I[0] I[1] LSB MSB L[0] Output on x86-64 Characters 0-7 = [0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7] Shorts 0-3 = [0xf1f0,0xf3f2,0xf5f4,0xf7f6] Ints 0-1 = [0xf3f2f1f0,0xf7f6f5f4] Long 0 = [0xf7f6f5f4f3f2f1f0]

More Related