- Overview of the instruction set
- Processes in the instruction set
- Data Processing Instructions
- load-store order
- 32-bit data constants and instructional expressions
- Function calls and stack access
- Condition Flags and Branch Instructions
- Read Write to the Current Program Status Register
- Coprocessor Access Instructions
Overview of the instruction set
Why do we need to understand the instruction set?
In this article, you will learn the basic knowledge of instruction sets necessary for implementing initialization and interrupt handlers. When debugging or tuning, knowledge of the instruction set will facilitate your development. For more information on instructions, see the Arm and Thumb-2 Instruction Set Quick Reference Card .
Instruction set supported by Cortex-A
Arm processors used two instruction sets: the Arm instruction set (32-bit) and the Thumb instruction set (16-bit); the Cortex-A series used the Arm instruction set (A32 (Arm)) and the Thumb-2 instruction set, a new version of the Thumb instruction set. The
Arm Instruction Set
The Arm instruction set is a 32-bit fixed-length instruction set and is used in Armv4T, Armv5TEJ and Armv6 architectures. It is also supported in the Cortex-A and Cortex-R profiles when performance is important or for compatibility.
Thumb-2 instruction set
Introduced as a 16-bit fixed-length instruction set, with the introduction of Thumb-2 technology, it is a mixed instruction set of 16-bit and 32-bit instruction length, the workhorse instruction set of the Cortex series that combines the performance of the Arm instruction set with the code density characteristics of the Thumb instruction set.
Processes in the instruction set
Basic Form of Assembly Instructions
Assembler instructions perform operations from back to front, just like operations in C. Taking ADD (additive instructions) as an example, the basic form of assembly instructions is shown below.
The number of operands varies from instruction to instruction, so the “Arm and Thumb-2 instructions Set Quick Reference Card.
Data Processing Instructions
Data processing instructions are a generic term for instructions that transfer and operate between registers, and are the basis for learning an instruction set. All Arm processors have a load/store architecture, and arithmetic is done in registers.
- Transfers the data in the register.
- Assigns a medium value to a register.
- Add between the immediate value and the register.
- Subtracts between the immediate value and the register.
- Add between registers.
- Subtracts between registers.
- An AND logical operation is performed between an immediate value and a register.
- Performs an OR-logic operation between an immediate value and a register.
- AND logical operations between registers.
- OR logical operations between registers.
- Performs NOT AND logical operations between the immediate value and the register.
- NOT AND logical operations between registers.
Use a load/store instruction to access a specific address (memory or I/O) for a read or write operation. Set the address to be accessed in a register and access is performed with a single load/store instruction.
Reads a word (32-bit) of data from “address indicated by the value of the r1 register” into the r0 register from memory.
Writes the word (32-bit) data of the r0 register to “address indicated by the value of the r1 register”.
Double-word, half-word and byte-sized access instructions are also available.
- LDRD/STRD double-word size (64 bits)
- LDRH/STRH half-word size (16 bits)
- LDRB/STRB byte size (8 bits)
32-bit data constants and instructional expressions
When using the MOV instruction to set an Immediate Operand, it is “a value that can be expressed by rotating an 8-bit constant any even number of bit times to the right”. The instruction format uses Immed_8 (Immediate Data) and Rotate_imm (Rotate).
For example, if you want to assign 0xFF000000 to the r1 register, it can be expressed by rotating 0xFF eight times.
If you can’t set a set value using the above method, use the Literal Pool to set the constant value to a register. In this example, 0x12345678 will be set to the r0 register by reading the set data to the r0 register in the LDR instruction.
The DCD pseudo-instruction is an assembly language that initializes the word data with an initial value set on a 4-byte boundary.
The Thumb-2 instruction uses the 16-bit constant load instruction (MOVW and MOVT instructions) to load 32-bit constants to further improve efficiency.
What is the LDR Pseudo Instruction?
Determining the size of a constant value and using multiple instructions can be problematic in programming. To solve this problem, the LDR pseudo-instruction is used.
By using the LDR pseudo-instruction, coding is possible regardless of the size of the constant values. The assembler determines whether to use the MOV instruction or a literal pool depending on the size of the Immediate Value.
Function calls and stack access
When performing a function call (subroutine call in assembly language), set the address of
However, if the function call is nesting, the lr will be corrupted and it will be necessary to save it to the stack, so we will make the function call in the following steps
- Save registers and lr to the stack for use in processing.
- Execute the function call process.
- Return the register and pc used in the process from the stack.
When the value of lr is returned to pc, execution is resumed from the next instruction that made the function call.
When calling an assembly language function from C/C++ language, the data size to be saved and returned to the stack is done in 8 byte units. For more information, see “AAPCS (Arm Architecture’s (Procedure Call Standard).
Check the behavior of the stack for r2=0x1234, r3=0x5678, r5=0x2000 and sp=0x100C.
STMFD and LDMFD Instructions
STMFD and PUSH and LDMFD and POP have the same behavior; UAL (Unified Assembler Format) uses PUSH/POP.
Condition Flags and Branch Instructions
cpsrConditional branching, etc., is performed with the conditional flags of the program status register (program status register).
- Indicates that N is a negative number.
- C=indicates the occurrence of overflow in unsigned operations.
- V=indicates the occurrence of overflow in the signed operation.
Instructions for updating condition flags
- CMP r1, r0 ; Set the result of r1-r0 to the condition flags.
Update the NZCV (condition code flag) according to the result of the calculation.
If r1 and r0 have the same value, the condition flag Z=1.
- TST r1, r0 ; conditionally flag the result of r1 AND r0.
Update the NZCV according to the result of the operation.
If the r1 register and the r0 register are AND logic operations and the result is 0, the condition flag is set to 1.
Update condition flags by setting
Data processing and multiplication instructions allow you to choose whether or not to reflect the result of an operation in the condition flags.
|A mnemonic||meaning||Condition flags|
|CS/HS||Carry set/unsigned large or same||C=1|
|CC/LO||Carry reset/unsigned small||C=0|
|PL||Positive number or zero||N=0|
|VC||It’s not an overflow.||V=0|
|HI||unsigned large||C=1 and Z=0|
|LS||Unsigned small or same||C=0 or Z=1|
|GE||Signed large or same||N=V|
|GT||large signalling device||Z=0 and N=V|
|LE||Signed small or same||Z=1 or N!=V|
Conditional branch instruction
When performing loop processing, it is necessary to change the branch destination of the program with the contents of the conditional flags. Before executing a conditional branch instruction, it is necessary to update the conditional flags.
Example of updating a condition flag in software timer processing
The SUB instruction subtracts the loop counter (r0 register) and updates the condition flags, and if executed with the SUB instruction, this program will not operate properly.
Read Write to the Current Program Status Register
To access the cpsr (current program status register), use the MRS and MSR instructions.
Access instruction for cpsr
|Order||field||Program Status Register|
|cpsr_c||Control field mask byte||0ビットから7ビット|
|cpsr_x||Extended Field Mask Bytes||8 to 15 bits|
|cpsr_s||Status field mask byte||16 to 23 bits|
|cpsr_f||Flag field mask byte||24 to 31 bits|
Field Access Instructions for cpsr
Coprocessor Access Instructions
The Cortex-A series must be set up in the coprocessor to control the cache and MMU. For coprocessor access instructions, please refer to the manual (*1) of the processor to be used.
|Order||What it does|
|MRC||Moves from the coprocessor register to a register.|
|MCR||Moves from the Arm register to the coprocessor register.|
|system control register||SCTLR||R||MRC p15, 0,<Rd>, c1, c0, 0|
|W||MCR p15, 0,<Rd>, c1, c0, 0|
|auxiliary control register||ACTLR||R||MRC p15, 0,<Rd>, c1, c0, 1|
|W||MCR p15, 0,<Rd>, c1, c0, 1|
Please refer to the following manuals
This post is also available in: Japanese