ARM Assembly Language Specifics

The examples use GNU assembler syntax for AArch64. A line comment starts with //. The semicolon separates statements; this book places each instruction on its own line.

ADD X0, X1, X2    // X0 = X1 + X2
Table 1: Architecture, execution state and instruction-set terminology
Term Meaning
Armv8-A An architecture version for the application profile. Implemented features depend on the processor.
AArch64 The 64-bit execution state, using the A64 instruction set.
A64 Fixed-width 32-bit instruction encodings; instructions can operate on 32-bit or 64-bit data.
AArch32 The 32-bit execution state, using A32 or T32 where supported.
A32 The instruction set traditionally called ARM, with 32-bit instruction encodings.
T32 The Thumb instruction set, containing both 16-bit and 32-bit encodings.
Cortex-A76 The CPU core used in Raspberry Pi 5.

Cortex-M processors implementing Armv7-M execute Thumb instructions, not A32 instructions. Different Thumb encoding widths can appear in the same instruction stream. A32 and T32 support must not be inferred solely from a processor being described as an Arm processor.

The following encoding comparison is supplementary material. The remaining programming examples use A64.

A64

The encoding in figure 1 represents the register-copy form of MOV, an alias of ORR with the zero register as its first source. The sf bit selects a 32-bit or 64-bit operand width. It changes a bit in the instruction encoding, while the instruction itself remains 32 bits long.

Diagram of A64 MOV instruction machine code format showing bit fields: opcode bits, sf bit for 32/64-bit selection, Rm source register (5 bits), Rd destination register (5 bits), and reserved/condition fields. Allows addressing all 32 CPU registers.
Figure 1: Machine Code for the MOV Instruction in the A64 Instruction Set

The Rm and Rd fields select the source and destination. A five-bit register field has 32 possible encodings, but AArch64 has 31 general-purpose registers. In this form, encoding 31 selects the zero register. Fields fixed by this MOV alias, including N, must retain their specified values; they are not ignored or arbitrary.

A32

Figure 2 shows the same instruction, but the register address is smaller than in the A64 instruction. The bitfields' Rd' and 'Rm' are 4-bit wide, so only 16 CPU registers can be addressed using this instruction in A32.

Diagram of A32 MOV instruction machine code format with opcode bits, cond field (4 bits), S bit for status register update, Rd destination register (4 bits), Rm source register (4 bits), stype shift type field, and imm5 shift amount field. Limited to 16 general-purpose registers.
Figure 2: Machine Code For the MOV Instruction in the A32 Instruction Set

Other bitfields, like 'cond', are also used for conditional instruction execution. The 'S' bit identifies whether the status register must be updated. The 'stype' bitfield is used for the type of shift to be applied to the second source register, and finally, the 'imm5' bitfield is used to identify the shift amount 0 to 31.

Table 2: Shift Options
'stype' bit-field value Shift type Meaning
0b00 LSL Logical Shift Left
0b01 LSR Logical Shift Right
0b10 ASR Arithmetic Shift Right
0b11 ROR ROtate Right

Shifts and rotations are illustrated in figures 3, 4, 5, 6 and 7. A left shift by k positions multiplies an unsigned value by 2 to the power k and keeps only the low w bits, where w is the register width. Logical right shift divides an unsigned value by that power, discarding the remainder. Arithmetic right shift preserves the sign and rounds a negative value towards negative infinity; this differs from signed division, which rounds towards zero. A rotate moves the shifted-out bits back into the opposite end of the register.

Diagram demonstrating logical left shift operation where each bit moves one position to the left, vacated positions filled with zeros, and leftmost bit is lost. Original value 0110 becomes 1100 after left shift by 1.
Figure 3: Logical Left Shift
Diagram demonstrating logical right shift where each bit moves one position to the right, vacated positions filled with zeros, and rightmost bit is discarded. Original value 0110 becomes 0011 after right shift by 1.
Figure 4: Logical Right Shift
Diagram showing arithmetic right shift with most significant bit (MSB) equal to 0. Bits move right, rightmost bit discarded, and vacated positions filled with 0 (sign extension with positive sign). 0110 becomes 0011.
Figure 5: Arithmetic Right Shift with MSB Equal to 0
Diagram showing arithmetic right shift with MSB equal to 1. Bits move right, rightmost bit discarded, and vacated positions filled with 1 (sign extension with negative sign). 1010 becomes 1101 preserving sign.
Figure 6: Arithmetic Right Shift with MSB Equal to 1
Diagram demonstrating right rotate (circular shift) where bits move right, rightmost bit wraps to leftmost position creating circular rotation. Original value 0110 becomes 0011 with bit exiting on right entering on left.
Figure 7: Right Circular Shift

T32

The Thumb instructions have multiple machine codes for this one operation.

Diagram of T1 THUMB instruction format (16 bits) with opcode field, D bit combined with 3-bit Rd field to address 16 registers, and Rm source register (3 bits addressing 8 registers). Simplest Thumb MOV format with register restrictions.
Figure 8: T1 THUMB Instruction

T1 THUMB instruction 'D' bit and 'Rd' fields together identify the destination register (figure 8). The source and destination registers can now be addressed with only 4 bits, so only 16 general-purpose registers are accessible. Fewer registers are available in the following machine code. Figures 9 and 10 present T2 and T3 THUMB instructions, respectively.

Diagram of T2 THUMB instruction format (16 bits) showing opcode bits, OP field for shift type, imm5 field for shift amount, Rm source register (3 bits), and Rd destination register (3 bits). Allows only 8 accessible registers for limited operations.
Figure 9: T2 THUMB Instruction

The 'OP' bitfield specifies the shift type, and imm5 specifies the amount. The result 'Rd' will be shifted by 'imm5' bits from the 'Rm' register. Notice that only three bits are used to address the general-purpose registers – only eight registers are accessible. The T3 encoding shown in figure 10 is 32 bits wide. Its four-bit register fields identify registers in the AArch32 register set. The imm3 and imm2 fields together encode the shift amount. This instruction provides more shift operations than the previous one, but instead of a single 'imm5' field specifying the shift amount, the shift amount is split into two fields: 'imm3' and 'imm2'. Both parts are combined for the same purpose: to determine the amount of the shift.

Diagram of T3 THUMB instruction format (32 bits) showing opcode bits, Rd and Rm fields (4 bits each for 16 registers), imm3 and imm2 fields split to form complete shift amount. More complex Thumb format with extended shift capabilities.
Figure 10: T3 THUMB Instruction

Thumb instructions with different encoding widths can coexist in one program. The assembler chooses a supported encoding according to the instruction and its operands. The distinction between A32, T32 and A64 concerns execution states and instruction-set design, not a requirement to use one encoding width throughout a Thumb program. The examples that follow use A64 and registers X0–X30 or their W0–W30 views.

en/multiasm/paarm/chapter_5_2.txt · Last modified: by karlisberkolds
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0