480 likes | 643 Views
Lecture 4: Advanced Instructions, Control, and Branching cont. EEN 312: Processors: Hardware, Software, and Interfacing. Department of Electrical and Computer Engineering Spring 2014, Dr. Rozier (UM). COURSE PLAN FOR TODAY Control Instructions Basic Memory Access. CONTROL INSTRUCTIONS.
E N D
Lecture 4: Advanced Instructions, Control, and Branching cont. EEN 312: Processors: Hardware, Software, and Interfacing Department of Electrical and Computer Engineering Spring 2014, Dr. Rozier (UM)
COURSE PLAN FOR TODAY Control Instructions Basic Memory Access
Branching • Branches allow us to transfer control of the program to a new address. • b (<suffix>) <label> • bl (<suffix>) <label> b start bl start
Branch (b) • Branch, possibly conditionally, to a new address. beq subroutine @ If Z=1, branch • Good practice to use bal instead of b.
Branch with link (bl) • Branch, possibly conditionally, to a new address. • Before the branch is complete, store the PC in the LR. • Allows easy return from the branch. bleq subroutine @ If Z=1, branch, saving the PC
Branch with link (bl) • How do we get back once we’ve saved the PC? mov pc, lr • Moves the contents of the link register to the program counter.
Goto vs. Subroutine • b – Allows us to transfer control of the program without returning. • bl – Allows us to transfer control of the program, with returning.
Implementing If Statements • C code:if (i == j) f = g+h;else f = g - h; • ARM codecmp r0, r1 @ Set flags via r0-r1 and discard bne Else add r2, r3, r4 @ r2 = r3 + r4 bal ExitElse: sub r2, r3, r4 @ r2 = r3 - r4Exit:
Implementing Loop Statements • C code:while (i < j) i += 1; • ARM codeLoop: cmp r0, r1 bge Exit add r0, r0, #1 bal Loop Exit: i < j? i<j i=i+1 i>=j Exit
What about a Case Statement? • Say we have a case statement: switch(x) { case 0: foo(); break; case 1: bar(); break; case 2: baz(); break; case 3: qux(); break; }
Jump Tables • Set up a portion of memory as such: • If our case variable is stored in r0… • r0 << #2 is the index into our jump table of the function address.
Cases Statements as Jump Tables (assume r0 holds the switch variable) ldr r1, =jumptable ldr pc, [r1, r0, lsl #2] Wasn’t that easy?
Jump Table Exercise • Convert the follow C-style code into ARMv6 instructions: x = getPrime(); switch(x) { case 1: firstPrime(); break; case 3: secondPrime(); break; case 5: thirdPrime(); break; case 7: fourthPrime(); break; default: notFirstFourPrimes(); }
Pseudo-Instructions • Notice the use of: • ldr r0, =casetable • We saw this before in helloworld.s • What is really going on here?
Pseudo-Instructions Code as we wrote it: Disasembled code:
This is weird… • Let’s play with gdb… x/x 0x8090 0x8090 <_exit+8>: 0x00010094 x/x 0x10094 0x10094 <string>: “Hello World!\nA\025”
Looking back at the assembled code… • While at instruction 0x8080 p/x $pc 0x8080
Looking back at the assembled code… • While at instruction 0x8080 p/x $pc+8 0x8088 The real value of $pc +4 +4
Looking back at the assembled code… • While at instruction 0x8080 p/x $pc+8 0x8088 p/x ($pc+8)+8 0x8090
So why does it show up as muleq? • Representing instructions • Condition Field • 0000 – EQ • 0000 | 000000 | 0 | 0 |????|????|????| 1001|???? mul r1, r4, r0 mul{<cond>}{S} rd, rm, rs
So why does it show up as muleq? • Representing instructions mul r1, r4, r0 mul{<cond>}{S} rd, rm, rs mul 0001, 0100, 0000
So what is this? Code as we wrote it: Disasembled code:
The problem with immediates • The fact that instructions, AND all their arguments, must take up only 32 bits limits the size of immediates to 1 byte. • Range 0 – 255. • Hello world was in 0x10094 • PC was at 0x8088 • Max offset with immediate value? • 0x8088 + 0xFF = 0x8187
Enter, the Literal Pool Last instruction in basic block Literal Pool
A basic block is a sequence of instructions with No embedded branches (except at end) No branch targets (except at beginning) Basic Blocks • A compiler identifies basic blocks for optimization • An advanced processor can accelerate execution of basic blocks
So how do we use the Literal Pool? • We’ve been using it all along. ldr r0, =string ldr r0, [pc, #8]
What about procedures? • Implement the following: foo(int x) { x = x + 1 } main() { x = 1; foo(x); }
What about procedures? • Implement the following: int foo(int x) { if (x < 5) x = foo(x+1); return(x) } main() { x = 1; x = foo(x); }
The problem with Procedures • When we never branch back, who cares what state the registers are in? • If we branch and return, we expect our registers to be in the state that we left them! • Procedures need to use registers too!
A Call Chain Image by David Thomas
Procedure Calling • Place parameters for procedure in registers • Transfer control to procedure • Procedure acquires storage • Procedure performs function. • Procedure places return value in appropriate register • Return control
The Stack • Region of memory managed with stack discipline. • Accessed with pushand pop
Stack Frames • Stack frames “belong” to a procedure. • Store local variables here (they go out of scope automatically) • Can communicate with other procedures with a stack frame.
Communicating with Procedures Caller sets up stack frame
Communicating with Procedures Callee stores values before return
Procedures and Register Use • What if we want to use some registers in the procedure? • Caller could have data in it!
Stack Discipline and ABI • Stack Discipline is important • Define an Application Binary Interface • How should procedures communicate? How should the be called? • Consistency, following standards, is the key.
Conventions and Discipline Caller Callee Callee saves temporary values in its frame before using. Callee restores values in its frame after using. • Caller saves temporary values in its frame before the call. • Caller restores values in its frame after the call.
For next time • More on stacks, procedures, and calling.