lecture07

Document Sample
lecture07 Powered By Docstoc
					The Memory Map and Addressing
 

Last lecture we showed how to build and call subroutines in assembly code

Lecture 7 The Memory Map and Addressing Modes

– We used jump-and-link and jump-register to go to and return from a subroutine
 

This lecture is about memory – How it is organised – How to access it
 

References: – Stallings Chapter 11 – Tanenbaum 5.4 – Patterson Chapter 3

Dr Iain Styles, School of Computer Science October 2006

2

Memory
 

MIPS Addresses
Address = 4n Byte 0 Byte 1 Byte 2 Byte 3 Word n

What exactly is memory? – It's just a collection of boxes – Each box stores one item – In MIPS, each item is a 32-bit binary string MIPS also allows access to individual bytes
¡

– Each box is referenced by an address – The address is just a number (in binary format) – An address will typically have 32 bits Memory addresses run from 0 to 232 -1 In MIPS, this allows access to 232 bytes, since MIPS is byte-addressable
¡ ¡

Address = 8 Address = 4 Address = 0
 

Byte 0 Byte 0 Byte 0

Byte 1 Byte 1 Byte 1

Byte 2 Byte 2 Byte 2

Byte 3 Byte 3 Byte 3

Word 2 Word 1 Word 0

MIPS word addresses are always multiples of 4 – They are said to be aligned – We won't deal with unaligned data in this course
 

– MIPS is a big-endian machine The word address is the address of the left-most byte
¡

There are special instructions for loading and storing individual bytes (lb, sb) which can be useful

3

4

The Memory Map
 

The Code and Data Memory
 

The memory is not just a collection of boxes, there is a bit more structure than that
 

The code segment of memory is where program instructions are stored – Usually occupies the lower part of the memory space At the very bottom is some protected memory, which is used for critical OS code The code segment is of fixed size
¡  

Different parts of the memory are used for different purposes
 

Broadly speaking, there are four main segments into which memory is divided

High memory

Stack Free memory Heap Data Code

The data memory is where globally defined program data is stored – Anything defined at the top-level of a program is stored here – Memory allocation in this block is static, although the contents need not be

5

Low memory

6

The Heap
 

The Stack
 

The heap is a segment of variable size, starting at some fixed memory address and growing upwards
 

The stack is used to store data temporarily within a program
 

It is used to store dynamically allocated data – Arrays which are created at run-time
 

It occupies the upper regions of memory, with the first stack entry at the highest address and the most recent entry at the lowest address – It fills up from the top to the bottom
 

Allocation of heap addresses is dynamic – Each time a new variable is created it will be allocated a free slot on the heap
 

Unlike the heap, entries can only go onto the stack at one point – “Pushing” a value onto the stack adds an entry at the highest available address (stack height increases) – “Popping” a value from the stack clears the most recent entry off the stack (stack height decreases)
 

The heap is essentially just a big pile of boxes and data goes wherever it will fit

Can access data at any point on the stack using offsets, but can only add/remove items from the bottom of the stack

7

8

¡

How the stack works
 

Pushing and Popping the Stack
&stack Top of stack Push r9 onto the stack Top of stack Contents of r1 Contents of r5 Contents of r9

The address of the bottom of the stack is &stack – Stored in a special register called the stack pointer, $sp
 

An item is added (pushed) onto the stack, it is placed at &stack (stored in $sp) sw $r1, $sp // push r1 onto the stack
 

Push r1 onto the stack Top of stack Contents of r1 &stack Pop the stack Push r5 onto the stack Top of stack Contents of r1 Contents of r5 &stack

The stack pointer is then changed accordingly subi $sp, $sp, 4
 

// update stack pointer

&stack

We update the stack pointer by subtracting four – Remember that MIPS is byte-addressable Items are removed (popped) from the stack from address &stack+4 addi $sp, $sp, 4 lw $r1, $sp // update stack pointer // pop the stack into r1
 

Top of stack Contents of r1 Contents of r5

9

&stack 10

Using the stack: a detailed example
 

Using the stack
lw $r1, &b lw $r2, &c add $r1, $r1, $r2 subi $sp,4 sw $r1, $sp lw $r1, &d lw $r2, &e add $r1, $r1, $r2 lw $r2, $sp addi $sp,4 mult $r1, $r1, $r2 // Load b into r1 // Load c into r2 // b+c, result into r1 // update stack_ptr // Push r1 onto the stack // Load d into r1 // Load e into r2 // d+e, result into r1 // pop the stack // update stack_ptr // (b+c)*(d+e)

Imagine that you only have registers $r1 and $r2 available for you to use freely – This could be because the other registers are being used to store other global variables – Or the machine you are working on may only have a few registers
 

// Can't load d or e into r1 yet

The stack allows you to store intermediate values temporarily
 

// Now we can load d and e

Consider the code fragment a = (b+c)*(d+e);
 

Don't have enough registers to store everything, so we have to use the stack

// Get b+c back from the stack

11

12

Comments on the stack
 

Accessing the stack using an offset
Top of stack

Using the stack to hold register contents directly is known as “spill”
 

We can also use the stack to hold local variables in a subroutine – It's very easy to push them onto the stack, and pop them off the stack without needing to worry about where they're going to go – they just take the next free stack entry
 

Any stack elements can be accessed, but can only add/remove elements from the bottom – We access these elements using a stack offset – This is especially useful when the variable on the stack is an array In general, if a[N]is an array of N elements (from 0 to N-1), then &a is the address of a[0] – The address of subsequent array entries is &a[i] = &a + i*sizeof(a)
   

&stack+20 &stack+16 &stack+12 &stack+8 &stack+4 &stack

s[3] s[2] s[1] s[0] b a

Provided that we know what order we pushed things onto the stack, it is trivial to access them directly
 

In this way, we can use the stack to quickly and easily allocate new space to local variables

13

14

Computing memory addresses
 

Addressing Modes
 

We have seen how different parts of the memory have distinct uses
 

In lecture 4 we showed how the 32 bits of each machine instruction were used to encode the instruction
 

It is the segregation of program from data that allows us to use the program counter to keep track of whereabouts in our program we are – Allows instructions to be stored sequentially without being interspersed by data
 

Load/store instructions use 16 bits to encode addresses
 

Jumps have a 6-bit opcode and a 26-bit address segment
 

Branches have a 6-bit opcode, 2x5-bit register addresses, and a 16-bit address segment
 

So far we’ve just referred to addresses in memory with a symbol (e.g. &a, &x etc)
 

Our full memory addresses are 32-bits long
 

Let’s now figure out how to compute the addresses explicitly
 

It appears that we can’t access all memory locations using these instruction formats
 

This takes us one step closer to really understanding what happens when a program runs

A variety of addressing modes allow us to get around this problem

15

16

Load/Store Instructions
If the memory address of the variable is < 216-1=65535 we can use direct or immediate addressing lw $r1, 10000 If we want to access higher addresses, we must do something else
   

Jumps and Branches
 

A standard jump j has 26 bits available to encode an address – This is enough to span 256MB of memory – Program code is rarely this large and so a plain jump uses immediate addressing
 

 

In base addressing, the address is stored in one of the registers: lw $r1, $r2 – Loads the data at the address specified by the contents of $r2, i.e. $r2=&variable
   

If a bigger jump is needed, we can use base addressing with the jr instruction Branches are more complex: only 16 bits are available for address encoding
 

We must use some kind of base/displacement addressing
 

Displacement addressing is similar, but allows us to add a constant: lw $r1, 32($r2) – Loads from the address stored in r2, plus 32 – Often used when accessing arrays

Since branches tend to be over quite short distances (e.g. out of a loop, or to a clause in an if statement), it makes sense to use the current point in the code as the base address

17

18

Comments on addressing
 

PC-Relative Addressing
 

There are many more addressing modes that we haven’t looked at today
 

The address of the current instruction is given by the program counter
 

CISC processors generally have more addressing modes than RISC machines – Intel is especially complex
 

Since the PC is incremented early in the instruction cycle, branch addressing is done relative to the next instruction bne $r1, $r2, L1 8000 add $r3, $r4, $r5 j NEXT L1:
 

Using an appropriate addressing mode can save you time and effort – Arrays are much easier to access using displacement addressing – You also use displacement addressing to access the stack – lw $r1, 8($sp) points to the third element of the stack
 

8004 8008 8012 8016

sub $r3, $r4, $r5

NEXT: mult $r1, $r3, $r3

After the branch, PC=8004, so the branch distance to L1 (8012) is 8 – this is the address that will be encoded in the machine instruction Incidentally, the jump will encode 8016 in its address field – a direct address
 

19

20

We can now write the actual machine code!

Writing the machine code
 

Conclusions
 

All we need to do is replace the instructions with their opcodes, specify sources and targets, and calculate addresses bne $r1,$r2,L1 add $r3,$r4,$r5 j NEXT L1: sub $r3,$r4,$r5 NEXT: mul $r1,$r3,$r4
 

In this lecture we have – Seen how memory is partitioned into code, data, heap and stack – We’ve discussed the purpose of each partition and spent some time discussing the stack and its importance as a temporary resource that is easy to manage – We’ve discussed different methods for addressing the memory and when each is appropriate – We've translated our assembly language into machine code
 

5 0 2 0 0

1 4 4 3

2 5 5 3

3 8016 3 1

8 0 0 0

32 34 30

In binary, this is exactly what would sit in the code section of the memory
 

Next lecture we will – Begin to study the microarchitecture of the CPU to see how our instructions are executed

Note that add, sub, mul have the same opcodes, but a different func specifier – they are essentially variants of the same instruction
 

There are some subleties I have not discussed

21

– See appendix A of Patterson for details

22


				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:8
posted:8/25/2009
language:English
pages:6
Shah Muhammad  Butt Shah Muhammad Butt IT professional
About IM IT PROFESSIONAL