How to determine whether an immediate value is a valid immediate value in an ARM instruction

http://blog.sina.com.cn/s/blog_7ea827fe0100torx.html

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    instruction mnemonics, such as LDR, STR,  etc.

Cond        execution conditions, such as EQ, NE,  etc.

                 Does affect the value of the CPSR  register? When writing, it affects the CPSR, otherwise it does not affect

       Rd           target register

         Register of the first operand of Rn 

shifter_operand       second operand

 

The instruction encoding format is as follows:

 

31-28

27-25

24-21

20  

19-16

15-12

11-0  (12th)

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     R3, #0x7F00    ; E3 A0 3C 7F This instruction completes the 0x7f shift by itself

ORR    R1, R3, #2

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_8represents the 8-bit constant,  the so-called "8-bit image", rotate_immrepresents 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;   rotate_imm == 0xC

2. The immediate 0x3F0 is indirectly represented by 0xE3F, that is,
immed_8 == 0x3F;  rotate_imm == 0xE
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;  rotate_imm == 0xF , which is obtained by rotating the 8-bit 0xFC by 30 (2*15) to the right;  rotate_imm == 0xF

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:

  1. 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.
  2. 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.
Therefore, in future programming, always check whether the second operand used conforms to the 8-bit bitmap is a thing that must not be neglected. As for why the 12-bit operand2 "eighty-four open", this question should be consulted. Cattle

Guess you like

Origin blog.csdn.net/lgdlchshg/article/details/78605140