From fe84155562f3e6d51b94155197ab5606f2e3bebe Mon Sep 17 00:00:00 2001
From: johannst keywords: x86_64, x86, abi keywords: arm64, aarch64, abi0
points to
x86_64
x86_64
dependent featuresarm64
Stack
-
@@ -2779,11 +2786,252 @@ required when compiling natively on arm64.
+
+sp
points to the last used location (valid item)sp
must be 16byte aligned when used to access memory for r/wsp
must be 16byte aligned on public interface interfaces
AArch64
dependent featureskeywords: arm, armv7, abi
+RISC
little
, big
bytes
+[3:0] alt desc
+---------------------------------------------
+r0-r12 general purpose registers
+r11 fp
+r13 sp stack pointer
+r14 lr link register
+r15 pc program counter
+
+bytes
+[3:0] desc
+---------------------------------------------
+cpsr current program status 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)
+
+Reading from system registers:
+mrs r0, cpsr // move cpsr into r0
+
+Writing to system registers:
+msr cpsr, r0 // move r0 into cpsr
+
+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)
+
+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 registerr0
here.
Push/Pop
+push {r0-r2} // effectively stmfd sp!, {r0-r2}
+pop {r0-r2} // effectively ldmfd sp!, {r0-r2}
+
+aapcs32
)reg arg
+-----------
+r0 1
+.. ..
+r3 4
+
+r1+r2
)right-to-left (RTL)
, meaning next arguments are closer to current sp
.
+void take(..., int a5, int a6);
+ | | | ... | Hi
+ | +-->| a6 | |
+ +---------->| a5 | <-SP |
+ +-----+ v
+ | ... | Lo
+
+reg size
+-----------------
+r0 32 bit
+r0+r1 64 bit
+
+r4
- r11
sp
sp
points to the last used location (valid item)sp
must be 4byte aligned (word boundary) at all timesp
must be 8byte aligned on public interface interfacesframe record
+(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
+
+(0,-)
r11
is not updated before the new frame record is fully constructedpush {fp, lr}
+mov fp, sp // FP points to frame record
+
+pop {fp, pc} // pop LR directly into PC
+
+Small assembler skeleton, ready to use with following properties:
+man 2 syscall
for ABI)C runtime (crt)
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.