160 likes | 261 Views
Apps. O/S. Execution of Machine Code. Arch. m Arch. Logic. Machine State and Operations. Digital. Analog. Devices. Physics. Longer Assembly Example. lw 1 0 five load reg1 with 5 (uses symbolic address) lw 2 1 3 load reg2 with -1 (uses numeric address)
E N D
Apps O/S Execution of Machine Code Arch mArch Logic Machine State and Operations Digital Analog Devices Physics
Longer Assembly Example lw 1 0 fiveload reg1 with 5 (uses symbolic address) lw 2 1 3 load reg2 with -1 (uses numeric address) startadd 1 1 2 decrement reg1 beq 0 1 2 goto end of program when reg1 equals 0 beq 0 0 startgo back to the beginning of the loop noop donehaltend of program five.fill 5 neg1.fill -1 stAddr.fill startwill contain the address of start (2)
State of the Machine • Exposed State • “Architected State” • Behavioral Simulation • Doesn’t simulate the inner workings of the processor • Only includes as much detail as is necessary to get correct execution • Role in verification • This exact idea is used in industry • “Golden Model” • Role in software/OS development
Jump and Link Register • jalr – J-type – opcode 101 • Usage: jalr RegA RegB • First store PC+1 into regA, where PC is the address of the jalr instruction. Then branch to the address contained in regB. • Note: This explicit ordering implies that if regA is the same as regB (i.e. jalr 3 3), the processor will first store PC+1 into that register, then end up branching to PC+1.
JALR Example add 3 2 1 lw 6 0 faddr jalr 7 6 add 4 1 1 … func nand 1 3 4 #Where to store this? jalr 6 7 … faddr .fill func
Converting high level semantics to assembly code C: printf(“hello world\n”); Need to pass parameters Need to save return address Need to jump to printf Need to get return value (if used) Execute instructions for printf()
Task 1: Passing parameters Q: Where should you put all of the parameters? Registers? Fast access but few in number and wrong size for some objects Memory? Slower, but good general solution – where in memory? A: Registers and memory. Put the first few parameters in registers (if they fit) Put the rest in memory on the call stack
Call stack • There are conventions on most processors which allocate a specific region of memory for the call stack • This memory is used to manage all the storage requirements to simulate function call semantics, such as…: • Parameters / Return values • Local variables • Temporary storage (when you run out of registers and need somewhere to save a value) (“spillage”) • Return address • Etc. • Sections of memory on the call stack are allocated when you make a function call, and deallocated when you return from a function.
Saving registers during a call • What happens to the values we have in registers when we make a function call? • You can save your registers before you make the function call. • Where? • What if the function you are calling doesn’t use that register? The call frame is used to store anything required to support function calls We just wasted our time… (and space)
Caller vs. Callee registers • An alternative to the caller saving the register is to have the callee save any registers that will be used in the function. • Save any registers that are going to be overwritten in this function to the call frame at the start of the function. • “You break it, you buy it” • These values are then loaded back into the registers just prior to returning from the call. Is this really any better?
What is the best solution? • Advantages to caller saved • Advantages to callee saved • Hybrid approach • Have some registers that are caller saved, some that are callee saved. • If you need a register, but not at the site of a call, allocate a caller saved. • If you need a register at a call site, allocate a callee saved The programmer (or compiler) should pick the easiest register for your current needs.
Caller and Callee Save Example • Assume that • r1 is caller-save • r2 is callee-save
Class Problem • You have: • 2 caller-save regs • (1 and 2) • 2 callee-save regs • (3 and 4) • What is the best choice of regs for a, b, c, d?