ARM学习笔记(四)

来源:互联网 发布:送女朋友的礼物 知乎 编辑:程序博客网 时间:2024/05/14 12:38





ARM指令集的概要介绍

ARM指令集的分类

跳转指令

数据处理指令

程序状态寄存器(PSR)传输指令

Load/Store指令

协处理器指令

异常中断产生指令

ARM指令的语法格式

<opcode>[cond][S] <Rd>,<Rn>,<shifter_operand>

其中:

Opcode:指令助记符;

[cond]:可选的指令执行条件;

[S]:决定指令的操作是否影响CPSR的值;

<Rd>:目标寄存器;

<Rn>:表示包含第一个操作数的寄存器;

<shifter_operand>:表示第二个操作数。

ARM指令的编码格式

ARM指令字长固定为32位,一条典型的ARM指令的编码格式如下:

31    28

27    25

24    21

20

19    16

15    12

11     8

7      0

cond

001

opcode

S

Rn

Rd

shifter_operand

 

ARM指令的条件码域

大多数ARM指令都可以根据CPSR中的标志位的值来决定是否执行该指令。ARMV5以前所有指令都是条件执行的,从ARMV5以后引入了一些必须无条件执行的指令。

 

每一条ARM指令可以包含四位的条件码,条件码共有16个,各条件吗的助记符及含义如下:

条件码(cond)

条件码助记符

含义

CPSR中条件标志位的值

0b0000

EQ

相等(Equal)

Z==1(Z set)

0b0001

NQ

Not equal

Z==0(Z clear)

0b0010

CS/HS

Carry Set/unsigned higher or same

无符号数大于/等于

C==1(C set)

0b0011

CC/LO

Carry clear/unsigned lower

无符号数小于

C==0(C clear)

0b0100

MI

Minus/negative(负数)

N==1

0b0101

PL

Plus/positive or zero(非负数)

N==0

0b0110

VS

Overflow(上溢出)

V==1

0b0111

VC

No overflow(没有上溢出)

V==0

0b1000

HI

Unsigned higer(无符号数大于)

C==1 and Z==0

0b1001

LS

Unsigned lower or same

C==0 and Z==1

0b1010

GE

Signed greater than or equal

N==V

(N==1 and V==1

     or

N==0 and V==0)

0b1011

LT

Signed less than

N!=V

0b1100

GT

Signed greater than

Z clear, and either N set and V set ,or N clear and V clear(Z==0,N==V)

0b1101

LE

Signed less than or equal

Z==1 or N!=V

0b1110

AL

Always(unconditional)无条件执行

-----------------------

0b1111

AV

该指令从不执行

-----------------------

 

ARM指令寻址方式

1. 数据处理指令的操作数的寻址方式

2. 字及无符号字节的Load/Store指令的寻址方式

3. 杂类Load/Store指令的寻址方式

4. 批量Load/Store指令的寻址方式

5. 协处理器Load/Store指令的寻址方式

 

数据处理指令中的的操作数的寻址方式

<opcode>[cond][S] <Rd>,<Rn>,<shifter_operand>

Shifer_operand有三种表示方式:立即数方式,寄存器方式,寄存器移位方式。

 

立即数方式,每个立即数由一个8位的常数循环右移偶数位得到。其中循环右移的位数由一个4位二进制数的2倍表示。如立即数记作<immediate>8位常数记作immed_8,四位循环右移的常数记作rotate_imm,则有:

Immediate = immed_8 循环右移 (2 * rotate_imm)

  这样并不是每一个32位常数都是合法的立即数,只有通过以上方法构造的才是合法的立即数。

  一个合法的立即数可以有多种编码方法(取不同的immediateimmed_8),由于循环右移会影响CPSRC标志位值,因此同一个合法的立即数采用不同的编码方式将使不某些指令产生不同的执行结果,这是不允许的,因此ARM处理器对立即数采用了如下的编码方式:

      当立即数值在00xFF之间时,令immed_8=<immediate>rotate_imm=0

      其它情况下编译器使用rotate_imm最小的编码方式。

 

ARM指令系统

 

一.跳转指令

ARM中有两种方式可以实现程序的跳转,一种是跳转指令,另一种是直接向PC(R15)中写入目标地址。后一种方式可以实现在4GB的地址空间中任意跳转,前一种方式可以实现在当前指令前后32M的地址空间中任意跳转。

 

四种跳转指令:

1.  B:跳转指令;

2.  BL:带返回的跳转指令(跳转前将PC值保存在LR(R14)中用于返回);

3.  BLX:带返回和状态切换的跳转指令;

4.  BX:带状态切换的跳转指令。

 

BBL(用于子程序调用)

  指令语法格式B[L][cond] <target_address>

  指令编码格式

31

28

27

26

25

24

23            0

cond

1

0

1

L

signed_immed_24

  L决定是否保存返回值地址,有时保存PC值于LR(R14)中,无时不保存。

  target address:指令跳转的目标地址。其计算方法是将指令中的24位带符号数的补码立即数扩展为32(扩展符号位),将此32位数左移2位,将得到的值加到PC寄存器中得到的即为跳转的目标地址(由此可知跳转范围为-32M-+32M(223*2*2))。

  指令操作的伪代码:

      If ConditionPassed(cond) then

         If L==1 then

            LR=address of the instruction after the branch instruction

            PC=PC+(SignExtend(Sign_immed_24) << 2)

         …..

BLX <target_address>:跳转到目标地址,将程序状态切换为Thumb状态,复制PCLR,用于从ARM指令中调用Thumb子程序…..

BX <target_address>:目标地址处的指令可以是ARM指令也可以是Thumb指令,目标地址为<target_address>0xFFFFFFFF做与操作的结果,目标地址处的指令类型由Rmbit[0]决定。

二.数据处理指令

数据传送指令用于向寄存器中传入一个常数;

算数逻辑运算指令

比较指令不保存运算结果,只更新CPSR中相应的条件标志位。

 

数据处理指令包括:

MOV 数据传送指令

MVN 数据求反传送指令

CMP 比较指令

CMN 基于相反数的比较指令

TST 位测试指令

TEQ 相等测试指令

ADD 加法指令

SUB 减法指令

RSB 逆向减法指令

ADC 带位加法指令

SBC 带位减法指令

RSC 带位逆向减法指令

AND 逻辑与

BIC 位清除

EOR 逻辑异或操作指令

ORR 逻辑或操作指令

 

1.       MOV(P75)

Syntax formatMOV[cond][S] Rd<shifter_operand>

Coding format

31    28

27    25

24    21

20

19    16

15    12

11     8

7      0

cond

001

1101

S

SBZ(0)

Rd

shifter_operand

 

The MOV(MOVE) instruction moves the value of <shifter_operand> to the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Operation:

  If ConditionPassed(cond) then

     Rd = shifter_operand

     If S == 1 and Rd == R15 then

        CPSR = SPSR

     If S == 1 then

        N Flag = Rd[31]

      Z Flag = if Rd == 0 then 1 else 0

      C Flag = shifter_carry_out

      V Flag = unaffected

Usage

   MOV is used to:

.Move a value from one register to another.

.Put a constant value into a register.

.Perform a shift without other arithmetic or logical operation.A left shift by n can be used to multiply by 2n.

.When the PC is the destination of the instruction,a branch occurs.The instruction

MOV PC LR can therefore be used to return from a subroutine.

.When the PC is the destination of the instruction and the S bit is set,a branch occurs and the SPSR of the current mode is copied to the CPSR.This means that a MOV PC LR instruction can be used to return from some types of exception.

2.       MVN(76)

Syntax format and coding format are same as MOV.

The MVN instruction moves the logical one’s complement(补码) of the value of <shifter_operand> to the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Usage

MVN is used to:

.write a negative value into a register

.form a bit mask(位掩码)

.take the one’s complement of a value

3.       ADD(76)

Syntax formatADD[cond][S] <Rd>,<Rn>,<shifter_operand>

Coding format

31    28

27    25

24    21

20

19    16

15    12

11     8

7      0

cond

001

0100

S

Rn

Rd

shifter_operand

     

The add instruction adds the value of <shifter_operand> to the value of register <Rn>,and stores the result in the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Operation

  if ConditionPassed(cond) then

     Rd = Rd + shifter_operand

     if S == 1 and Rd == R15 then

        CPSR = SPSR

     else if S == 1 then

        N Flag = Rd[31]

        Z Flag = if Rd == 0 then 1 else 0

        C Flag = CarryFrom(Rn + shifter_operand)

        V Flag = OverflowFrom(Rn + shifter_operand)

 

4.       ADC(77)

Syntax format and coding format are same as ADD.

The ADC(Add with Carry) instructions adds the value of <shifter_operand> and the Carry flag to the value of <Rn> and stores the result in <Rd>.The condition code flags are optionally updated,based on the result and S bit.

Operation

  if ConditionPassed(cond) then

     Rn = Rn + shifter_operand + C Flag

     if S == 1 and Rd == 15 then

        CPSR = SPSR

     else if S == 1 then

        N Flag = Rd[31]

        Z Flag = if Rd == 0 then 1 else 0

        C Flag = CarryFrom(Rn + shifter_operand + C Flag)

        V Flag = OverflowFrom(Rn + shifter_operand + C Flag)

5.       SUB(78)

Syntax format and coding format are same as ADD.

The SUB(Subtract) instruction subtracts the value of <shifter_operand> from the value of register <Rn>,and stores the result in <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Operation

  if ConditionPassed(cond) then

     Rd = Rn - shifter_operand

     if S == 1 and Rd ==R15 then

        CPSR = SPSR

     else if S == 1 then

        N Flag = Rd[31]

        Z Flag = if Rd == 0 then 1 else 0

        C Flag = NOT BorrowFrom(Rn – shifter_operand)

        V Flag = OverflowFrom(Rn – shifter_operand)

6.SBC

The syntax format and coding format are same as sub instruction.

The SBC instruction(Subtract with Carry) instruction is used to synthesize multi-word subtraction. SBC subtracts the value of <shifter_operand> and the value of NOT(Carry flag) from the value of register <Rn>,and stores the result in the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S Bit.

Operation

if ConditionPassed(cond) then

Rd = Rn – shifter_operand – NOT(C Flag)

if S==1 and Rd == R15 then

CPSR = SPSR

else if S==1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag = NOT BorrowFrom(Rn – shifter_operand – NOT(C Flag))

V Flag = OverflowFrom(Rn – shifter_Operand – NOT(C Flag))

Usage

SBC is used to synthesize multi-word word subtraction.If register pairs R0,R1 and R2,R3 hold 64 bit values(R0 and R2 hold the least significant words(低字) ),the following instructions leave the 64-bit difference in R4,R5(R4 hold the least significant word):

SUBS R4,R0,R2

SBC R5,R1,R3


7.RSB

The syntax format and coding format are same as the SUB instruction.

The RSB(Reverse Subtract) instruction subtracts the value of register <Rn> from the value of shifter_oprand,and stores the result in the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Operation

if ConditionPassed(cond) then

Rd = shifter_operand – Rn

if S==1 and Rd == R15 then

CPSR = SPSR

else if S==1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag = NOT BorrowFrom(shifter_operand - Rn)

V Flag = OverflowFrom(shifter_operand – Rn)

8.RSC

The syntax format and coding format are same as the SUB instruction.

The Rsc(Reverse Subtract with Carry) instruction subtracts the value of register <Rn> and the value of NOT(Carry flag) from the value <shifter_operand>,and stores the result in the destination register <Rd>.The condition code flags are optionally updated,based on the result and the S bit.

Operation

if ConditionPassed(cond) then

Rd = shifter_operand – Rn – NOT(Carry Flag)

if S == 1 and Rd == R15 then

CPSR SPSR

else if S == 1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag = NOT BorrowFrom(shifter_operand – Rn – NOT(C Flag))

V Flag = OverflowFrom(shifter_operand – Rn – NOT(C Flag))

Usage

To negate(求负) the 64-bit value in R0,R1,use the following sequence(R0 holds the least significant word) which stores result in R2,R3(R2 holds the least significant word):

RSBS R2,R0,#0

RSC R3,R1,#0

9.AND

Syntax format: AND[cond][S] <Rd>,<Rn>,<shifter_operand>

The coding format is same as the sub instruction.

The AND instruction performs a bitwise AND of the value of register <Rn> and the value of <shifter_operand>,and stores the result in the destination register <Rd>.The condition codes are optionally updated,based on the result and the S bit.

Operation

if ConditionPassed(cond) then

Rd = Rd AND(bitwise) shifter_operand

else if S == 1 and Rd == R15 then

CPSR = SPSR

else if S == 1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag = shifter_carry_out

V Flag = unaffected

Usage

AND is most useful for extracting a field from a register,by ANDing the register with a mask value that has 1s in the field to be extracted,and 0s elsewhere.

10.ORR

The syntax format and coding format are same as the AND instruction.

The ORR(Logical OR) instruction performs a bitwise(inclusive) OR of the value of the register <Rn> with the value of <shifter_operand>,and stores the results in the destination register <Rd>.The condition code flags are optionally updated,based on the result.

Operation

if ConditionPassed(cond) then

Rd = Rn OR(bitwise) shifter_operand

if S == 1 and Rd == R15 then

CPSR = SPSR

else if S == 1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag = shifter_carry_out

V Flag = unaffected

Usage

ORR can be used to set selected bits in a register.For each bit,OR with 1 sets the bit ,and OR with 0 leaves it unchanged.

   三.乘法指令

ARM有两类乘法指令,一类为32位乘法指令(结果为32),一类为64位乘法指令(结果为64)。共有6条指令。


1.MUL(Multiply)

Syntax format: MUL[cond][S] <Rd>,<Rm>,<Rs>

where:

[cond] Is the condition under which the instruction is executed. The conditions are defined in The condition fields in CPRS. If <cond> is omitted, the AL(Always) condition is used.

[S] Causes the S bit(bit[20]) in the instruction to be set to 1 and specifies that the instruction updates the CPSR by setting the N and Z flags according to the result of the multiplication. If S is omitted, the S bit of the instruction is set to 0 and the entire CPSR is unaffected by the instruction.

<Rd> Specifies the destination register for the instruction

<Rm> Specifies the register that contains the first value to be multiplied.

<Rs> Holds the value to be multiplied with the value of <Rm>


Conding format:

31

28

27

21

20

19

16

15

12

11

8

7

4

3

1

cond

0000000

(opcode)

S

Rd

SBZ

(0000)

Rs

1001

Rm


The MUL(Multiply) instruction is used to multiply signed or unsigned variables to produce a 32-bit result. The condition code are optionally updated, based on the result.

Operation

if ConditionPassed(cond) then

Rd = (Rm * Rs)[31:0]

if S == 1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag and V Flag = unaffected

Notes

Because the MUL instruction produces only the lower 32 bits of the 64 bits product, MUL gives the same answer for multiplication of both signed and unsigned numbers.

2.MLA(Multiply Accumulate)

Syntax format: MLA[cond][S] <Rd>,<Rm>,<Rs>,<Rn>

where

[cond],[S]<Rd> are similar as MUL.

<Rm> Holds the value to be multiplied with the value of <Rs>

<Rs> Holds the value to be multiplied with the value of <Rm>

<Rn> Contains the value which will be added to the result of <Rs>*<Rm>


Coding format

31

28

27

21

20

19

16

15

12

11

8

7

4

3

1

cond

0000001

(opcode)

S

Rd

Rn

Rs

1001

Rm


The MLA(Multiply Accumulate) multiplies signed or unsigned operands to produce a 32-bit result, which is then added to a third operand, and written to the destination register. The condition code flags are optionally updated, based on the result and the S bit.

Operation

if ConditionPassed(cond) then

Rd = (Rm * Rs + Rn)[31:0]

if S == 1 then

N Flag = Rd[31]

Z Flag = if Rd == 0 then 1 else 0

C Flag and V Flag = unaffected

Notes

Because the MLA instructions produces only the lower 32 bits of the 64-bit product, MLA gives the same answer for multiplication of both signed and unsigned numbers.

3.SMULL(Signed Multiplied Long)

Syntax format:SMULL[cond][S] <RdLo>,<RdHi>,<Rm>,<Rs>

Coding format:

31

28

27

21

20

19

16

15

12

11

8

7

4

3

1

cond

0000110

(opcode)

S

RdHi

RdLo

Rs

1001

Rm


The SMULL(Signed Multiply Long) instruction multiplies the signed value of the register <Rm> with the signed value of <Rs>to produce a 64-bit result. The upper 32 bits of the result are stored in <RdHi>. The lower 32 bits are stored in <RdLo>. The condition code flags are optionally updated, based on the 64-bit result.

Operation

if ConditionPassed(cond) then

RdHi = (Rm * Rs)[63:32]

RdLo = (Rm * Rs)[31:0]

if S == 1 then

N Flag = RdHi[31]

Z Flag = if (RdHi == 0) and (RdLo == 0) then 1 else 0

C Flag and V Flag = unaffected

4.SMLAL(Signed Multiply Accumulate Long)

The Syntax format and coding format are similar as SMULL.

The SMLAL(Signed Multiply Accumulate Long) instruction multiplies the signed value of register <Rm> with the signed value of register <Rs> to produce a 64-bit product. This product is added to the 64-bit value held in <RdHi> and <RdLo>,and the sum is written back to <RdHi> and <RdLo>.The condition code flags are optionally updated, based on the result and the S bit.

Operation

if ConditionPassed(cond) then

RdLo = (Rm * Rs)[31:0] + RdLo

RdHi = (Rm * Rs)[63:32] + RdHi + CarryFrom((Rm * Rs)[31:0] + RdLo)

if S == 1 then

N Flag = RdHi[31]

Z Flag = if (RdHi == 0) and (RdLo == 0) then 1 else 0

C Flag and V Flag = unaffected

5.UMULL(Unsigned Multiply Long)

The syntax format and coding format are similar as SMULL.

The UMULL(unsigned Multiply Long) instruction multiplies the unsigned value of register <Rm> with the unsigned value of register <Rs> to produce a 64-bit result. The upper 32-bit of the result is stored in <RdHi>. The lower 32-bit of the result is stored in <RdLo>...


Operation is same as SMULL.


6.UMLAL(Unsigned Multiply Accumulate Long)

The syntax format and coding format are similar as SMLAL.

The UMLAL(Unsigned Multiply Accumulate Long) instruction multiplies the unsigned value of register <Rm> with the unsigned value of register <Rs> to produce a 64-bit product. This product is added to the 64-bit value held in <RdHi> and <RdLo>, and the sum is written back to <RdHi> and <RdLo>...

Operation is same as SMLAL.


原创粉丝点击