armv1
what is arm?
arm (advanced risc machines)
what is risc
risc means reduced instruction set compiler (arm, risc-v)
arm is a microprocessor architecture.
core principle: uses a small set of highly optimized instructions that each can be executed in a single clock cycle.
arm holdings develops the instruction set, architecture and licenses them. also the cores (ip blocks which means reusable pre-designed logic or chip).
arm processor has
- low cost
- low power consumption
- low heat generation
that's why it's chosen for mobile devices.
arm versions
original arm1 used 32 bit internal structure.
had a 26-bit address space that limited it to 64 MB of main memory.
arm1 was running at 6 mhz.
first program ran on arm1 written with arm assembly.
arm2 was running at 8MHz.
speed bumped version was 10-12 mhz.
arm2 had 32 bit data bus, 26 bit address space, 27 32 bit registers (16 was accessible at any time).
arm2 had 30000 transistors.
it had no cache.
example: 1.8 MIPS @ 10 mhz
mips (million instructions per second)
10 mhz means 10 million clock cycle per second
10 million clock cycle but 1.8 million instructions executed per second.
so this means one instuction takes 5.5 cycles to execute.
in a perfect machine 10 MIPS @ 10MHz
in modern cpus we use IPC (instructions per cycle)
5, 6, 8 IPC in modern cpus
arm3 was produced with a 4kb cache.
address bus extended 32 bits in arm6 but program code still had to lie within 64mb of memory in 26 bit compatibility due to reserved bits for the status flags.
late 80s apple + vlsi: arm6 was a collaboration.
apple used arm610 as base of the apple newton pda
apple's personal digital assistant from 93 to 98.
(https://en.wikipedia.org/wiki/Apple_Newton)
arm610 also used in risc pc as the base (https://en.wikipedia.org/wiki/RiscPC)
market share
in 2005 about 98% of the all mobile phones sold had arm processor.
32 bit architecture
32 bit arm architecture (arm32) was the most widely used architecture in mobile devices.
primary source of documentation are arm architecture reference manual (https://en.wikipedia.org/wiki/ARM_architecture_family#External_links) -> instruction set, interfaces exct.
armv7 (version seven of the arch) defines three arch profiles:
- a-profile: the application profile, 32 bit cores in cortex-a series
- r-profile: the real time profile, cores in cortex-r series
- m-profile: the microcontroller profile, cortex-m series
armv1
(https://en.wikichip.org/wiki/arm/armv1)
32 bit isa (instruction set architecture) 26 bit addressing space.
"how much space a command takes up?"
"how much data it can "crunch" at once?"
each instruction is 32 bit in size and operates on two 32 bit operands.
the instruction is divided into parts like
- "what to do" 6 bits (operation code like "add", "divide")
- first source register 5 bits
- second source register 5 bits
- where to save the data 5 bits
operands means "the numbers you are working with"
"data width, payload"
example:
5+3 = 8 (5 and 3 are operands)
32 bit operands means armv1 designed to handle numbers up to 2^32 - 1
registers
16, 32 bit general purpose registers. 14th and 15th excluded, all registers are orthogonal (independent from each other) with no specific purpose.
r15 stores program counter in arm architectures -> always holds the next instruction.
r14 lr (link register) -> when you call a function, hardware saves the return address here to look after execution finished.
addressing modes
armv1 has five addressing modes:
rn -> base registers (address in one of the registers)
n is a placeholder, 0 < n < 15
pc (program counter) relative mode:
effective address = pc +- offset (12 bits)
assembly: LDR R0, MyData
offset modes:
base register
offset
post increment:
effective address = rn
rn = rn +- offset
assembly:
LDR R0, [R1], #4
logic:
r1 = 1000
ea = r1
r1 = r1 + 4
base register
offset
pre increment:
effective address = rn +- offset (12 bits)
rn = rn +- offset
assembly:
LDR R0, [R1 #4]!
logic:
r1 = 1000
r1 = 1000 + 4
ea = r1
post increment:
the address is used exactly as it is currently stored in the register, and then the register is updated for the next time.
use case: reading a value from a list and automatically pointing to the next item.
- cpu uses the address rn
- after the data is accessed
- updates rn by adding or subtracting the offset.
pre increment:
the address is changed before the cpu goes to memory to fetch the data.
use case: useful if your pointer is currently sitting at the "end" of the previous item and you need to move to the next one before reading.
- cpu calculates new address by adding or subtracting the offset to rn before accessing the data
- updates rn with this new value
index modes:
instead of offsets in above modes, we use values stored in rm to increment or decrement.
base register
index
post increment:
effective address = rn
rn = rn +- rm
assembly:
LDR R0, [R1], R2
logic:
ea = r1
r1 = r1 + r2
base register
index
pre increment:
effective address = rn +- rm
rn = rn +- rm
assembly:
LDR R0, [R1, R2]!
logic:
r1 = r1 + r2
ea = r1
post increment:
- cpu uses the address rn
- after the data is accessed
- updates rn by adding or subtracting the rm.
pre increment:
- cpu calculates new address by adding or subtracting the rm
- to rn before accessing the data
- updates rn with rm
instruction listing
armv1 isa (instruction set architecture) has 45 operations under 23 mnemonics (text abbreviation).
there is 8 classes of instructions:
- movement
- load
- store
- arithmetic
- logical
- comparison
- branch
- miscellaneous
movement instructions
to move variables across registers .
mov, move value instant:
copies the value into the destination register
assembly:
mov cond {S} rd, #10
logic:
register = rd
rd = 10
mov, move value:
copies the register's value into the destination register
shiftable
assembly:
mov cond {S} rd, rm
logic:
register = rd
register = rm
rd = rm
mvn, move not value instant:
copies the bitwise "not" value instant into the destination register
assembly:
mov cond {S} rd, #10
logic:
register = rd
rd = 01
mvn, move not value:
copies the bitwise "not" register value instant into the destination register
shiftable
assembly:
mov cond {S} rd, rm
logic:
register = rd
register = rm
rd = !rm
load instructions
move the content of memory addresses into registers
ldm, load multiple:
loads multiple variables into registers from the memory addresses
assembly:
ldm cond type rn{!}, reglist{^}
logic:
addr = rn
for each rd in {reglist}:
rd = [addr]
update address based on {type}
if! : rn = addr
ldr, load register immed:
take the address in a register
add x to that address
go to summed address in the memory
get the data
put data into the target register
update the pointer with x
assembly:
ldr r0, [r1, #4]!
logic:
r0 = [r1's address + 4] (load data from memory)
r1 = r1 + 4 (update address in register)
todo: will continue with the other instructions
tools
visual is a arm emulator you can run assembly codes on:
(https://salmanarif.bitbucket.io/visual/downloads.html)
code with VisUAL
main
LDR r0, =num1
LDR r1, =num2
LDR r0, [r0]
LDR r1, [r1]
ADD r2, r1, r0
LDR r3, [r2]
STR r2, [r3]
MOV r7, #1
num1 DCD 10
num2 DCD 20
result DCD 0