ARM指令集2

来源:互联网 发布:linux top怎么退出 编辑:程序博客网 时间:2024/05/12 17:48

ARM工作模式:

管理模式

快速中断

中断

中止

未定义

系统

用户

异常和非异常

特权和非特权


ARM运行状态:

ARM状态:ARM指令,32bit,4字节对齐

Thumb状态:Thumb指令,16bit,2字节对齐


寄存器:

R0-R12:通用寄存器

R13SP):存放栈顶指针

R14LR):存放返回地址

R15PC):存放取指的指令的地址

CPSR:程序状态寄存器

bit[4:0]CPU的工作模式

bit[5]:CPU的运行状态

bit[6]:FIQ的禁止位

bit[7]:IRQ的禁止位

bit[31:28]:条件标志位NZCV

SPSR5个,用于备份CPSR


跳转指令:PC

B:相对跳转,PC(跳转)=PC(当前)+/-偏移量(32M

BL:相对跳转,PC(跳转)=PC(当前)+/-偏移量(32M

要返回,MOVPCLR PC=LR

BX:绝对跳转,4G,带状态切换,ARMThumb状态切换

BX R0

CPSR[5]=R0[0]

PC=R0& 0xFFFFFFFE

BLX


数据处理指令可细分为4类:

数据传送指令(MOVMVN

算术运算指令(ADDADCSUBSBCRSBRSC

位运算指令(ANDORREORBIC

比较指令(CMPCMNTSTTEQ

数据处理指令的一般格式:

<opcode>{cond}{S} <Rd>, <Rn>, <shifter_operand>


<opcode>

{cond}

{S}

1.当目标寄存器不是PC时,根据目标寄存器的结果影响CPSRNZCV条件标志位

MOVS R0#2

由于目标寄存器不是PC,根据R0的结果影响NZCV

2.当目标寄存器是PC时,CPSR=SPSR

MOVS PCLR //PC=LRCPSR=SPSR

异常的返回

<Rd>:目标寄存器,寄存器

<Rn>:第一源操作数,只能是寄存器

<shifter_operand>:第二源操作数


ADD R0, R1, #1

MOVEQ R0, R2

SUBEQS R0, R1, R2, LSR #1

CMP R1, R3


操作数:

<Rn>:第一源操作数,只能是寄存器

<shifter_operand>:第二源操作数,共有11

1.立即数:相当于常量,直接出现在指令中,不用存储在寄存器或存储器中

ADD R0R1#3 //R0=R1+3

2.寄存器:

ADD R0R1R2 //R0=R1+R2

3.寄存器移位:

1.<Rm>,LSL #<shift_imm>

ADD R0, R1, R2 LSL #1// R0=R1+(R2 << 1)

LSL逻辑左移:空出的低位用0填充

2.<Rm>,LSL <Rs>

ADD R0, R1, R2 LSL R3//R0=R1+(R2 << R3)


3.<Rm>,LSR #<shift_imm>

ADD R0, R1R2 LSR #2 //R0=R1+(R2>>2)

LSR逻辑右移:空出的高位用0填充

4.<Rm>,LSR <Rs>

ADD R0, R1R2 LSR R3 //R0=R1+(R2>>R3)


5.<Rm>,ASR #<shift_imm>

ASR算数右移:空出的高位用符号位填充

6.<Rm>,ASR <Rs>


7.<Rm>,ROR #<shift_imm>

ROR循环右移:移出的低位用于填充空出的高位


8.<Rm>,ROR <Rs>


9.<Rm>,RRX

RRX:扩展右移一位,将Rm寄存器的内容右移1位,空出的高位用原来CPSRC位来填充,并将移出的1位填充CPSRC位,只有RRX,不需要指定移位位数。


第一源操作数:寄存器

第二源操作数:11

1.立即数

2.寄存器

3.寄存器移位(LSLLSRASRRORRRX

1.LSL #shift

2.LSL Rs

空出的低位用0填充

3.LSR #shift

4.LSR Rs

空出的高位用0填充

5.ASR#shift

6.ASRRs

空出的高位用符号位填充

7.ROR#shift

8.RORRs

循环右移,将移出的低位填充空出的高位

9.RRX

扩展右移一位,将Rm寄存器的内容右移1位,空出的高位用原来CPSRC位来填充,并将移出的1位填充CPSRC位,只有RRX,不需要指定移位位数。


CMP R1#0x04800000 32bit

找到8bit立即数,然后将8bit立即数扩展为32bit,再将该32bit的数采用循环右移的方式进行移位,移2X#rot)次,最终得到0x4800000


0x12扩展为32bit数,高位全用0填充,然后将其循环右移2X5=10次,即得到立即数0x4800000

5 0x12

6 0x48

如果找到的组合不唯一,取循环右移次数少的那组


8位图立即数


合法立即数的判定?

1.0-0xFF就是合法立即数

2.立即数中1的个数大于8的一定不合法

3.从两个方向看1的间距大于8,非法


数据传送指令MOV

指令格式:

MOV{cond}{S} <Rd>, <shifter_operand>

shifter_operand:立即数(8位图)、寄存器、寄存器移位

功能:Rd=<shifter_operand>

示例:

MOVEQ R0, #0x80 //EQ , R0=0x80

MOVS PC, LR

//S,目标寄存器PC

//PC=LR,CPSR=SPSR异常返回


MOVEQS R0R1

//EQ,R0=R1,R0的结果影响CPSRNZCV

N= R0[31]

Z= if R0== 0 then 1 else 0

C= shifter_carry_out,

不影响V

MOV R3, R4, LSL #2 //R3=(R4<<2)

MOV R0, R0

MOV PC, R14 //PC=R14


NZCV

N:运算结果为负值的标志位

N=1,负值

N=0,正值

Z:运算结果为0的标志位

Z=1,结果0

Z=0,结果为非0


数据取反传送指令:MVN

指令格式:

MVN{cond}{S} <Rd>, <shifter_operand>

shifter_operand:立即数(8位图)、寄存器、寄存器移位

功能:Rd=<shifter_operand>按位取反

示例

MVNEQ R0, #0x80

//EQ,0x80按位取反,R0=0xFFFFFF7F

MVNS PC, R0

//PC=R0按位取反,SPCCPSR=SPSR

MVNEQS R0R1

//EQ,R0=R1按位取反,SR0的结果影响NZCV

N= R0[31]

Z= if R0 == 0 then 1 else 0

C= shifter_carry_out,

不影响V

MVN R3, R4, LSL #2

//R3=(R4<<2)按位取反


MOV R0,#0x00 //R0=0x0

MVN R0,#0x00 //R0=0xFFFFFFFF

MOV R0,#0xffffff00 //不合法

MVN R0, #0x000000FF //R0=(0x000000FF)按位取反


MOV

MVN

没有第一源操作数

S

PCCPSR=SPSR

不是PC,根据结果影响NZCV


算术运算指令

加法指令ADD

指令格式:

ADD{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn+<shifter_operand>

示例

ADD R0, R1, #0x80 //R0=R1+0x80

ADDEQ R0, R1, R3 //EQ, R0=R1+R3

ADDS R0, R1, R2

//R0=R1+R2,S,R0,根据R0影响NZCV

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C= CarryFrom(Rn + shifter_operand)

V= OverflowFrom(Rn + shifter_operand)

ADDS PC, R1, #0 //PC=R1,CPSR=SPSR


ADD R0, R1, R2 R0 = R1 + R2

ADD R0, R1, #256 R0 = R1 + 256

ADD R0, R2, R3, LSL #1 R0 = R2 + (R3 << 1)


NZCV

N:运算结果为负值的标志位

N=1,负值

N=0,正值

Z:运算结果为0的标志位

Z=1,结果0

Z=0,结果为非0

C:运算结果产生进位的标志位

无符号

C=1,有进位

C=0,无进位

V:运算结果产生溢出的标志位

有符号

V=1,有溢出

V=0,无溢出


8bit

有符号:-128~127溢出

无符号:0~255进位


3AH+ 7CH =

无符号:58+ 124 = 182 无进位

有符号:58+ 124 = 182 有溢出


AAH+ 7CH =

无符号:170+ 124 = 294 有进位

有符号:-86+ 124 = 38 无溢出


带进位的加法指令:ADC

指令格式:

ADC{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd= Rn +<shifter_operand>+C

示例

ADC R0, R1, #0x80 //R0=R1+0x80+C

ADCEQ R0, R1, R3 //EQ,R0=R1+R3+C

ADCS R0, R1, R2 //R0=R1+R2,S,R0

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C= CarryFrom(Rn + shifter_operand + C Flag)

V= OverflowFrom(Rn + shifter_operand + C Flag)

ADCS PC, R1, #0


加数(R1R0),

被加数(R3R2),

结果(R1R0),

前者为高32位,后者为低32


R1R0

+R3 R2

R1R0


ADDS R0, R0, R2 //R0=R0+R2结果影响NZCV

ADC R1R1R3 //R1=R1+R3+C


减法指令:SUB

指令格式:

SUB{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn-<shifter_operand>

示例

SUB R0, R1, #0x80 //R0=R1-0x80

SUBNE R0, R1, R3 //NER0=R1-R3

SUBS R0, R1, R2 //R0=R1-R2,R0影响NZCV

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C= NOT BorrowFrom(Rn - shifter_operand)

有借位,C=0

无借位,C=1

V= OverflowFrom(Rn - shifter_operand)

SUBS PC, R14, #04 //PC=R14-4,S,PC,CPSR=SPSR


SUB R0, R1, R2

SUB R0, R1, #256

SUB R0, R2, R3, LSL #1

SUBS R1, R2, R3

SUBS PC, R14, #4


带借位的减法指令:SBC

指令格式:

SBC{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn-<shifter_operand>-Not C

示例

SBC R0, R1, #0x80 //R0=R1-0x80-Not C

SBCNE R0, R1, R3 //NE,R0=R1-R3-Not C

SBCS R0, R1, R2 //R0=R1-R2-Not C

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C=NOTBorrowFrom(Rn - shifter_operand – NOT(C Flag))

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

SBCS PC, R1, #0


被减数(R1R0

减数(R3R2

结果(R1R0

前者为高32位,后者为低32

R1R0

  • R3R2

R1R0

SUBS R0, R0, R2 //R0=R0-R2,影响NZCV

SBC R1R1R3//R1=R1-R3-Not C


反向减法指令:RSB

指令格式:

RSB{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd= <shifter_operand>- Rn

示例

RSB R0, R1, #0x80

RSBNE R0, R1, R3

RSBS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C= NOT BorrowFrom(shifter_operand – Rn)

V= OverflowFrom(shifter_operand – Rn)

RSBS PC, R1, #0


RSB R3, R1, #0 //R3=-R1

RSBS R1, R2, R2, LSL #2 //R1=(R2<<2)-R2=R2×3

影响标志位


带借位的反向减法指令:RSC

指令格式:

RSC{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd=<shifter_operand>-Rn-NotC

示例

RSC R0, R1, #0x80

RSCNE R0, R1, R3

RSCS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

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

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

RSCS PC, R1, #0


算术运算

ADD加法C=1进位,C=0,无进位

ADC带进位的加法

SUB减法C=0借位,C=1,无借位

SBC带借位减

RSB反向减

RSC带借位的反向减


位运算

AND

指令格式:

AND{<cond>}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd= Rn & <shifter_operand>按位与

示例

AND R0, R1, #0x80

ANDNE R0, R1, R3

ANDS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C=shifter_carry_out

ANDS PC, R1, #0xFFFFFFFF


AND R0R1R2

AND R0R1#0x80

ANDS R0, R1R2LSL#1

ANDEQ R3R4#0xFF


按位与操作实现什么功能:

&1用于判断某位是1还是0

&0用于清除某位


或操作ORR

指令格式:

ORR{<cond>}{S}<Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn|<shifter_operand>

示例

ORR R0, R1, #0x80

ORRNE R0, R1, R3

ORRS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C=shifter_carry_out

ORRS PC, R1, #0x0


ORR R0, R1, #1

ORR R0, R1, R2

ORR R0, R1, R2, LSL #2


用或操作实现什么功能?

|1,将某位置1

|0,保持不变


异或EOR

指令格式:

EOR{<cond>}{S}<Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn^<shifter_operand>

示例

EOR R0, R1, #0x80

EOREQ R0, R1, R3

EORS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C=shifter_carry_out

EORS PC, R1, #0x0


用异或操作实现什么功能?

相同,为0

不同,为1

1.判断两个数是否相等?

R1^ R2 == 0, R1==R2

2.把一个变量的某位与1做异或可以实现取反

0 1 1

1 1 0

3.加密

0x80^ 0xFF =1000 0000 ^ 1111 1111 =01111111 = 0x7F

0x7F^ 0xFF =0111 1111^ 1111 1111 =10000000 =0x80


EOR R0, R0, #FF

EOR R0, R0, R1

EORS R0, R0, #1


位清除BIC

指令格式:

BIC{cond}{S} <Rd>, <Rn>, <shifter_operand>

功能:Rd=Rn&(~<shifter_operand>)

示例

BIC R0, R1, #0x80

BICEQ R0, R1, R3

BICS R0, R1, R2

N= Rd[31]

Z= if Rd == 0 then 1 else 0

C=shifter_carry_out

BICS PC, R1, #0x0


BIC R0, R0, #0xFF

BIC R1R2R3


AND

ORR

EOR

BIC


比较测试指令

比较指令CMP

指令格式

CMP{cond} <Rn>, <shifter_operand>

功能:Rn-<shifter_operand>

1.没有目标寄存器

2.不用加SRn-<shifter_operand>影响NZCV


示例

CMP R0, #0x80

CMPEQ R0, R3

N=ALU_out[31]

Z= if ALU_out == 0 then 1 else 0

C=NOTBorrowFrom(Rn - shifter_operand)

V=OverflowFrom(Rn- shifter_operand)


cmp r1, #10 r1-10

moveq r0, r1 Z=1

bleq test Z=1

……

test:

……



负值比较指令:CMN

指令格式

CMN{cond} <Rn>, <shifter_operand>

功能:Rn+<shifter_operand>

示例

CMN R0, #0x80

CMNEQ R0, R3

N=ALU_out[31]

Z= if ALU_out == 0 then 1 else 0

C= CarryFrom(Rn + shifter_operand)

V= OverflowFrom(Rn + shifter_operand)


CMN R1,#5R1+5==0 Z=1 EQ

BEQ SKIP

......

SKIP:

……


位测试指令:TST

指令格式:

TST{cond} Rn, shifter_operand

功能:Rn& shifter_operand

示例

TST R0, #0x80

TSTEQ R0, R3

N=ALU_out[31]

Z= if ALU_out == 0 then 1 else 0

C= shifter_carry_out


TST R0, #0x1

ADDEQ R1R2R3

TST R1R4


相等测试指令TEQ

指令格式

TEQ{cond} <Rn>, <shifter_operand>

功能Rn^ <shifter_operand>

示例

TEQ R0, #0x80

TEQNE R0, R3

N=ALU_out[31]

Z= if ALU_out == 0 then 1 else 0

C= shifter_carry_out


TEQ R0,R1 R0==R1 Z=1 EQ

R0!=R1Z=0 NE

MOVNE R0,R1


数据处理指令:

1.数据传送(MOVMVN

2.算术运算(ADDADC SUB SBC RSB RSC

进位:C=1有进位,C=0无进位

借位:C=1无借位,C=0有借位

3.位运算(ANDORR EOR BIC

4.比较测试(CMP- CMN+ TST& TEQ^


一般格式:

操作码{条件码}S目标寄存器,第一源操作数,第二源操作数

<opcode>{cond}{S} <Rd>, <Rn>, <shifter_operand>

1.第一源操作只能是寄存器

2.第二源操作数:

8位图立即数(#rot,8bit立即数,ROR

寄存器

寄存器移位(LSLLSRASRRORRRX

3.S

1.目标寄存器为PCCPSR=SPSR,异常返回

2.目标寄存器不是PC,根据运算结果影响NZCV

4.数据传送指令没有第一源操作数

5.比较测试指令没有目标寄存器,不加S,结果影响NZCV


用汇编指令实现1-10累加和计算

mov

add

sub

cmp

b



求最大公约数

20 12

R0=20

R1=12

while(R0=R1)

if(R0>= R1) cmp

{

R0= R0 - R1条件执行cs

}

else

{

R1= R1 – R0条件执行cc

}


mov

cmp

sub

b















0 0