Armv8 Registers
Before introducing operation instructions, let's have a brief look at the register names and data features in the Armv8 architecture.
In the Armv8 architecture, registers are classified into 64-bit registers and 128-bit registers. For a 64-bit register, Xn and Wn are used to represent the 64 bits and lower 32 bits of the register, respectively, as shown in Figure 1.
A 128-bit register can be used as a scalar register. Qn, Dn, Sn, Hn, and Bn are used to represent the 128 bits, lower 64 bits, lower 32 bits, lower 16 bits, and lower 8 bits of the register, respectively, as shown in Figure 2. It can also be used as a vector register. Vn.2D, Vn.4S, Vn.8H, and Vn.16B indicate that the 128-bit register is divided into 64-bit, 32-bit, 16-bit, and 8-bit channels, respectively, as shown in Figure 3.
According to the preceding naming rules, the same instruction can be used to process data of different lengths. This is often applied to data truncation. For example, in the following code, eight bytes are loaded to registers x1 and x2 respectively. However, the logic only needs to compare the lower 32-bit data. In this case, the two registers are represented in the form of w, and the 32-bit data does not need to be reloaded to another register.
... ... ldr x3, [x0] ldr x4, [x1] cmp w3, w4 /* compare */ ... ...
It should be noted that a prerequisite for data multiplexing is that the instruction takes effect on a register represented in this form. The Q register (128-bit scalar register) and the V register (128-bit vector register) are the same set of registers using two sets of instructions. That is, data is stored in the same 128-bit register. However, the scalar assembly instruction applies only to the 128-bit register represented in scalar form, and the vector assembly instruction (also called the neon instruction) applies only to the 128-bit register represented in vector form. The two types of instructions cannot be used together. Otherwise, the compiler reports an error.
Defining Registers
If we use digits to identify registers for a large amount of assembly code, the register values will be confusing. In addition, the code will be developer unfriendly. A better way is to define the register function by using define at the header of the code file as shown in the following code:
#define data1 x3 #define data2 x4 #define Lowdata1 w3 #define Lowdata2 w4 #define src1 x0 #define src2 x1 ... ... ldr data1, [src1] ldr data2, [src2] /* compare */ cmp Lowdata1, Lowdata2 ... ...


