aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/README.md1
-rw-r--r--src/arch/armv7.md222
2 files changed, 223 insertions, 0 deletions
diff --git a/src/arch/README.md b/src/arch/README.md
index b14cd98..088bbe7 100644
--- a/src/arch/README.md
+++ b/src/arch/README.md
@@ -2,3 +2,4 @@
- [x86_64](./x86_64.md)
- [arm64](./arm64.md)
+- [armv7](./armv7.md)
diff --git a/src/arch/armv7.md b/src/arch/armv7.md
new file mode 100644
index 0000000..5f4980e
--- /dev/null
+++ b/src/arch/armv7.md
@@ -0,0 +1,222 @@
+# armv7a
+keywords: arm, armv7, abi
+
+- ISA type: `RISC`
+- Endianness: `little`, `big`
+
+## Registers
+### General purpose registers
+```markdown
+bytes
+[3:0] alt desc
+---------------------------------------------
+r0-r12 general purpose registers
+r11 fp
+r13 sp stack pointer
+r14 lr link register
+r15 pc program counter
+```
+
+### Special registers
+```markdown
+bytes
+[3:0] desc
+---------------------------------------------
+cpsr current program status register
+```
+
+### CPSR register
+```markdown
+cpsr
+bits desc
+-----------------------------
+ [31] N negative flag
+ [30] Z zero flag
+ [29] C carry flag
+ [28] V overflow flag
+ [27] Q cummulative saturation (sticky)
+ [9] E load/store endianness
+ [8] A disable asynchronous aborts
+ [7] I disable IRQ
+ [6] F disable FIQ
+ [5] T indicate Thumb state
+[4:0] M process mode (USR, FIQ, IRQ, SVC, ABT, UND, SYS)
+```
+
+## Instructions cheatsheet
+### Accessing system registers
+Reading from system registers:
+```armasm
+mrs r0, cpsr // move cpsr into r0
+```
+
+Writing to system registers:
+```armasm
+msr cpsr, r0 // move r0 into cpsr
+```
+
+### Control Flow
+```armasm
+b <lable> // relative forward/back branch
+bl <lable> // relative forward/back branch & link return addr in r14 (LR)
+
+// branch & exchange (can change between ARM & Thumb instruction set)
+// bit Rm[0] == 0 -> ARM
+// bit Rm[0] == 1 -> Thumb
+bx <Rm> // absolute branch to address in register Rm
+blx <Rm> // absolute branch to address in register Rm &
+ // link return addr in r14 (LR)
+```
+
+## Procedure Call Standard ARM ([`aapcs32`][aapcs32])
+### Passing arguments to functions
+- integer/pointer arguments
+ ```markdown
+ reg arg
+ -----------
+ r0 1
+ .. ..
+ r3 4
+ ```
+- a double word (64bit) is passed in two consecutive registers (eg `r1+r2`)
+- additional arguments are passed on the stack. Arguments are pushed
+ `right-to-left (RTL)`, meaning next arguments are closer to current `sp`.
+ ```markdown
+ void take(..., int a5, int a6);
+ | | | ... | Hi
+ | +-->| a6 | |
+ +---------->| a5 | <-SP |
+ +-----+ v
+ | ... | Lo
+ ```
+
+### Return values from functions
+- integer/pointer return values
+ ```markdown
+ reg size
+ -----------------
+ r0 32 bit
+ r0+r1 64 bit
+ ```
+
+### Callee saved registers
+- `r4` - `r11`
+- `sp`
+
+### Stack
+- full descending
+ - full: `sp` points to the last used location (valid item)
+ - descending: stack grows downwards
+- `sp` must be 4byte aligned (word boundary) at all time
+- `sp` must be 8byte aligned on public interface interfaces
+
+### Frame chain
+- not strictly required by each platform
+- linked list of stack-frames
+- each frame links to the frame of its caller by a `frame record`
+ - a frame record is described as a `(FP,LR)` pair (2x32bit)
+- `r11 (FP)` must point to the frame record of the current stack-frame
+ ```markdown
+ +------+ Hi
+ | 0 | frame0 |
+ +->| 0 | |
+ | | ... | |
+ | +------+ |
+ | | LR | frame1 |
+ +--| FP |<-+ |
+ | ... | | |
+ +------+ | |
+ | LR | | current |
+ r11 ->| FP |--+ frame v
+ | ... | Lo
+ ```
+- end of the frame chain is indicated by following frame record `(0,-)`
+- location of the frame record in the stack frame is not specified
+- `r11` is not updated before the new frame record is fully constructed
+
+### Function prologue & epilogue
+- prologue
+ ```armasm
+ push {fp, lr}
+ mov fp, sp // FP points to frame record
+ ```
+- epilogue
+ ```armasm
+ pop {fp, pc} // pop LR directly into PC
+ ```
+
+## ASM skeleton
+Small assembler skeleton, ready to use with following properties:
+- use raw Linux syscalls (`man 2 syscall` for ABI)
+- no `C runtime (crt)`
+- gnu assembler [`gas`][gas_doc]
+```armasm
+// file: greet.S
+
+#include <asm/unistd.h> // syscall NRs
+
+ .arch armv7-a
+
+ .section .text, "ax"
+ .balign 4
+
+ // Emit `arm` instructions, same as `.arm` directive.
+ .code 32
+ .global _start
+_start:
+ // Branch with link and exchange instruction set.
+ blx _do_greet
+
+ mov r0, #0 // exit code
+ mov r7, #__NR_exit // exit(2) syscall
+ swi 0x0
+
+ // Emit `thumb` instructions, same as `.thumb` directive.
+ .code 16
+ .thumb_func
+_do_greet:
+ mov r0, #2 // fd
+ ldr r1, =greeting // buf
+ ldr r2, =greeting_len // &len
+ ldr r2, [r2] // len
+ mov r7, #__NR_write // write(2) syscall
+ swi 0x0
+
+ // Branch and exchange instruction set.
+ bx lr
+
+ .balign 8 // align data on 8byte boundary
+ .section .rodata, "a"
+greeting:
+ .asciz "Hi ASM-World!\n"
+greeting_len:
+ .int .-greeting
+```
+> man gcc: `file.S` assembler code that must be preprocessed.
+
+To cross-compile and run:
+```bash
+> arm-linux-gnueabi-gcc -o greet greet.S -nostartfiles -nostdlib \
+ -Wl,--dynamic-linker=/usr/arm-linux-gnueabi/lib/ld-linux.so.3 \
+ && qemu-arm ./greet
+Hi ASM-World!
+```
+> Cross-compiling on `Ubuntu 20.04 (x86_64)`, paths might differ on other
+> distributions. Explicitly specifying the dynamic linker should not be
+> required when compiling natively on arm.
+
+## References
+- [Procedure Call Standard ARM][aapcs32]
+- [ARMv7-A Programmer's Guide][armv7a_prog_guide]
+- [ARMv7-A Architecture Reference Manual][armv7a_arm]
+- [GNU Assembler][gas_doc]
+- [GNU Assembler Directives][gas_directives]
+- [GNU Assembler `ARM` dependent features][gas_arm]
+
+
+[aapcs32]: https://github.com/ARM-software/abi-aa/blob/master/aapcs32/aapcs32.rst
+[armv7a_prog_guide]: https://developer.arm.com/documentation/den0013/latest
+[armv7a_arm]: https://developer.arm.com/documentation/ddi0406/latest
+[gas_doc]: https://sourceware.org/binutils/docs/as
+[gas_directives]: https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops
+[gas_arm]: https://sourceware.org/binutils/docs/as/ARM_002dDependent.html