COMP2300/6300
Computer Organisation and Program Execution
Memory operations
Dr Charles 1, 2022
Copyright By PowCoder代写 加微信 powcoder
Week 3: Memory Operations
load/store instructions
address space labels & branching
Memory is how your CPU interacts with the outside world
but first, a few more instructions
Bitwise instructions
Not all instructions treat the bit patterns in the registers as “numbers” Some treat them like bit vectors ( and , orr , etc.)
There are even some instructions (e.g. cmp , tst ) which donʼt calculate a “result” but they do set the flags
Look at the bit operations section of your cheat sheet
Example: bitwise clear
mov r1, 0xFF
mov r2, 0b10101010
bic r3, r1, r2
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 00000000000000000000000011111111
00000000000000000000000010101010
00000000000000000000000001010101
Bit-shi s and rotations
Other instructions will shi (or rotate) the bits in the register, and there are lots of di erent ways to do this!
See the Shi /Rotate section of the cheat sheet
Be careful of the di erence between logical shi and arithmetic shi
ARM barrel shi er
Your microbitʼs CPU actually has special hardware (called a “barrel shi er”) to perform these shi s as part of another instruction (e.g. an add); thatʼs what {,
There are dedicated bit shi instructions (e.g. lsl ) and other instructions which can take an extra shi argument, e.g.
@ some examples
adds r0, r2, r1, lsl 4
mov r3, r3, lsr 2
mov r3, r3, lsr 3 @ off the end!
Is that everything?
We havenʼt looked at everything on the cheat sheet
(not even close!)
The cheat sheet doesnʼt have everything in the reference manual (not even close!)
But you can do a lot with just the basics, and you can refer to the cheat sheet whenever you need it
how do you keep track of all the registers youʼre using in your program? what if you “run out”?
Memory addresses
…but registers can store data
Yes, they can! Thatʼs what weʼve been doing with the instructions so far (e.g. mov , add , etc.) manipulating values in registers.
Registers are super-convenient for the CPU, because theyʼre inside the CPU itself. And we can give them all special names— r0 , r9 , lr , pc , etc.
A pet duckling for COMP2300
Random Access Memory
RAM (Random Access Memory) is for storing lots data
character data for a MMORPG
rgb pixel data from a high-resolution photo
or the machine code instructions which make up a large program
Current price: ~$100 for 16GB
Types of memory
Three technologies to keep in mind:
static RAM (SRAM): uses flip flops (faster, but more expensive and physically larger)—itʼs used in registers & caches
dynamic RAM (DRAM): is slow(er), more power-e icient, cheaper and physically denser— itʼs used where you need more capacity (bytes)
Flash: flash, or “non-volatile” memory is used for storage with power turned o (e.g., SSD), itʼs slower again and more complicated to read/write.
Most computers have all of these types, but the “RAM” in your computer usually refers to DRAM
On your microbit:
16 general purpose registers (64 bytes) 128 kilobytes of RAM
512 kilobytes of flash
(a bit small compared to your laptop/desktop!)
Further reading on memory Shi and Rotate Instructions
– 8bit memory intro
Essentials of Computer Organization and Architecture, Ch. 6 “Memory”
now we have an addressing problem…
Memory addresses
The solution: refer to each di erent section of memory with a (numerical) address
Each of these addressable units is called a cell
Think of it like a giant array in your favourite programming language:
byte[] memory = { 80, 65, 54, /* etc. */ };
Analogy: street addresses
Byte addressing (addresses in blue)
The byte: the smallest addressable unit
One interesting question: what should the smallest addressable unit be? In other words, how many bits are in each bucket? 1, 8, 16, 32, 167?
The ARMv7-M ISA uses 8-bit byte addressing (so do most of the systems youʼll come across these days)
8bits==1byte
Usually, we use a lowercase b to mean bits, and an uppercase B to mean bytes, e.g. 1Mbps == 1 million bits per second, 3.9 GB means 3.9 billion bytes
Why 8 bits to a byte?
Again, thereʼs no fundamental reason it had to be that way
But thereʼs a trade-o between the number of bits you can store and the address granularity (why?)
8 bits provides 256 ( ) di erent values, which is enough to store an ASCII character
A memory address is just a number
A note about “drawing” memory
Itʼs a one-dimensional array (i.e. thereʼs just a single numerical address for each memory cell)
When “drawing a picture” of memory (like in the earlier slides) sometimes we draw le -to- right (with line wrapping!), sometimes top-to-bottom, sometimes bottom-to-top
It doesnʼt matter! The address is all that matters
Can you get data in and out of memory with the instructions weʼve covered already in the course?
Load/store instructions
Load instructions
We need a new instruction (well, a bunch of them actually) ldr is the the l oa d r egister instruction
Itʼs on the cheat sheet under Load & Store
Loading from memory into a register
Any load instruction loads (reads) some bits from memory and puts them in a register of your choosing
The data in memory is una ected (it doesnʼt take the bits “out” of memory, theyʼre still there a er the instruction)
@ load some data into r0
ldr r0, [r1]
Whatʼs with the [r1] ?
Hereʼs some new syntax for your .S files: using a register name inside square brackets (e.g.
This means interpret the value in r1 as a memory address, and read the 32-bit word at that memory address into r0
remember, memory addresses are just a number
Addresses in immediate values?
Can we specify the memory address in an immediate value?
Yes, but the number of addresses would be limited to what could fit in the instruction encoding (remember, thatʼs what immediates are!)
But more o en youʼll read the address from a register (so you get the full possible addresses, but you have to get the address into a register before the ldr instruction)
ldr example
mov r1, 0x20000000 @ put the address in r1
ldr r0, [r1] @ load the data into r0
What value will be in r0 ?
Let’s find out
The converter slide
Binary 0b 0000 0000 0000 0000 0000 0000 0000 0000
0x 0000 0000
Are these valid memory addresses?
0x467ab787e
Answers: yes, yes, yes, no (too big!)
ARM immediate value encoding
ARM instructions have at most 12 bits of room for immediate values (depending on encoding), but it canʼt represent all the values 0 to 4096 ( )
Instead, it uses an 8-bit immediate with a 4-bit rotation—Alistair McDiarmid has a really nice blog post which explains how it works
Storing to memory
Ok, so we probably want to put some data in memory first
The ARMv7-M has a paired st ore r egister instruction for ldr , which takes a value in a register and stores (writes) it to a memory location
str r0, [r1]
Again, the [r1] syntax means “use the value in r1 as the memory address”—this time the address to store the data to
str example
mov r0, 42
mov r1, 0x20000000
str r0, [r1]
What will the memory at 0x20000000 look like a er this?
Endianness
Memory is byte addressable, but a register can fit 4 bytes
So we can load up to 4 bytes into a register—which order do we “combine” them in?
Why do I need to care?
Because the memory at those addresses might have been:
the result of a operation from your microbit
read from a file created on some other machine
received over the network
Little-endian is now more common, but itʼs important to know that other options exist
Further reading on endianness https://betterexplained.com
https://www.embedded.com Computerphile: Endianness
Load/store halfwords & bytes
Sometimes, you just want to read a byte or a halfword (2 bytes), even though youʼve got a 4 byte register
The instruction set provides additional load/store instructions for this:
ldrb @ load byte from register
ldrh @ load halfword from register
strb @ store byte to register
strh @ store halfword to register
They work just the same, but they read fewer bytes from memory (and pad the value in the register with zeroes)
Are these byte/halfword versions of the instructions necessary? Or could you live without them?
Is it an address or a number?
the address & the value at that address are di erent (but theyʼre both just numbers)
Memory address space
Address space?
Address space
The address space is the set of all valid addresses
So on a machine with 32-bit addresses (like your microbit) thatʼs di erent addresses
So you can address about 4GB of memory (is that a lot?)
6927694924 = 2
A memory address is just a number
Not all memory is the same
You can see from the diagram on the previous slide: the address space is divided into “chunks”
Some parts look like “memory” as weʼve been talking about so far (e.g., SRAM, External RAM) but some parts donʼt (e.g. Peripherals)
The load/store architecture
What if everything the CPU did in interacting with the outside world was treated like a load or a store to a memory address?
loading & storing data to RAM
configuring the various peripherals on the board blinking the LEDs
beeping the speaker
This is the idea behind the load/store architecture, and itʼs the model your microbit CPU uses
Recap: reading memory diagrams
Youʼll see “Memory diagrams” (picture representations of data in memory, or at least in the Cortex address space)
Look for the addresses—which direction are they ascending/descending? Remember that the spatial layout can be misleading!
Not all memory is “data”
Some of it is: readable
executable
connected to external peripherals (which could still be r, w, x or some combination)
This is a consequence of the load/store model: we treat everything like memory, because it makes the CPU simpler
Nordic nRF52833 memory map
The microbit conforms to that Cortex M memory map (since itʼs a Cortex M CPU)
But even within those memory ranges the addresses of specific peripherals (e.g. timers, GPIO, LCD, audio codec) are unique to this particular model of microbit
To find out more, you need the nRF52833 Product Specification
Code in memory
You probably noticed the Code section at the bottom (i.e. the lower memory addresses) of
the address space/memory map diagram
Thatʼs where the encoded instructions are: this is sometimes called the instruction stream Each instruction has a memory address
Thatʼs where the fetch-decode-execute cycle fetches from (based on the address in the pc register)
Labels and branching
Labels: addresses for humans
All these 32-bit numbers are fine for the microbit, but not so good for humans Labels provide a way to (temporarily) give a name to a memory address
Youʼve seen labels already— main is one! Any word followed by a colon ( : ) in your assembly code is a label
Label gotchas
only certain characters are allowed in label names
a label is not an instruction, it doesnʼt get encoded, itʼs not in memory
by default, labels arenʼt “visible” outside the source file
the label points to the address of the next instruction (whether itʼs on the same line or a newline)
@ these two are the same
label1: mov r0, 5
Branch: select the next instruction to execute
How do we get back to a previous part of our program?
The answer: change the value in the program counter ( pc ) to “jump back” to an earlier instruction
To do this, use a b (branch) instruction, e.g. b 0x80001c8
Branch? Why not jump?
but where to branch to?
Labels in the instruction stream
You donʼt want to have to figure out the address of the instruction “by hand” and move it into the pc
So we use labels in the assembly code to keep track of the addresses of specific instructions
And thereʼs a b (branch) instruction to tell your microbit to make the jump to that instruction
Branch & labels example
@ infinite loop – r0 will overflow eventually
Branches & labels are best friends 🙂
Conditional branch
b
Conditional branch examples
beq
Does your microbit need to know about the labels? Where is that information stored?
Labels: just for humans
When you build your program, the linker program:
1. figures out what exact memory addresses the labels refer to, and
2. swaps all the label names for the 32-bit address values the microbit understands
arm-none-eabi-ld -nostdlib -T lib/link.ld –print-memory-usage src/main.o lib/s
Memory region
Used Size Region Size %age Used
800 B 184 B 0 GB
Your CPU never knows about the labels
The linker replaces them all with addresses before you create the binary file (e.g. ) which is uploaded to your microbit
program.elf
Memory segmentation
The other thing that the linker does is to make sure that the various parts of your program get put in the right part of the address space
make sure secret data isnʼt readable
make sure code/instructions isnʼt writable make sure “storage” memory isnʼt executable
This is a good thingTM
Itʼs all controlled by the linker file.
Questions?
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com