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),先出栈,后加地址,由于满减栈原则,栈顶指针指向的是有效元素,所以要先出,否则,栈顶元素就被遗漏。
<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),先出栈,后加地址,由于满减栈原则,栈顶指针指向的是有效元素,所以要先出,否则,栈顶元素就被遗漏。
相关文章推荐
- ARM学习笔记4——加载存储指令
- 12_ARM汇编自学笔记指令系统之加载存储指令
- 13_ARM汇编自学笔记指令系统之批量数据加载存储指令
- ARM学习笔记3——数据处理指令
- ARM体系结构笔记①---(ARM的7种模式、寄存器、存储空间、指令、中断、最小系统)
- ARM学习笔记 (二)存储系统
- arm学习笔记四(arm伪指令)
- ARM汇编指令学习笔记(一)【为明天BOOTLOADER学习准备】
- arm 汇编学习常用指令伪指令笔记汇总
- 学习笔记TF049:TensorFlow 模型存储加载、队列线程、加载数据、自定义操作
- ARM学习笔记(九)--指令基本格式
- ARM汇编伪指令学习笔记
- ARM指令---学习笔记
- ARM框架学习笔记 part1 寄存器、存储空间
- 嵌入式学习笔记--关于ARM中SWP指令的执行顺序问题【待验证】
- [国嵌笔记][025][ARM指令分类学习]
- ARM底层学习笔记-存储管理器及sdram的使用
- 【ARM学习笔记】三、S3C2440A的存储控制器及启动过程
- ARM学习笔记7——乘法指令
- ARM汇编基础-存储和加载指令