pa5 overview (for real this time) - lecture 15kjleach.eecs.umich.edu/c18/l15.pdf · load operand 1...
TRANSCRIPT
PA5 Overview (for real this time)Lecture 15
lol, let’s not target Windows executables
March 7, 2018
PA5 Overview
“[PA5] is by far the most difficult assignment... youhave to get almost everything right which makes itdifficult to estimate how much progress you’remaking...”“[PA5] was the most time intensive and the hardestof the assignments in both classes. There was (1)just a lot more stuff and (2) a lot more creativityrequired...”“[PA5] needs a lot to come together to get a basicprogram working.”
Compiler Construction 2/31
Compiler Construction 3/31
Considerations for PA5
É Stack machine code generationÉ Without a sensible register allocator, we must
make sure to use a fixed number of registers foreverything.
É VtablesÉ Object layoutÉ Interfacing with external libraries
Compiler Construction 4/31
x86-64É CISC — Complex
Instruction SetÉ Lots of
opportunities foroptimizationsÉ Nightmarish
interfacing withexternal librariesÉ Must use external
tools (e.g., gdbinstead of thereference compiler)É Amazing CV
booster
Cool AssemblyÉ RISC — Reduced
Instruction SetÉ Only 8 registersÉ Fewer optimization
opportunitiesÉ Reference compiler
has helpfuldebuggingcapabilitiesÉ If you don’t like
the referencecompiler.... well,sorry
É Easier to completeCompiler Construction 5/31
Cool Assembly
Compiler Construction 6/31
x86-64 AssemblyX86/WIN32 REVERSE ENGINEERING CHEATSHEET
Registers Instructions
GENERAL PURPOSE 32BIT REGISTERS ADD <dest>, <source> Adds <source> to <dest>. <dest>may be a register or memory. <source>may EAX Contains the return value of a function call. Be a register, memory or immediate value. ECX Used as a loop counter. "this" pointer in C++. CALL <loc> Call a function and return to the next instruction when finished. <proc>EBX General Purpose may be a relative offset from the current location, a register or memory addr.EDX General Purpose CMP <dest>, <source> Compare <source> with <dest>. Similar to SUB instruction but does notESI Source index pointer Modify the <dest> operand with the result of the subtraction.EDI Destination index pointer DEC <dest> Subtract 1 from <dest>. <dest> may be a register or memory.ESP Stack pointer DIV <divisor> Divide the EDX:EAX registers (64‐bit combo) by <divisor>. <divisor>may beEBP Stack base pointer a register or memory.SEGMENT REGISTERS INC <dest> Add 1 to <dest>. <dest>may be a register or memory. CS Code segment JE <loc> Jump if Equal (ZF=1) to <loc>.SS Stack segment JG <loc> Jump if Greater (ZF=0 and SF=OF) to <loc>. DS Data segment JGE <loc> Jump if Greater or Equal (SF=OF) to <loc>. ES Extra data segment JLE <loc> Jump is Less or Equal (SF<>OF) to <loc>. FS Points to Thread Information Block (TIB) JMP <loc> Jump to <loc>. Unconditional.GS Extra data segment JNE <loc> Jump if Not Equal (ZF=0) to <loc>.
MISC. REGISTERS JNZ <loc> Jump if Not Zero (ZF=0) to <loc>.EIP Instruction pointer JZ <loc> Jump if Zero (ZF=1) to <loc>.
EFLAGS Processor status flags. LEA <dest>, <source> Load Effective Address. Gets a pointer to the memory expression <source>STATUS FLAGS and stores it in <dest>.ZF Zero: Operation resulted in Zero MOV <dest>, <source> Move data from <source> to <dest>. <source> may be an immediate value,CF Carry: source > destination in subtract register, or a memory address. Dest may be either a memory address or aSF Sign: Operation resulted in a negative # register. Both <source> and <dest> may not be memory addresses.OF Overflow: result too large for destination MUL <source> Multiply the EDX:EAX registers (64‐bit combo) by <source>. <source>may
16BIT AND 8BIT REGISTERS be a register or memory.The four primary general purpose registers (EAX, EBX, ECX and EDX) have 16 and 8 bit overlapping aliases.
POP <dest> Take a 32‐bit value from the stack and store it in <dest>. ESP is incremented by 4. <dest>may be a register, including segment registers, or memory.
EAX 32‐bit PUSH <value> Adds a 32‐bit value to the top of the stack. Decrements ESP by 4. <value> AX 16‐bit may be a register, segment register, memory or immediate value.
AH AL 8‐bit ROL <dest>, <count> Bitwise Rotate Left the value in <dest> by <count> bits. <dest>may be a register or memory address. <count> may be immediate or CL register.
The Stack ROR <dest>, <count> Bitwise Rotate Right the value in <dest> by <count> bits. <dest>may be a
register or memory address. <count> may be immediate or CL register.
Low Addresses
Empty
<‐ESP points here
SHL <dest>, <count> Bitwise Shift Left the value in <dest> by <count> bits. Zero bits added to
the least significant bits. <dest>may be reg. or mem. <count> is imm. or CL.
Local Variables SHR <dest>, <count> Bitwise Shift Left the value in <dest> by <count> bits. Zero bits added to
the least significant bits. <dest>may be reg. or mem. <count> is imm. or CL.
↑ EBP‐x <‐EBP points here
SUB <dest>, <source> Subtract <source> from <dest>. <source> may be immediate, memory or a↓ EBP+x Saved EBP register. <dest>may be memory or a register. (source = dest)‐>ZF=1, Return Pointer (source > dest)‐>CF=1, (source < dest)‐>CF=0 and ZF=0 Parameters TEST <dest>, <source> Performs a logical OR operation but does not modify the value in the <dest> Parent function's
data operand. (source = dest)‐>ZF=1, (source <> dest)‐>ZF=0.
XCHG <dest, <source> Exchange the contents of <source> and <dest>. Operands may be registerHigh Addresses
Grand‐parent function's data
or memory. Both operands may not be memory. XOR <dest>, <source> Bitwise XOR the value in <source> with the value in <dest>, storing the result
in <dest>. <dest>may be reg or mem and <source> may be reg, mem or imm.
Assembly Language Terminology and Formulas
Instruction listings contain at least a mnemonic, which is the operation to be performed. Many instructions will take operands. Instructions with multiple operands list the destination operand first and the source operand second (<dest>, <source>). Assembler directives may also be listed which appear similar to instructions.
Pointer to Raw Data Offset of section data within the executable file. Size of Raw Data Amount of section data within the executable file. RVA Relative Virtual Address. Memory offset from the beginning of the executable.Virtual Address (VA) Absolute Memory Address (RVA + Base). The PE Header fields named VirtualAddress actually contain Relative Virtual Addresses.Virtual Size Amount of section data in memory. Base Address Offset in memory that the executable module is loaded.
ASSEMBLER DIRECTIVES ImageBase Base Address requested in the PE header of a module.DB <byte> Define Byte. Reserves an explicit
byte of memory at the current location. Initialized to <byte> value.
Module An PE formatted file loaded into memory. Typically EXE or DLL.Pointer A memory addressEntry Point The address of the first instruction to be executed when the module is loaded.
DW <word> Define Word. 2‐Bytes Import DLL functions required for use by an executable module.DD <dword> Define DWord. 4‐Bytes Export Functions provided by a DLL which may be Imported by another module.OPERAND TYPES RVA‐>Raw Conversion Raw = (RVA ‐ SectionStartRVA) + (SectionStartRVA ‐ SectionStartPtrToRaw)Immediate A numeric operand, hard coded RVA‐>VA Conversion VA = RVA + BaseAddressRegister A general purpose register VA‐>RVA Conversion RVA = VA ‐ BaseAddressMemory Memory address w/ brackets [ ] Raw‐>VA Conversion VA = (Raw ‐ SectionStartPtrToRaw) + (SectionStartRVA + ImageBase)
Copyright © 2009 Nick Harbour www.rnicrosoft.net
Compiler Construction 7/31
Stack MachinesÉ A simple evaluation modelÉ No variables or registers (aside from temporary
storage)É A stack of values for intermediate results
Compiler Construction 8/31
Example Stack Machine Program
É Consider two instructionsÉ push i place integer i on top of the stackÉ add pop two elements, add them and put the
result back on the stack
É A program to compute 7 + 5:
push 7push 5add
Compiler Construction 9/31
Stack Machine Example
É Each instruction:É Takes its operands from the top of the stackÉ Removes those operands from the stackÉ Computes the required operation on themÉ Pushes the result on the stack
stack ...
push 7
...7
push 5
...75 ⊕
add
...12
Compiler Construction 10/31
Why Stack Machines?
É Each operation takes operands from the sameplace and puts the results in the same place(i.e., fixed offsets from the top of the stack)
É This means a uniform compilation schemeÉ To do an add, always get sp[0] and sp[1], add them,
store result at sp[0]
É And thus a simpler compilerÉ This is the easiest way to do PA5É Register allocation is more complex!
Compiler Construction 11/31
Why Stack Machines?É Location of the operands is implicit
É Always on the top of the stackÉ No need to specify operands explicitly
É You can load fixed temporary registers withoperands from stack!
É example discipline:load operand 1 by popping sp[0] to r4,load operand 2 by popping sp[1] to r5
É No need to specify result locationÉ e.g., always put result in r6, then push r6
É Can represent instruction as add instead ofadd r1, r2É Smaller program size (sometimes faster: why?)É Java Bytecode uses a stack evaluation model!
É Dalvik uses register allocationCompiler Construction 12/31
Remarks on Stack Machines
É The add instruction performs 3 memoryoperationsÉ Two reads and one write to the stack
É How can we improve this?É Hint: fold from functional programming
É Idea: the top of the stack is accessed frequentlyÉ Keep an accumulator in a fixed registerÉ Implement add as:
É accumulator← accumulator + top_of_stack
É Only one memory operation!
Compiler Construction 13/31
Remarks on Stack Machines
É The add instruction performs 3 memoryoperationsÉ Two reads and one write to the stack
É How can we improve this?É Hint: fold from functional programming
É Idea: the top of the stack is accessed frequentlyÉ Keep an accumulator in a fixed registerÉ Implement add as:
É accumulator← accumulator + top_of_stack
É Only one memory operation!
Compiler Construction 13/31
Stack Machine with AccumulatorFrom before: 7 + 5
acc
stack ...
acc← 7push 7
...7
7
acc← 5
...7
5⊕
acc← acc + toppop
...
12
Compiler Construction 14/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 init
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7acc← 5 5 init, 3, 7
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7acc← 5 5 init, 3, 7acc← acc + top 12 init, 3, 7
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7acc← 5 5 init, 3, 7acc← acc + top 12 init, 3, 7pop 12 init, 3
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7acc← 5 5 init, 3, 7acc← acc + top 12 init, 3, 7pop 12 init, 3acc← acc + top 15 init, 3
Compiler Construction 15/31
Example: 3 + (7 + 5)
Code Acc Stackacc← 3 3 initpush acc 3 init, 3acc← 7 7 init, 3push acc 7 init, 3, 7acc← 5 5 init, 3, 7acc← acc + top 12 init, 3, 7pop 12 init, 3acc← acc + top 15 init, 3pop 15 init
Compiler Construction 15/31
NotesÉ It is critical that the stack is preserved across
the evaluation of a subexpressionÉ Stack before evaluating 7 + 5 is init, 3É Stack after evaluating 7 + 5 is init, 3É The first operand is top of the stack
Compiler Construction 16/31
RISC-y Business
É We’ve been talking about some abstract notionof a stack machine
É The compiler actually generates assembly codefor a specify ISA
É Briefly: COOL-ASM is a RISC-style assemblylanguageÉ Untyped, unsafe, low-level, few primitivesÉ 8 general registers, 3 special registers sp, fp, and raÉ load-store architecture: bring values into registers
from memory to operate on them
Compiler Construction 17/31
Drink your Cool-aid
É Sample COOL-ASM instructions(more in CRM)
1 add r2 <- r5 r2 ; r2 = r5 + r22 li r5 <- 183 ; r5 = 1833 ld r2 <- r1[5] ; r2 = *(r1 + 5)4 st r1[6] <- r7 ; *(r1+6) = r75 my_label: ; label my_label6 push r1 ; *sp = r1; sp --;7 sub r1 <- r1 1 ; r1 = r1 - 18 bnz r1 my_label ; if (r1 != 0) goto my_label
Compiler Construction 18/31
Simulating a Stack MachineÉ The compiler generates COOL-ASM (or
x86-64)É Emit code to implement a stack machine!
É Convention: accumulator is kept in register r1É Stack is stored in memory
É We have more memory than registers
É Both x86-64 and COOL-ASM have supplystacks that grow downwardsÉ The address of the next unused location on the
stack is kept in register spÉ i.e., the top of the stack is at address sp+1
ld r1 <- sp[1] ; load top of stack into accÉ Word size = 1 in COOL-ASM (8 in x86-64)
Compiler Construction 19/31
COOL-ASM for 7+5Stack Machine COOL-ASMacc <- 7 li r1 7push acc push r1acc <- 5 li r1 5acc <- acc + top pop r2
add r1 <- r1 r2pop pop r2
Compiler Construction 20/31
Generalizing Code GenerationÉ Cool is an expression-based language...
É We want to take a principled approach that lets usgenerate code for every type of expression, nomatter where the expression appears in the code,and regardless of how complex the expressions are
É We make a cgen(e) function that generatescode for an expression in the AAST
É Follow a discipline: cgen(e) should computethe value of e and store it in r1 (theaccumulator)É Preserve sp and the contents of the stack
É No matter what the expression must do to thestack, leave it the way you found it
Compiler Construction 21/31
Code Generation: Constants
cgen(123) = li r1 123
Just move the constant into the accumulator!This also preserves the stack (doesn’t touch it)
Compiler Construction 22/31
Code generation: Addition
cgen(e1 + e2) =cgen(e1)push r1cgen(e2);; e2 now in r1pop r2;; r2 contains the saved result of evaluating r1!add r1 <- r1 r2
Why can’t we use r2 directly after cgen(e1) to save apush and pop?
Compiler Construction 23/31
Code generation notes
É The cgen code for + is a template with holesfor code that evaluates e1 and e2
É Stack Machine code generation is recursive
É Code for e1 + e2 consists of code for e1 and e2glued together
É Most critically! Code generation can be writtenas a recursive-descent tree walk of the AASTÉ At least, for expressions
Compiler Construction 24/31
Code Generation: Ifcgen(if e1 = e2 then e3 else e4 fi) =
cgen(e1)push r1cgen(e2)pop r2beq r1 r2 true_branch ;; else fall throughbne r1 r2 else_branch
true_branch:cgen(e3)jmp after_if
else_branch:cgen(e4)jmp after_ifafter_if:Compiler Construction 25/31
Code Generation: VariablesÉ “Variables” could be function parameters, let
bindings...É Parameters get pushed on the stackÉ Recall: fp is established by the function prologue,
sp can change during function execution
Consider: f(x1, x2)
Compiler Construction 26/31
SummaryÉ Activation record is co-designed with the code
generator
É Code generation is a recursive traversal of theAAST
É Stack Machine code is simpler for PA5(although you’re encouraged to try registerallocation!)
Compiler Construction 27/31
Object Oriented Code Generation
É “Variables” are references to objectsÉ What are the semantics of addition in Cool?
É Liskov Substitution Principle: If B is asubclass of A, then an object of class B can beused wherever an object of class A is expected
É This means that code in class A must workunmodified on an object of class B
Compiler Construction 28/31
Two issues
É How are objects represented in memory?É How is dynamic dispatch implemented?
Compiler Construction 29/31
Object Layout
É An object is like a struct in C. The referencefoo.field is an index into a foo struct at anoffset corresponding to fieldÉ Objects are laid out in contiguous memoryÉ Each attribute stored at a fixed offset in objectÉ When a method is invoked, the object becomes self
and the fields are the object’s attributes
Compiler Construction 30/31
Cool Object Layout
É Class tagÉ An integer that identifies the class of the object
(Int=1, Bool=2, ...)
É Object sizeÉ Number of words occupied by the object
É Dispatch pointerÉ Address to a table of methods
É AttributesÉ Each attribute laid out in contiguous memory
Compiler Construction 31/31