From fe84155562f3e6d51b94155197ab5606f2e3bebe Mon Sep 17 00:00:00 2001 From: johannst Date: Sun, 28 Feb 2021 20:37:15 +0000 Subject: deploy: 5e76b1948f7d7f499993862933f0622cf76d83ff --- arch/armv7.html | 451 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 451 insertions(+) create mode 100644 arch/armv7.html (limited to 'arch/armv7.html') diff --git a/arch/armv7.html b/arch/armv7.html new file mode 100644 index 0000000..940d518 --- /dev/null +++ b/arch/armv7.html @@ -0,0 +1,451 @@ + + + + + + armv7 - Notes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

armv7a

+

keywords: arm, armv7, abi

+
    +
  • ISA type: RISC
  • +
  • Endianness: little, big
  • +
+

Registers

+

General purpose registers

+
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

+
bytes
+[3:0]             desc
+---------------------------------------------
+cpsr              current program status register
+
+

CPSR register

+
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:

+
mrs r0, cpsr      // move cpsr into r0
+
+

Writing to system registers:

+
msr cpsr, r0      // move r0 into cpsr
+
+

Control Flow

+
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)
+
+

Load/Store

+

Different addressing modes.

+
str r1, [r0]         // [r0]=r1
+str r1, [r0, #4]     // [r0+4]=r1
+str r1, [r0, #4]!    // r0+=4; [r0]=r1
+str r1, [r0], 4      // [r0]=r1; r0+=4
+
+

Load/store multiple registers full-descending.

+
stmfd r0!, {r1-r2, r5}    // r0-=4; [r0]=r5
+                          // r0-=4; [r0]=r2
+                          // r0-=4; [r0]=r1
+ldmfd r0!, {r1-r2, r5}    // r1=[r0]; r0+=4
+                          // r2=[r0]; r0+=4
+                          // r5=[r0]; r0+=4
+
+
+

! is optional but has the effect to update the base pointer register r0 here.

+
+

Push/Pop

+
push {r0-r2}    // effectively stmfd sp!, {r0-r2}
+pop {r0-r2}     // effectively ldmfd sp!, {r0-r2}
+
+

Procedure Call Standard ARM (aapcs32)

+

Passing arguments to functions

+
    +
  • integer/pointer arguments +
    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. +
    void take(..., int a5, int a6);
    +                   |       |   | ... |       Hi
    +                   |       +-->| a6  |       |
    +                   +---------->| a5  | <-SP  |
    +                               +-----+       v
    +                               | ... |       Lo
    +
    +
  • +
+

Return values from functions

+
    +
  • integer/pointer return values +
    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 +
          +------+                   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 +
    push {fp, lr}
    +mov fp, sp              // FP points to frame record
    +
    +
  • +
  • epilogue +
    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
  • +
+
// 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:

+
> 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

+ + +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3