In the assembly language of the ARM processor, there are provisions for the constant expression of the <shifter_operand> in the instruction syntax format: "The constant must correspond to an 8-bit bitmap, that is, the constant is an even number cyclically shifted by an 8-bit constant Bit."<?xml:namespaceprefix = o ns = "urn:schemas-microsoft-com:office:office"/>
Let's start with the grammatical format of the ARM instruction system.
The syntax format of an ARM instruction is divided into the following parts:
<opcode>{<cond>}{S}<Rd>,<Rn>{,<shifter_operand>}
Among them, the items in <> are required, the items in {} are optional, such as <opcode> is the instruction mnemonic, which is required, and {<cond>} is the instruction execution condition, which is optional , If not written, the default condition AL (unconditional execution) is used.
Opcode
Cond
shifter_operand
The instruction encoding format is as follows:
31-28 |
27-25 |
24-21 |
20 |
19-16 |
15-12 |
11-0 |
cond |
001 |
opcode |
S |
Rn |
Rd |
shifter_operand |
When the form of the second operand is: #immed_8r constant expression, "the constant must correspond to an 8-bit bitmap, that is, the constant is obtained by cyclically shifting an 8-bit constant to an even number."
It means this:
#Immed_8r represents a 32-bit number when the chip is processed, but it is obtained from an 8-bit number (for example: 01011010, that is, 0x5A) by cyclically shifting even digits (10000000 0000 0000 0000 0000 0001 0110, that is, 0x5A is shifted to the right through the cycle 2 digits (even digits).
However, 1010 0000 0000 0000 0000 0000 00010110 does not meet this requirement, and an error must be made during compilation. Because you may get it by cyclically shifting 10110101 to the right, but it is impossible to get it by cyclically shifting even-numbered bits. 1011 0000 0000 0000 0000 0000 00010110 also does not meet this requirement. Obviously, 1 0110 1011 has 9 digits.
Why is there such a requirement?
To explain from the instruction encoding format (this is why I talked about the instruction encoding format at the beginning), carefully look at the number of bits occupied by shifter_operand in the table: 12 bits. It is absolutely impossible to use a 12-bit code to represent any 32-bit number (12-bit numbers have 2^12 possibilities, and 32-bit numbers have 2^32 types).
But what should I do if a 12-bit code is used to represent 32-bit numbers?
There is only a limit on the number of representations. Through the coding to achieve the use of 12-bit coding to represent 32-bit numbers.
In the 12-bit shifter_operand: 8 bits store data, 4 bits store the number of shifts.
8-bit storage data: Explained that "the constant must correspond to an 8-bit bitmap".
The number of shifts in 4-bit storage: explains why only even digits can be shifted. There are only 16 possible values for 4 bits, and 32 bits can be cyclically shifted 32 times (32 possible), so we have to limit: only even digits can be shifted (two digits are shifted, as if a 16 digit is shifting , 16 kinds of shift possible). In this way, the contradiction that the situation that can be represented is half of the actual situation is solved.
So the restriction on the #immed_8r constant expression is a helpless move to solve the problem that the second operand of the instruction code is not enough to represent the 32-bit operand, but in my opinion: this can be said to be a smart approach. Because if you directly use 12 digits to represent 32-bit operands, you can only represent 0 to (2^12-1). Numbers greater than (2^12-1) cannot be represented. And if you think about it carefully, "8 bits store data, 4 bits store the number of shifts", it should be the best combination (I haven't thought about all the combinations, just tried a few by the way).
ARM instruction second operand #immed_8r detailed explanation
Most ARM general data processing instructions have a flexible second operand (flexible secondoperand), here is an explanation of one of the formats, #immed_8r constant expression. The constant must correspond to an 8-bit pattern. The bitmap is cyclically shifted by even-numbered bits (0,2,4,...28,30) in a 32-bit word. Legal constants 0xff, 0xff000, 0xf000000f. Illegal constant: 0x101,0xff04
In the 32-bit mode of ARM, an instruction is 32 bits long. In the above data processing instructions, operand 2 is 12 bits. So a number like 0x7f02 requires two instructions to complete.
MOV
ORR
So I can’t find 0x7f02
Regarding cyclic shift, in fact, there is only cyclic right shift (ROR) in arm. 0x7f to 0x7f00 are realized by circular shifting 24 times to the right, here each shift is 2 bits so it is 12 times (0xc)
In the ARM data processing instructions, when the second operand involved in the operation is an immediate value, each immediate value is obtained indirectly by using an 8-bit constant to rotate the even digits to the right. Among them, the number of digits to be rotated right is one The double representation of 4-bit binary. The effective immediate number can be expressed as:. <immediate> :=immed_8; 循环右移(2×rotate_imm)
Among them: <immediate>
represents the immediate number, immed_8
represents the 8-bit constant, rotate_imm
represents the 4-bit cyclic right shift value. This way it appears There is a problem: Although the range of representation has become larger, the number of numbers that can be represented by 12 bits is certain. Therefore, ARM stipulates that not all 32-bit constants are legal immediate numbers, only through the above construction The method gets the legal immediate value, and it will not report an error when compiling.
Take an example.
0x3FC (0000 0000 0000 0000 0000 00 11 1111 11 00) is obtained by rotating 0xff by 2 bits;
200 (0000 0000 0000 0000 0000 00 00 1100 10 00) is obtained by rotating 0xc8 by 2 bits. Obtained, they are all legal.
And 0x1FE (0000 0000 0000 0000 0000 0001 1111 1110) and
511 (0000 0000 0000 0000 0000 0001 1111 1111) cannot be regarded as 8 -bit constants obtained by rotating the even digits to the right . Therefore it is illegal.
When the instruction operand is immediate, each immediate is obtained by shifting the even digits to the right by an 8-bit constant.
<immediate>= immed_8 cyclic right shift (2*rotate_imm)
, for example:
1. The immediate value 0xF200 is indirectly represented by 0xCF2, that is,
immed_8 == obtained by cyclically shifting the 8-bit 0xF2 to the right by 24 (2*12) 0xF2;
2. The immediate 0x3F0 is indirectly represented by 0xE3F, that is,
immed_8 == 0x3F;
or the
immediate 0x3F0 is obtained by rotating the 8-bit 0x3F to the right by 28 (2*14) Indirectly represented by 0xFFC, that is,
immed_8 == 0xFC;
means that there are several
PS: In fact, you don’t need to count one by one. Just use the LDR pseudo-instruction, for example:
ldr r1, =12345678 The
compiler will naturally do the work for you. It should be the same in real programming.
In comparison, we can summarize it like this:
- To judge whether a number conforms to the principle of 8-bit bitmap, first see whether the number of 1s in the binary representation of the number does not exceed 8. If it does not exceed 8, then see whether these n 1s (n<=8) can Put it in 8 binary digits at the same time, if you can put it in, then see if these eight binary digits can be rotated right by even digits to get the number we want to use. If it can, then this number conforms to the 8-bit bitmap principle and is legal The immediate value. Otherwise, it does not meet.
- The unrepresentable 32-bit number can only be obtained through other means such as logic or arithmetic operations. For example, 0xffffff00, which can be obtained by bitwise inversion of 0x000000ff.
operand2
"eighty-four open", this question should be consulted. Cattle