https://developer.arm.com/documentation/102404/0200
ARM mimarisi en popüler mimarilerden birisi, her yıl 7 milyar ARM mimarili cihaz pazara sürülüyor. Arm mimarisinin 3 temel profili bulunmaktadır. Bunlar:
Mimari ve mikro-mimari terimleri birbirlerinden farklıdır. Mimari terimi kullanıldığı zaman işlemcinin fonksiyonel işlevselliğinden bahsedilir. Mimari bir işlemcinin hangi instruction'larda ne yapacağını ve hangi instruction'ları alacağını söyler. Dokümanda mimarinin donanım ve yazılım arasında bir köprü olduğundan bahsedilmektedir.
Mimarinin temel taşları:
Mimaride görüldüğü üzere işlemcinin nasıl yapıldığı anlatılmaz. Mikro-mimaride ise işlemcilerin nasıl tasarlandığı (pipeline,cache, vb) gibi özellikler anlatılır.
ARM mimarisi beraberinde başka küçük mimarileri getirmektedir. Bunlar:
Mimarinin dokümanlarında bazı terimlerin önemli olduğundan bahsedilmektedir, bunlar:
ISA => Instruction Set Architecture, bir yazlımın işlemciyi nasıl kontrol edeceğini tanımlar.
aarch64 registerlar | açıklama |
---|---|
X0,X1..X30 | General Purpose 64bit |
W0,W1..W30 | General Purpose 32bit |
XZR, WZR | Zero Register |
SP | Stack Pointer |
X30 | Link Register |
PC | Program Counter |
Exception level:
Exception Level | Stack Pointer | Exception Link Register | Saved Process Status Register |
---|---|---|---|
EL0 | SP_EL0 | - | - |
EL1 | SP_EL1 | ELR_EL1 | SPSR_EL_1 |
EL2 | SP_EL2 | ELR_EL2 | SPSR_EL_2 |
EL3 | SP_EL3 | ELR_EL3 | SPSR_EL_3 |
ARM mimarisinim 31 tane general purpose register'ı bulunuyor. Register isimlendirmesi: X0, X1, ... X30
Arm Assembly | C |
---|---|
ADD x, y, z | x = y + z |
SUB x, y, z | x = y - z |
SDIV x, y, z | x = y / z |
AND x, y, z | x = y & z |
ORR x, y, z | x = y | z |
ERR x, y, z | x = y ^ z |
ASR x, y, z | x = y >> z |
System register'ları işlemciyi ayarlamak, MMU ayarlaması, exception handling gibi işlemleri yapmak için kullanırız. System register'larına direk olarak erişmek mümkün değildir bunun için özel instructionlar bulunamkatadır.
instruction | kullanım | açıklama |
---|---|---|
MRS |
MRS Xd,
|
system register'ı Xd içerisine koy |
MSR |
MSR
|
Xn'yi system register'a yaz |
Önemli: System register'larının isimleri
_ELx
ile biter. Burada x minimum yetki seviyesini belirtir. Daha düşük seviyeden bu registerlara erişmek bir
exception
oluşturur.
arm mimarisinde registerlar üzerinde direk işlem yapılmadığını önceden bahsetmiştik. bundan ötürü load & store instructionları önemli.
instruction | kullanımı | açıklama |
---|---|---|
LDR | ldr dest, [src] | bellekten register'a yükler |
STR | str src, [dest] | register'dan belleke yükler |
ADR | adr x0, variable | bir label'ın adresini register'a koyuyor. |
örnek:
.section data
var: .word 1
.section text
.global main
main:
adr x0, data
ldr w1, [x0]
load & store instructionları için birden çok adresleme metodu mevcuttur.
LDR WO, [X1]
LDR WO, [X1, #10]
LDR WO, [X1, #10]!
LDR WO, [X1], #12
instructionlar bellekte nasıl yer alırsalar aynı sırada çalışmaları gerekir. bunu değiştirebilecek tek şey branch instructionlarıdır.
instruction | kullanım |
---|---|
B (unconditional) | B <label> diyerek istediğimiz adrese zıplayabiliyoruz. |
BR | BR <XN> diyerek XN içerisinde bulunan adrese zıplayabiliyoruz |
BLE | branch less than or equal |
BGE | branch greater than |
Örnek C Kodu:
if (a == 5)
b = 5;
Compiler tarafından oluşturulmuş kod:
CMP W0, #5
BNE skip
MOV W8, #5
skip:
!! Önemli : CMP insturction'ı çağrıldığı zaman bunun sonucu PSTATE register'ında saklanıyor ve branch işlemleri de bu register'a bakılarak yapılıyor.
instruction | kullanım | açıklama |
---|---|---|
CBZ | CBZ Xn, label | Eğer Xn sıfırsa label'a git |
CBNZ | CBNZ Xn, label | Eğer Xn sıfır değilse label'a git |
flag | mean |
---|---|
N | negative |
C | carry |
V | overflow |
Z | zero |
fonksiyonlar çağırıldığı zaman tekrar geri dönebilmek için link işlemini yapmamız gerekir. arm isa'sında da B veya BR instructionlarına L ekleyerek bunu yapmak mümkündür.
BL foo
foo:
RET
bir fonksiyon çağrısını doğru bir şekilde gerçekleştirebilmek için bazı sorulara cevap vermemiz gerekir. 1. Fonksiyon çağrısının oluşturulması (call) 2. Fonkisiyondan geri dönülmesi (ret) 3. Argüman gönderme 4. Lokal değişkenleri saklama 5. Fonksiyonun değer döndürmesi
örnek bir c fonksiyonu:
long foo(long a, long a)
{
long k;
k = foo2();
return (k + a);
}
1 ve 2. sıkıntıların çözümü için auto register 'lar kullanılabilir.
instruction | kullanım |
---|---|
BL | branch and link ==> dönüş adresini X30'da sakla |
RET | X30'daki adrese git |
ancak bu instructionlarda bize çözüm olarak yeterli değil. eğer iç içe fonksiyonlar tanımlanırsa:
foo:
bl foo2
foo2:
bl foo3
ret
foo3:
ret
burada foo2'nin nereye gideceğini kaybettik . bunu kaybetmememk için stack 'i doğru bir şekilde kullanmamız gerekiyor.
sub sp, sp, 16
+------------+ 0
| |
| |
| |
| |
| |
+------------+ New SP
| |
+------------+ Old SP
| |
+------------+
| |
+------------+
instruction | kullanımı | açıklama |
---|---|---|
LDR | ldr dest, [src] | bellekten register'a yükler |
STR | str src, [dest] | register'dan belleke yükler |
Dönülecek adresi ayarlayabilmeiz için şu işlemleri yapmamız gerekiyor.
str x30, [sp]
..
ldr x30, [sp]
Özellikle call işlemleri yaparken register kullanımına önem vermiliyiz. ARM mimarisinde bu kullanım kuralları Procedure Call Standard (PCS) olarak adlandırılmaktadır.
registers | isim | açıklama |
---|---|---|
X0..X7 | parametre ve sonuç | parametre ve sonuçlar bu registerlarda tutulur, alınır |
X8..X18 | caller saved | geçiçi değişkenler bunları kullanıcı stack'te saklamalıdır |
X19.. X29 | calle saved | kalıcı değişkenler call'lar arası kullanılabilir |
# Sabit tanımlama
.equ SIZE, 48
# Register isimlendirme
counter .req x20
foo:
sub sp, sp, SIZE
add counter, #1
add sp, sp, SIZE
Quick notes about MMU: * MMU (Memory Management Unit) * Translates virtual address to physical address * Multiple programs or even vm's can run their own virtual address space. * TLB (Translation Lookahead Buffer): some type of cache to decrease overhead of memory access with referancing actual memory locations. * Cache : L1 cache * Address translation done by hardware
. - 0x40000000
memory mapped peripherals
Flag | Description |
---|---|
AF
|
Access Flag |
SH
|
Shareable attribute |
AP
|
Access Permission |
NS
|
Security Bit |
.equ TT_S1_NORMAL_NO_CACHE, 0x00000000000000401 // Index = 0, AF=1
.equ TT_S1_NORMAL_WBWA, 0x00000000000000405 // Index = 1, AF=1
.equ TT_S1_DEVICE_nGnRnE, 0x00600000000000409 // Index = 2, AF=1, PXN=1, UXN=1
A virtual address structure :
63-42 | 41-29 | 28-0 |
---|---|---|
TTBR selector | index in page table | low bits of virtual address |
mov x0, #0
mov x1, #0
mov x2, #0
mov x3, #0
mov x4, #0
mov x5, #0
mov x6, #0
mov x7, #0
mov x8, #0
mov x9, #0
mov x10, #0
mov x11, #0
mov x12, #0
mov x13, #0
mov x14, #0
mov x15, #0
mov x16, #0
mov x17, #0
mov x18, #0
mov x19, #0
mov x20, #0
mov x21, #0
mov x22, #0
mov x23, #0
mov x24, #0
mov x25, #0
mov x26, #0
mov x27, #0
mov x28, #0
mov x29, #0
mov x30, #0
MSR VTTBR_EL2, xzr
LDR x0, =tt_l1_base
MSR TTBR0_EL1, x0
instruction | kullanımı | açıklama |
---|---|---|
MOV | mov x1, x2 ; mov x1, #5 | |
MRS |
MRS Xd,
|
system register'ı Xd içerisine koy |
MSR |
MSR
|
Xn'yi system register'a yaz |
instruction | kullanımı | açıklama |
---|---|---|
LDR | ldr dest, [src] | loads a 32-bit constant value or an address |
STR | str src, [dest] | stores to memory address |
ADR | adr x0, variable | bir label'ın adresini register'a koyuyor. |
Examples:
var1 = 13; address of var1 = 0x10
ldr x0, addr @ ==> loads address (0x10)
ldr x0, =var1 @ ==> loads address of variable (0x10)
ldr x0, [addr] @ ==> load value inside address (13)
ldr x0, [addr, #12] @ ==> load value inside (address + 12) must be 4 byte aligned
LDR ARM pseudo-instruction
[R1,#0x14] ===> (base+0x14)
LDR r2,=place ===> loads address of place
LDR r1,=0xfff ===> loads 0xfff into r1
Exception Level | Stack Pointer | Exception Link Register | Saved Process Status Register |
---|---|---|---|
EL0 | SP_EL0 | - | - |
EL1 | SP_EL1 | ELR_EL1 | SPSR_EL_1 |
EL2 | SP_EL2 | ELR_EL2 | SPSR_EL_2 |
EL3 | SP_EL3 | ELR_EL3 | SPSR_EL_3 |
elr
: Exception Link Register holds the exception return address
spsr
: The processor state is stored in spsr
Register | Desc. |
---|---|
SCTLR | system control register (level control of the system, including memory) |
TTBR0_EL1, TTBR1_EL1 | Translation Table Base Registers |
TCR_EL1 | Translation Control Register |
SCR_ELx | Secure configuration register, Secure or Non-secure, what mode the processor branches to if an IRQ, FIQ or external abort occurs |
Inline assembly:
uint64_t read_register_64(){
uint64_t foo;
asm volatile ("mov %0, x14" : "=r"(foo) ::);
return foo;
}