Changes

Jump to: navigation, search

AArch64 Register and Instruction Quick Start

2,100 bytes added, 14:06, 2 March 2020
Starter Kit
[[Category:Assembly Language]]
 
This page contains very basic information on the AArch64 mode of the [[ARMv8]] architecture: the [[Register|register]] layout and naming and the some basic instructions.
 
== Registers ==
The aarch64 registers are named:
* r0 through r30 - to refer generally to the registers
* x0 through x30 - for 64-bit-wide access(same registers)* w0 through w30 - for 32-bit-wide access (same registers - upper 32 bits are either cleared on loador sign-extended (set to the value of the most significant bit of the loaded value)).
Register '31' is one of two registers depending on the instruction context:
* For all other instructions, it is a "zero" register, which returns 0 when read and discards data when written - named rzr (xzr, wzr)
Usage during [[Syscalls|syscall]]/function call:* '''r0-r7 are used for arguments and return values; additional arguments are on the stack'''
* '''For syscalls, the syscall number is in r8'''
* '''r9-r15 are for temporary values (may get trampled)'''
* r16-r18 are used for intra-procedure-call and platform values (avoid)
* '''The called routine is expected to save preserve r19-r28*** These registers are generally safe to use in your program.'''
* r29 and r30 are used as the frame register and link register (avoid)
=== Starter Kit ===
These instructions are sufficient to complete the [[SPO600 Assembler Lab]]:; remember to replace the generic register names with ones that specify width (for example, replace "r0" with "x0" or "w0").  add r0,r1,r2 // load r0 with r1+r2 add r0,r1,99 // load r0 with r1+99 adr r0,''label'' // load r0 with the address ''label'' (this actually calculates an address from the [[Register#Program Counter|PC]] plus an offset) bl ''label'' // branch (with link) to label - this is a procedure / subroutine / function call br ''label'' // branch to label - this is a goto br ''register'' // branch to the address in register b.eq ''label'' // branch to label if equal b.ne ''label'' // branch to label if not equal b.lt ''label'' // branch to label if less b.gt ''label'' // branch to label if greater cmp r0,r1 // compare register r0 with register r1. The comparison sets flags in the processor status register which affect conditional branches. cmp r0,99 // compare the number 99 with register r0. The comparison sets flags in the processor status register which affect conditional branches. ldr r0,[r1,0] // load register r0 from the address pointed to by (r1 + (0 * ''size'')) where ''size'' is 8 bytes for 64-bit stores, 4 bytes for 32-bit stores ldr w0,[r1,0] // like above but reads 32 bits only - note the use of w0 instead of r0 for the source register name ldrb w0,[r1,0] // like above but reads 1 byte (8 bits) only - note the use of w0 for the source register name ldur r0,[r1,0] // load register r0 from the address pointed to by (r1 + 0) - the mnemonic means "load ''unscaled'' register" mov r0,r1 // move data from r1 to r0 mov r0,99 // load r0 with 99 (only certain immediate values are possible) ret // return from subroutine (counterpart to bl) str r0,[r1,0] // store register r0 to address pointed to by (r1 + (0 * ''size'')) where ''size'' is 8 bytes for 64-bit stores strb w0,[r1,0] // like str but writes one byte only - note the use of w0 for the source register name stur r0,[r1,0] // store register r0 to the address pointed to by (r1 + 0) - the mnemonic means "store ''unscaled'' register" svc 0 // perform a syscall msub r0,r1,r2,r3 // load r0 with r3-(r1*r2) (useful for calculating remainders) madd r0,r1,r2,r3 // load r0 with r3+(r1*r2) mul r0,r1,r2 // load r0 with r1*r2 (actually an alias - see ARM ARM) push r0 // push r0 onto the stack pop r0 // pop r0 off the stack udiv r0,r1,r2 // unsigned - divide r1 by r2, places quotient into r0 - remainder is not calculated (use msub)
add r0,r1,r2 // load r0 with r1+r2Note the syntax: add r0,r1,99 // load r0 with r1+99* [[Register]] names are not prefixed. adr r0,''label'' // load r0 with the address ''label'' (this actually calculates an address from the * [[Register#Program CounterImmediate Value|PCImmediate values]] plus an offset) beq ''label'' // branch to label if equal bne ''label'' // branch to label if are not equal blt ''label'' // branch to label if less bgt ''label'' // branch to label if greater cmp r0,r1 // compare register r0 prefixed with register r1 cmp r0,99 // compare the number 99 a character (they may be prefaced with register r0# if desired). ldr r0,[r1,0] // load register r0 from the address pointed to by (r1 + (0 * ''size'')) where ''size'' Indirect memory access is 8 bytes for 64-bit stores, 4 bytes for 32-bit stores ldr w0,indicated by [r1,0square brackets] // like ldr but reads one byte only - note the use of w0 instead of r0 for the source register name. ldur r0,[r1,0] // load register r0 from the address pointed to * Hexadecimal values are indicated by (r1 + 0) - the mnemonic means "load ''unscaled'' register"a 0x prefix. mov r0,r1 // move data from r1 to r0 mov r0,99 // load r0 with 99 (only certain immediate * Character values are possible) str r0,[r1,0] // store register r0 to address pointed to indicated by quotation marks. Escapes (r1 + (0 * ''sizesuch as '\n')) where ''size'' is 8 bytes for 64-bit storesare permitted. strb w0* Destinations are given as the first argument (mov r0,[r1,0] // like str but writes one byte only - note the use of w0 instead of r0 for the source register name stur moves INTO r0,[FROM r1,0] // store register ; you can think of this as r0 to the address pointed to by (=r1 + 0) - .* For the mnemonic means "store ''unscaled'' register" svc 0 LDR// perform STR instructions: you can append a syscall msub r0,r1,r2,r3 // load r0 with r3-character indicating the number of bits (r1*r2) (useful for calculating remainderslowest)to be loaded or stored: madd r0,r1,r2,r3 // load r0 with r3+(r1*r2)* Q = Quadword = 64 bits mul r0,r1,r2 // load r0 with r1*r2 (actually an alias - see ARM ARM)* D = Double word = 32 bits push r0 // push r0 onto the stack** W = Word = 16 bits pop r0 // pop r0 off the stack udiv r0,r1,r2 // unsigned - divide r1 by r2, places quotient into r0 - remainder is not calculated (use msub)** B = Byte = 8 bits
== References Resources ==
* Instruction Set and Software Developer Manual: ARM Aarch64 documentation** [http://infocenterdeveloper.arm.com/helpARM Developer Information Centre]*** [https:/index.jsp?topic=/comdeveloper.arm.doccom/docs/den0024/latest ARM Cortex-A Series Programmer’s Guide for ARMv8-A]*** The ''short'' guide to the ARMv8 instruction set: [https://www.element14.genc010197acom/indexcommunity/servlet/JiveServlet/previewBody/41836-102-1-229511/ARM.Reference_Manual.htmlpdf ARMv8 Instruction Set Overview] ("ARM ISA Overview")* Procedure call reference** The ''long'' guide to the ARMv8 instruction set: http[https://infocenterdeveloper.arm.com/helpdocs/topicddi0487/comlatest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile] ("ARM ARM")** [https://developer.arm.doccom/docs/ihi0055/latest/procedure-call-standard-for-the-arm-64-bit-architecture Procedure Call Standard for the ARM 64-bit Architecture (AArch64)]* GAS Manual - Using as, The GNU Assembler: https://sourceware.ihi0055borg/binutils/docs/as/IHI0055B_aapcs64.pdf

Navigation menu