您的位置:首页 > 其它

ARM学习笔记(二)——ARM数据处理指令、加载\存储指令

2014-07-18 19:25 253 查看
数据处理指令的一般格式:

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

<opcode>:数据处理指令的助记符   ADD MOV  SUB  CMP

{cond}:条件标识,EQ,NE所有的数据处理指令都可以条件执行

{S}:本指令的结构会影响CPSR状态寄存器的条件标志位 NZCV

<Rd>:目标寄存器

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

<shifter_operand>:第二源操作数

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

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

ASR:算数右移,空出的空位由符号位填充

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

RRX:扩展右移一位,将寄存器的内容右移1位,空位由原来的cpsr寄存器的C位填充,将移出的位填充到C位,只有RRX,不需要指定移动位数

 

数据传送指令(MOV、MVN)无第一源操作数

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

功能:Rd=<shifter_operand>的内容

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

当目标寄存器为PC时,如果加S
,不是影响NZCV,CPSR = SPSR,异常返回。

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

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

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

 

算术运算指令(ADD、ADC、SUB、SBC、RSB、RSC)

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

ADD 正常加    Rd= Rn +<shifter_operand>

ADC 带进位加  Rd= Rn +<shifter_operand>+C

SUB  正常减  Rd= Rn -<shifter_operand>

SBC 带借位减  Rd= Rn -<shifter_operand>-Not C

C=0 有借位,C=1 无借位  -Not C

RSB 反向减    Rd= <shifter_operand>-Rn

RSC 带借位的反向减   Rd= <shifter_operand>-Rn-Not C

S:

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

目标寄存器是PC,CPSR=SPSR

 

位运算指令(AND、ORR、EOR、BIC)

AND{cond}{S}  Rd, Rn,  op2

功能:Rd=Rn & op2

&1,用来判断某位是1还是0

&0,用来清除某位

 

ORR{cond}{S}Rd, Rn, op2

功能:Rd=Rn | op2

将某些位置1

 

EOR{cond}{S}  Rd,  Rn,  op2

功能:Rd=Rn ^ op2

1.                 判断2个数是否相等 R1^R2

2.                 把一个变量的某位取反

 

位清除指令

BIC{cond}{S}  Rd, Rn,  op2

功能:Rd=Rn &(~op2)

 

比较指令(CMP、CMN、TST、TEQ)

1.                 没有目标寄存器,不用保存结果

2.                 不用加S,根据计算结果,影响NZCV

比较指令

CMP{cond}  Rn, operand2

 影响N、Z、C、V←Rn-operand2

功能:Rn- operand2

 

负数比较指令

CMN{cond}  Rn, operand2

影响N、Z、C、V←Rn+operand2

 

TST{cond}  Rn, operand2

影响N、Z、C、V←Rn &operand2

 

相等测试指令

TEQ{cond}  Rn, operand2

影响N、Z、C、V←Rn ^ operand2

 

数据处理指令总结

1.                 MOV指令没有第一源操作数

2.                 比较指令没有目标寄存器,但是会根据运算结果影响NZCV

3.                 所有数据处理指令都有第二源操作数

4.                 第一源操作数一定是寄存器

5.                 数据处理指令,如果加S,分两种情况:

1.                 如果目标寄存器不是PC,根据结果影响NZCV

2.                 如果目标寄存器是PC,CPSR=SPSR

6.                 第二源操作数:

1.8位图立即数,(A,B)B数经过ROR 2*A得到指令中写的立即数

2.寄存器

3.寄存器移位:

加载/存储指令

数据处理指令只处理寄存器和立即数

访问存储器缓冲区中的数据,如变量。

访问处理器外设。

加载函数地址到PC寄存器,则实现程序跳转功能,可实现跳转表等

单寄存器字和无符号字节加载/存储指令

LDR{cond}   Rd, <地址模式>

功能:将指定地址单元的字数据读入Rd中。

LDR{cond}B  Rd, <地址模式>

功能:将指定地址单元中的一个字节数据读到Rd中。

      存放到Rd寄存器的低8位,高24位用0填充。

<地址模式>:数据源

Rd:目标寄存器

 

STR{cond}    Rd, <地址模式> 

功能:将Rd中的字数据保存到指定地址单元中。

STR{cond}B   Rd, <地址模式> 

功能:将Rd中的一个字节数据保存到指定地址单元中。

Rd: 源寄存器

<地址模式>:目标地址

 

单寄存器半字(有符号和无符号)和有符号字节

不要给PC加载半字和字节

  LDR{cond}SB Rd,<地址模式>  有符号的字节

功能:Rd<-<地址模式>, Rd低8位,高24位用符号位填充

 

  LDR{cond}SH Rd,<地址模式>  有符号的半字

功能:Rd<-<地址模式>,Rd低16位,高16位用符号位填充

 

  LDR{cond}H  Rd,<地址模式>  无符号半字

功能:Rd<-<地址模式>,Rd低16位,高16位用0填充

  STR{cond}H Rd,<地址模式>  无符号半字

功能:Rd-><地址模式> ,存储的是Rd低16位

半字读写时,指定地址必须是2字节对齐,否则结果不可预知

 

<地址模式>

1 .零偏移

LDR  R0,[R1]   //R0<-[R1] 将R1表示地址的字数据加载R0

2. [<Rn>,#+/-<offset_12>]

    LDR  R0,[R1,#0x8]              ;R0<-[R1+0x8]

LDR  R0, [R1,#-0x20]         ; R0<- [R1 – 0x20]

 

3. [<Rn>,+/-<Rm>]

    LDR  R0,[R1, R2]                 ;R0<-[R1+R2]

LDR R0,[R1,-R2]                ;R0<-[R1-R2]

 

4. [<Rn>,+/-<Rm>, <shift> #<shift_imm>]

LDR  R0,[R1,R2,LSL #2]     ;R0<-[R1+R2*4]

不改变基址R1

 

5. [<Rn>, #+/-<offset_12>]!

LDR  R0,[R1,#0x8]!            ;R0<-[R1+0x8]  R1=R1+8

 

6. [<Rn>, +/-<Rm>]!

LDR  R0,[R1,R2]!              ;R0<-[R1+R2]   R1=R1+R2

 

7. [<Rn>, +/-<Rm>, <shift>#<shift_imm>]!

LDR R0,[R1,R2,LSL #2]
4000
! ;R0<-[R1+R2*4]   R1=R1+R2*4

将(基址+偏移量)地址的值加载到Rd之后,基址发生改变,基址+偏移量

 

8. [<Rn>], #+/-<offset_12>

LDR  R0, [R1],#0x20        ;R0=<-[R1]  R1=R1+0x20

 

9. [<Rn>], +/-<Rm>

LDR  R0, [R1],R2              ;R0=<-[R1]  R1=R1+R2

 

10. [<Rn>], +/-<Rm>, <shift> #<shift_imm>

    LDR  R0, [R1], R2, LSL  #2  ;R0=<-[R1]  R1=R1+R2*4

    现将基址的内容加载到Rd中,然后在改变基址,基址+偏移量

 

多寄存器存储加载指令

 

多寄存器加载指令  LDM

LDM{cond}{addressing_mode}  Rb{!}, < Reglist >{^}

Rb:源基址

Reglist:目标寄存器列表

 

多寄存器存储指令  STM

STM{cond}{addressing_mode}  Rb{!}, < Reglist>{^}

Rb:目标基址

Reglist:源寄存器列表

cond  : 条件域

addressing_mode

LDMIA / STMIA            Increment After(先操作,后增加)

LDMIB / STMIB            Increment Before(先增加,后操作)

LDMDA / STMDA          Decrement After (先操作,后递减)

LDMDB / STMDB          Decrement Before (先递减,后操作)

Rb  : 基址寄存器

!  :    更新基址寄存器

Reglist:  源/目标寄存器列表(可以是16个寄存器的任何子集)

^   :   有两种作用,特权模式下使用用户模式下的寄存器,   

                                            CPSR=SPSR

特权模式下使用:

1.                 当寄存器列表当不含PC时,则特权模式下使用用户模式下的寄存器

2.                 当寄存器列表中包含PC时,CPSR=SPSR

 异常模式下,SPSR

 非常异常模式:用户和系统

ARM栈

Descendingstacks (减栈)

栈向内存地址减小的方向变化

Ascendingstacks   (加栈)

栈向内存地址增加的方向变化

Fullstacks (满栈) 栈顶指针指向有效的元素

栈指针指向的栈顶保存有效元素

Emptystacks (空栈) 栈顶指针指向空

栈指针指向的栈顶未保存有效元素

综合以上两种特点,有以下4种栈

FD(Full       Descending)满减栈

ED(Empty  Descending)   空减栈

FA(Full    Ascending)     满加栈

EA(Empty  Ascending)    空加栈

 

STMDB   先减小地址,再存储数据   STMFD     Push

LDMIA    先加载数据,后增加地址   LDMFD     Pop

STMDB  入栈:

   根据满减栈的规则入栈(STMDB \STMFD\Push),先减地址,后入栈,高地址存大号寄存器的原则,依次入栈,栈顶指向有效元素,因此,若需要入栈,则要先改变地址指向一个空位置,然后入栈,否则将会将原栈顶的有效元素覆盖。

LDMIA   出栈:

   根据满减栈的规则出栈(LDMIA\LDMFD\Pop),先出栈,后加地址,由于满减栈原则,栈顶指针指向的是有效元素,所以要先出,否则,栈顶元素就被遗漏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: