全部博文(36)
分类: 嵌入式
2012-08-14 17:52:07
对于做嵌入式开发的人来说,arm汇编是非常重要的一课,因为它对于理解底层非常的重要。所以俺抽点时间把汇编语言学习一下。
1. 寄存器装载和存储
LDM和 STM
批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器,STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。主要用于现场保护、数据复制、参数传送等。有八种模式。IA,IB,DA,DB,FD,ED,FA,EA.
例子:
LDMIA R0!,{R3-R9;加载R0指向的地址上的多字数据,保存到R3-R9中,R0值更新
STMIA R1!,{R3-R9};将R3-R9的数据存储到R1指向的地址上,R1值更新
STMFD SP!,{R0-R7,LR};现场保存,将R0-R7,LR入栈
LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回
LDR 和STR
加载/存储字和无符号字节指令,使用单一数据传送指令来装载和存储单一字节或字的数据从/到内存,LDR指令用于从内存中读取数据放入寄存器中;STR指令用于将寄存器中的数据保存到内存。
例子:
LDR R1,[R0,#0x12] ;将R0+0x12地址处的数据读出,保存到R1中(R0的值不变)
LDR R1,[R0,#-0x12];将R0-0x12地址处的数据读出,保存到R1中(R0的值不变)
LDR R1,[R0] ;将R0地址处的数据读出,保存到R1中(零偏移)
LDR R1,[R0,R2] ;将R0+R2地址的数据计读出,保存到R1中(R0的值不变)
LDR R1,[R0,-R2] ;将R0-R2地址处的数据计读出,保存到R1中(R0的值不变)
SWP
寄存器和存储器交换指令.SWP 指令用于将一个内存单元(该单元地址放在寄存器
Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单
元中.使用SWP可实现信号量操作
例子:
SWP R1,R1,[R0] ;将R1的内容与R0指向的存储单元的内容进行交换
SWP R1,R2,,[R0] ;将R0指向的存储单元内容读取一字节数据到R1中(高
24位清零),并将R2的内容写入到该内存单元中(最低字节有效)
2算数与逻辑指令
ADD
加法运算指令.将operand2数据与Rn的值相加,结果保存到Rd寄存器.
ADD{cond}{S} Rd,Rn,operand2
下:
ADDS R1,R1,#1 ;R1=R1+1
ADD R1,R1,R2 ;R1=R1+R2
ADDS R3,R1,R2,LSL #2 ;R3=R1+R2<<2
SUB
减法运算指令.用寄存器Rn减去operand2.结果保存到Rd中SUB{cond}{S} Rd,Rn,operand2
SUBS R0,R0,#1 ;R0=R0-1
SUBS R2,R1,R2 ;R2=R1-R2
RSB
逆向减法指令.用寄存器operand2减法Rn,结果保存到Rd中RSB{cond}{S} Rd,Rn,operand2
RSB R3,R1,#0xFF00 ;R3=0xFF00-R1
RSBS R1,R2,R2,LSL #2 ;R1=R2<<2-R2=R2×3
ADC
带进位加法指令.将operand2的数据与Rn的值相加,再加上CPSR中的C条件标志
位.结果保存到Rd寄存器 ADC{cond}{S} Rd,Rn,operand2
ADDS R0,R0,R2
ADC R1,R1,R3 ;使用ADC实现64位加法,(R1、R0)=(R1、R0)+(R3、R2)
SBC
带进位减法指令。用寄存器Rn减去operand2,再减去CPSR中的C条件标志位的
非(即若C标志清零,则结果减去1),结果保存到Rd中SCB{cond}{S}Rd,Rn,operand2
SUBS R0,R0,R2
SBC R1,R1,R3 ;使用SBC实现64位减法,(R1,R0)-(R3,R2)
RSC
带进位逆向减法指令.用寄存器operand2减去Rn,再减去CPSR中的C条件标志位,
结果保存到Rd中 RSC{cond}{S} Rd,Rn,operand2
RSBS R2,R0,#0
RSC R3,R1,#0 ;使用RSC指令实现求64位数值的负数
AND
逻辑与操作指令.将operand2值与寄存器Rn的值按位作逻辑与操作,结果保存到
Rd中.指令格式如下:
AND{cond}{S} Rd,Rn,operand2
AND指令举例如下:
ANDS R0,R0,#x01 ;R0=R0&0x01,取出最低位数据
AND R2,R1,R3 ;R2=R1&R3
ORR
逻辑或操作指令.将operand2的值与寄存器Rn的值按位作逻辑或操作,结果保存到
Rd中.指令格式如下:
ORR{cond}{S} Rd,Rn,operand2
ORR指令举例如下:
ORR R0,R0,#x0F ;将R0的低4位置1
MOV R1,R2,LSR #4
ORR R3,R1,R3,LSL #8;使用ORR指令将近R2的高8位数据移入到R3低8位
中
BIC
位清除指令.将寄存器Rn的值与operand2的值的反码按位作逻辑与操作,结果保存
到Rd中.指令格式如下:
BIC{cond}{S}Rd,Rn,operand2
BIC指令举例如下:
BIC R1,R1,#0x0F ;将R1的低4位清零,其它位不变
BIC R1,R2,R3 ;将拭的反码和R2相逻辑与,结果保存到R1
EOR
逻辑异或操作指令.将operand2的值与寄存器Rn的值按位作逻辑异或操作,结果保
存到Rd中.指令格式如下:
EOR{cond}{S}Rd,Rn,operand2
EOR指令举例如下:
EOR R1,R1,#0x0F ;将R1的低4位取反
EOR R2,R1,R0 ;R2=R1^R0
EORS R0,R5,#0x01 ;将R5和0x01进行逻辑异或,结果保存到R0,并影响标志位
MOV
数据传送指令.将8位图立即数或寄存器(operant2)传送到目标寄存器Rd,可用于
移位运算等操作.指令格式如下:
MOV{cond}{S} Rd,operand2
MOV指令举例如下:
MOV R1#0x10 ;R1=0x10
MOV R0,R1 ;R0=R1
MOVS R3,R1,LSL #2 ;R3=R1<<2,并影响标志位
MOV PC,LR ;PC=LR ,子程序返回
MVN
数据非传送指令.将8位图立即数或寄存器(operand2)按位取反后传送到目标寄存
器(Rd),因为其具有取反功能,所以可以装载范围更广的立即数.指令格式如下:
MVN{cond}{S} Rd,operand2
MVN指令举例如下:
MVN R1,#0xFF ;R1=0xFFFFFF00
MVN R1,R2 ;将R2取反,结果存到R1
3移位
LSL 逻辑左移
ASL 算数左移
LSR 逻辑右移
ASR 算数右移
ROR 循环右移
RRX 带扩展的循环右移
4乘法指令
MLA
32位乘加指令.指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的低
32位保存到Rd中.指令格式如下:
MLA{cond}{S} Rd,Rm,Rs,Rn
MLA指令举例如下:
MLA R1,R2,R3,R0 ;R1=R2×R3+10
MUL
32位乘法指令.指令将Rm和Rs中的值相乘,结果的低32位保存到Rd中.指令格式
如下:
MUL{cond}{S} Rd,Rm,Rs
MUL指令举例如下:
MUL R1,R2,R3 ;R1=R2×R3
MULS R0,R3,R7 ;R0=R3×R7,同时设置CPSR中的N位和Z位
5程序状态寄存器访问指令
MRS
程序状态寄存器到通用寄存器的数据传送指令
MSR
通用寄存器到程序状态寄存器的数据传送指令
6异常产生指令
SWI
软中断指令.SWI指令用于产生软中断,从而实现在用户模式变换到管理模式,CPSR
保存到管理模式的SPSR中,执行转移到SWI向量,在其它模式下也可使用SWI指令,处理
同样地切换到管理模式.指令格式如下;
SWI{cond} immed_24
其中 immed_24 24位立即数,值为0~16777215之间的整数
SWI指令举例如下:
SWI 0 ;软中断,中断立即数为0
SWI 0x123456 ;软中断,中断立即数为0x123456
BKPT
BKPT指令格式为:
BKPT 16位的立即数
BKPT 指令产生软件断点中断,可用于程序的调试
7协处理器指令
CDP
协处理器数据操作指令.ARM处理器通过CDP指令通知ARM协处理器执行特定的操
作.该操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取决于
协处理器.若协处理器不能成功地执行该操作,将产生未定义指令异常中断.指令格式如
下:
CDP{cond} coproc,opcodel,CRd,CRn,CRm{,opcode2}
其中: coproc 指令操作的协处理器名.标准名为pn,n为0~15.
opcodel协处理器的特定操作码
CRd 作为目标寄存器的协处理器寄存器.
CRN 存放第1个操作数的协处理器寄存器.
CRm 存放第2个操作数的协处理器寄存器.
Opcode2 可选的协处理器特定操作码.
CDP 指令举例如下:
CDP p7,0,c0,c2,c3,0 ;协处理器7操作,操作码为0,可选操作码为0
CDP p6,1,c3,c4,c5 ;协处理器操作,操作码为1
LDC
协处理器数据读取指令.LDC指令从某一连续的内存单元将数据读取到协处理器的
寄存器中.协处理器数据的数据的传送,由协处理器来控传送的字数.若协处理器不能成
功地执行该操作,将产生未定义指令异常中断.指令格式如下;
LDC{cond}{L} coproc,CRd,<地址>
其中: L 可选后缀,指明是长整数传送.
coproc 指令操作的协处理器名.标准名为pn,n 为0~15
CRd 作为目标寄存的协处理器寄存器.
<地址> 指定的内存地址
LDC指令举例如下:
LDC p5,c2,[R2,#4];读取R2+4指向的内存单元的数据,传送到协处理器p5的c2寄存器中
LDC p6,c2,[R1] ;读取是指向的内存单元的数据,传送到协处理器p6的c2寄存器中
STC
协处理器数据写入指令.STC指令将协处理器的寄存器数据写入到某一连续的内存
单元中.进行协处理器数据的数据传送,由协处理器来控制传送的字数.若协处理器不能
成功地执行该操作,将产生未定义指令异常中断.指令格式如下;
STC{cond}{L} coproc,CRd,<地址>
其中:
L 可选后缀,指明是长整数传送.
coproc 指令操作的协处理器名.标准名为pn,n为0~15
CRd 作为目标寄存的协处理器寄存器
<地址> 指定的内存地址
STC指令举例如下:
STC p5,c1,[R0]
STC p5,c1,[Ro,#-0x04]
MCR
ARM寄存器到协处理器寄存器的数据传送指令.MCR指令将ARM处理器的寄存器中的
数据传送到协处理器的寄存器中.若协处理器不能成功地执行该操作,将产生未定义指
令异常中断.指令格式如下;
MCR{cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}
其中 coproc 指令操作的协处理器名.标准名为pn,n为0~15.
cpcodel 协处理器的特定操作码.
CRD 作为目标寄存器的协处理器寄存器.
CRn 存放第1个操作数的协处理器寄存器
CRm 存放第2个操作数的协处理器寄存器.
Opcode2 可选的协处理器特定操作码.
MCR指令举例如下:
MCR p6,2,R7,c1,c2,
MCR P7,0,R1,c3,c2,1,
MRC
协处理器寄存器到ARM寄存器到的数据传送指令.MRC指令将协处理器寄存器中的
数据传送到ARM处理器的寄存器中.若协处理器不能成功地执行该操作.将产生未定义
异常中断.指令格式如下.
MRC {cond} coproc,opcodel,Rd,CRn,CRm{,opcode2}
其中coproc 指令操作的协处理器名.标准名为pn,n,为0~15
opcodel 协处理器的特定操作码.
CRd 作为目标寄存器的协处理器寄存器.
CRn 存放第1个操作数的协处理器寄存器.
CRm 存放第2个操作数的协处理器寄存器.
opcode2 可选的协处理器特定操作码.
MRC指令举例如下
MRC p5,2,R2,c3,c2
MRC p7,0,R0,c1,c2,1
8跳转指令
B 跳转指令
BL 是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,
BLX 从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态由arm态切换到Thumb态,同时将PC的当前内容保存到寄存器R14中。
BX 跳转到指令中所指定的目标地址,目标地址处的指令既可以是arm指令,也可以是THUMB