Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Compiler Construction Code Generation Activation Records LIR vs. assembly #Registers Function calls Instruction set LIR Unlimited Implicit Abstract Assembly Limited Runtime stack Concrete 2 Function calls • Conceptually – Supply new environment (frame) with temporary memory for local variables – Pass parameters to new environment – Transfer flow of control (call/return) – Return information from new environment (ret. value) 3 Activation records • New environment = activation record (a.k.a. frame) • Activation record = data of current function / method call – User data • • • • Local variables Parameters Return values Register contents – Administration data • Code addresses 4 Runtime stack • • • • Stack of activation records Call = push new activation record Return = pop activation record Only one “active” activation record: top of stack 5 Runtime stack Previous frame – top of current frame • FP: frame pointer – base of current frame – Sometimes called BP (base pointer) … … • Stack grows downwards (towards smaller addresses) • SP: stack pointer FP Current frame SP 6 X86 runtime stack Instruction Usage Register Usage push, pusha,… Push on runtime stack ESP Stack pointer pop, popa,… Pop from runtime stack EBP Base pointer call Transfer control to called routine ret Transfer control back to caller X86 stack registers X86 stack and call/ret instructions 7 Call sequences • The processor does not save the content of registers on procedure calls • So who will? – Caller saves and restores registers • Caller’s responsibility – Callee saves and restores registers • Callee’s responsability 8 SP call Callee push code callee caller … Caller push code FP Push caller-save registers Push actual parameters (in reverse order) … caller Call sequences (prologue) Callee pop code (epilogue) push return address Jump to call address SP Push current base-pointer bp = sp Push local variables Push callee-save registers Param n … param1 SP Pop callee-save registers Pop callee activation record Pop old base-pointer return Caller pop code Reg 1 … Reg n SP SP Previous fp Local 1 Local 2 … … Local n FP pop return address Jump to address Pop parameters Pop caller-save registers Return address SP 9 caller Call sequences – Foo(42,21) push %ecx push $21 push $42 call _foo Push caller-save registers Push actual parameters (in reverse order) push return address Jump to call address call push %ebp callee mov %esp, %ebp sub %8, %esp Push current base-pointer bp = sp Push local variables (callee variables) Push callee-save registers push %ebx pop %ebx mov %ebp, %esp pop %ebp Pop callee-save registers Pop callee activation record Pop old base-pointer ret caller return add $8, %esp pop return address Jump to address pop %ecx Pop parameters Pop caller-save registers 10 “To Callee-save or to Caller-save?” • Callee-saved registers need only be saved when callee modifies their value • Some conventions exist (cdecl) – %eax, %ecx, %edx – caller save – %ebx, %esi, %edi – callee save – %esp – stack pointer – %ebp – frame pointer – Use %eax for return value 11 Accessing stack variables Use offset from EBP Stack grows downwards Above EBP = parameters Below EBP = locals FP+8 … … • • • • Param n … param1 Return address FP • Examples FP-4 – %ebp + 4 = return address – %ebp + 8 = first parameter – %ebp – 4 = first local SP Previous fp Local 1 Local 2 … … … … Local n-1 Local n 12 main calling method bar int bar(int x) { int y; … } static void main(string[] args) { int z; Foo a = new Foo(); z = a.bar(31); … } 13 main calling method bar EBP+8 31 main’s frame EBP+12 … this ≈ a Return address EBP ESP, EBP-4 Previous fp y bar’s frame • Examples … int bar(Foo this, int x) { int y; implicit parameter … } static void main(string[] args) { int z; Foo a = new Foo(); z = a.bar(a,31); … } implicit argument – %ebp + 4 = return address – %ebp + 8 = first parameter • Always this in virtual function calls – %ebp = old %ebp (pushed by callee) – %ebp – 4 = first local 14 x86 assembly • AT&T syntax and Intel syntax • We’ll be using AT&T syntax • Work with GNU Assembler (GAS) 15 IA-32 • Eight 32-bit general-purpose registers – EAX, EBX, ECX, EDX, ESI, EDI – EBP – stack frame (base) pointer – ESP – stack pointer • EFLAGS register – info on results of arithmetic operations • EIP (instruction pointer) register • Machine-instructions – add, sub, inc, dec, neg, mul, … – generally suffixed with the letters "b", "s", "w", "l", "q" or "t" to determine what size operand is being manipulated. 16 Immediate and register operands • Immediate – Value specified in the instruction itself – Preceded by $ – Example: add $4,%esp • Register – Register name is used – Preceded by % – Example: mov %esp,%ebp 17 Memory and base displacement operands • Memory operands – Obtain value at given address – Example: mov (%eax), %eax • Base displacement – – – – Obtain value at computed address Syntax: disp(base,index,scale) offset = base + (index * scale) + displacement Example: mov $42, 2(%eax) • %eax + 2 – Example: mov $42, (%eax,%ecx,4) • %eax + %ecx*4 18 Accessing Variables: Illustration … … • Use offset from base pointer • Above BP = parameters • Below BP = locals (+ LIR reg.s) • Examples: – %eax = %ebp + 8 – (%eax) = the value 572 – 8(%ebp) = the value 572 %eax,BP+8 param n … 572 Return address BP BP-4 SP Previous bp local 1 … local n 19 Base displacement addressing 4 4 4 4 4 4 4 4 7 0 2 4 5 6 7 1 Array base reference (%ecx,%ebx,4) mov (%ecx,%ebx,4), %eax offset = base + (index * scale) + displacement %ecx = base %ebx = 3 offset = %ecx + (3*4) + 0 = %ecx + 12 20 Instruction examples • Translate a=p+q into – mov 8(%ebp),%ecx add 12(%ebp),%ecx mov %ecx,-4(%ebp) (load p) (arithmetic p + q) (store a) 21 Instruction examples • Array access: a[i]=1 – mov -4(%ebp),%ebx mov -8(%ebp),%ecx mov $1,(%ebx,%ecx,4) (load a) (load i) (store into the heap) • Jumps: – Unconditional: – Conditional: jmp label2 cmp $0, %ecx jne cmpFailLabel 22