常用ARM及汇编指令Word文件下载.docx
- 文档编号:22483679
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:24
- 大小:29.72KB
常用ARM及汇编指令Word文件下载.docx
《常用ARM及汇编指令Word文件下载.docx》由会员分享,可在线阅读,更多相关《常用ARM及汇编指令Word文件下载.docx(24页珍藏版)》请在冰豆网上搜索。
将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。
LDRR2,[R3,#0x0F]
将R3的数值加0x0F作为地址,取出此地址的数值保存在R2中
STRR1,[R0,#-2]
将R0中的数值减2作为地址,把R1中的内容保存到此地址位置
6、多寄存器寻址:
一次可以传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器
LDMIAR1!
{R2-R7,R12}
将R1所指向的地址的数据读出到R2-R7,R12,R1自动更新
STMIAR0!
{R3-R6,R10}
将R3-R6,R10中的数值保存到R0指向的地址,R0自动更新
7、堆栈寻址:
堆栈是特定顺序进行存取的存储区,堆栈寻址时隐含的使用一个专门的寄存器(堆栈指针),指向一块存储区域(堆栈),存储器堆栈可分为两种:
向上生长:
向高地址方向生长,称为递增堆栈
向下生长:
向低地址方向生长,称为递减堆栈
如此可结合出四中情况:
1、满递增:
堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址,指令如LDMFA,STMFA
2、空递增:
堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置,指令如LDMEA,STMEA
3、满递减:
堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址,指令如LDMFD,STMFD
4、空递减:
堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置,指令如LDMED,STMED
STMFDSP!
{R1-R7,LR}
将R1-R7,LR入栈,满递减堆栈
LDMFDSP!
数据出栈,放入R1-R7,LR寄存器,满递减堆栈
8、块拷贝寻址:
多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置
{R1-R7}
将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后增加,方向为向上增长
STMIBR0!
将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向上增长
SIMDAR0!
将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后增加,方向为向下增长
STMDBR0!
将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向下增长
不论是向上还是向下递增,存储时高编号的寄存器放在高地址的内存,出来时,高地址的内容给编号高的寄存器
9、相对寻址:
是基址寻址的一种变通,由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址
BLROUTE1
调用到ROUTE1子程序
BEQLOOP
条件跳转到LOOP标号处
================================================================================================================
指令集介绍
指令格式:
<
opcode>
{<
cond>
}{S}<
Rd>
<
Rn>
{<
operand2>
}
其中<
>
内的项是必须的,{}内的项是可选的
opcode
指令助记符,如LDR,STR等
cond
执行条件,如EQ,NE等
S
是否影响CPSR寄存器的值,书写时影响CPSR,否则不影响
Rd
目标寄存器
Rn
第一个操作数的寄存器
operand2第二个操作数
指令格式举例如下:
LDRR0,[R1]
读取R1地址上的存储器单元内容,执行条件AL(无条件执行)
BEQDATAEVEN
跳转指令,执行条件EQ,即相等跳转到DATAEVEN
ADDSR1,R1,#1
加法指令,R1+1=>
R1影响CPSR寄存器,带有S
SUBNESR1,R1,#0xD;
条件执行减法运算(NE),R1-0xD=>
R1,影响CPSR寄存器,带有S
条件码表
条件码助记符
标志
含义
EQ
Z=1
相等
NE
Z=0
不相等
CS/HS
C=1
无符号数大于或等于
CC/LO
C=0
无符号数小于
MI
N=1
负数
PL
N=0
正数
VS
V=1
溢出
VC
V=0
没有溢出
HI
C=1,Z=0
无符号数大于
LS
C=0,Z=1
无符号数小于或等于
GE
N=V
带符号数大于或等于
LT
N!
=V
带符号数小于
GT
Z=0,N=V
带符号数大于
LE
Z=1,N!
带符号数小于或等于
AL
任何无条件执行(指令默认条件)
条件码应用举例:
1、比较两个值大小,C代码如下:
if(a>
b)a++;
elseb++;
写出相应的ARM指令
代码如下:
设R0为a,R1为b
CMPR0,R1
R0与R1比较
ADDHIR0,R0,#1
若R0>
R1,则R0=R0+1
ADDLSR1,R1,#1
若R0<
=R1,则R1=R1+1
2、若两个条件均成立,则将这两个数值相加
C代码为:
if((a!
=10)&
&
(b!
=20))a=a+b;
对应的ARM指令为:
CMPR0,#10
比较R0是否为10
CMPNER1,#20
若R0不为10,则比较R1是否为20
ADDNER0,R0,R1;
若R0不为10且R1不为20,则执行R0=R0+R1
3、若两个条件有一个成立,则将这两个数值相加
if((a!
=10)||(b!
CMPEQR1,#20
ADDNER0,R0,R1
ARM存储访问指令:
LDR、STR、LDM、STM、SWP
LDR/STR:
加载/存储字和无符号字节指令
从寻址方式的地址计算方法分,加载/存储指令有以下4种形式:
1,零偏移:
LDRRd,[Rn]
2,前索引偏移:
LDRRd,[Rn,#0x04]!
,LDRRd,[Rn,#-0x04]Rn不允许为R15
3,程序相对偏移:
LDRRd,label,label为程序标号,该形式不能使用后缀!
4,后索引偏移:
LDRRd,[Rn],#0x04,Rn不允许是R15
指令举例如下:
LDRR2,[R5]
加载R5指定地址上的数据(字),放入R2中
STRR1,[R0,#0x04]
将R1的数据存储到R0+0x04存储单元,R0的值不变(若有!
,则R0就要更新)
LDRBR3,[R2],#1
读取R2地址上的一字节数据并保存到R3中,R2=R2+1
STRHR1,[R0,#2]!
将R1的数据保存到R0+2的地址中,只存储低2字节数据,R0=R0+2
LDM和STM是批量加载/存储指令,LDM为加载多个寄存器,STM为存储多个寄存器,主要用途是现场保护,数据复制、参数传递等,其模式有8种,前4种用于数据块的传输,后4种用于堆栈操作
IA:
每次传送后地址加4
IB:
每次传动前地址加4
DA:
每次传送后地址减4
DB:
每次传送前地址减4
FD:
满递减堆栈
ED:
空递增堆栈
FA:
满递增堆栈
EA:
批量加载/存储指令举例如下:
LDMIAR0!
{R3-R9}
加载R0指向的地址上的多字数据,保存到R3-R9中,R0值更新
STMIAR1!
{R3-49}
将R3-R9的数据存储到R1指向的地址上,R1值更新
{R0-R7,LR}
现场保存,将R0~R7、LR入栈
{R0-R7,PC}^;
恢复现场,异常处理返回
使用LDM/STM进行数据复制
LDRR0,=SrcData
设置源数据地址,LDR此时作为伪指令加载地址要加=
LDRR1,=DstData
设置目标地址
LDMIAR0,{R2-R9}
加载8字数据到寄存器R2~R9
STMIAR1,{R2-R9}
存储寄存器R2-R9到目标地址上
使用LDM/STM进行现场保护,常用在子程序或异常处理中
{R0-R7,LR};
寄存器入栈
.....
BLDELAY
调用DELAY子程序
{R0-R7,PC}
恢复寄存器,并返回
SWP是寄存器和存储器交换指令,可使用SWP实现信号量操作
12C_SEMEQU0x40003000
EQU定义一个常量
12C_SEM_WAIT
标签
MOVR1,#0
LDRR0,=12C_SEM
SWPR1,R1,[R0]
取出信号量,并设置为0
CMPR1,#0
判断是否有信号
BEQ12C_SEM_WAIT
若没有信号,则等待
ARM数据处理指令包括
1、数据传送指令
2、算术逻辑运算指令
3、比较指令
4、乘法指令
ADC指令:
带进位加法指令,将操作数2的数据与Rn的值相加,再加上CPSR中C条件标志位,结果保存到Rd中
使用ADC指令实现64位加法
ADDSR0,R0,R2
R0+R2=>
R0,影响CPSR中的值
ADC
R1,R1,R3
(R1、R0)=(R1、R0)+(R3、R2)
SBC指令:
带借位减法指令,用寄存器Rn减去操作数2,再减去CPSR中的C条件标志位的非(即若C标志清零,则结果减去1),结果保存在Rd中
使用SBC实现64位减法
SUBSR0,R0,R2
SBC
使用SBC实现64位减法,(R1,R0)-(R3,R2)
AND指令:
按位与操作
ANDSR0,R0,#0x01
取出最低位数据
ORR指令:
按位或操作
ORRR0,R0,#0x0F
将R0的低4位置1
EOR指令是进行异或操作,BIC指令是位清除指令(遇1清0)
TST:
位测试指令
TSTR0,#0x01
判断R0的最低位是否是为0
TEQ:
相等测试指令
TEQR0,R1
比较R0与R1是否相等,也可看作相减,相等则为0,Z=1
MUL指令:
乘法指令
MULR1,R2,R3
R1=R2*R3
MULSR0,R3,R7
R0=R3*R7,同时设置CPSR中的N位和Z位
MLA是乘加指令,将操作数1和操作数2相乘再加上第3个操作数,结果的低32位存入到Rd中
UMULL是64位无符号乘法指令
UMULLR0,R1,R5,R8
(R1、R0)=R5*R8
BL指令:
带链接的跳转指令,指令将下一条指令拷贝到R14(即LR)链接寄存器中,然后跳转到指定地址运行
BL指令用于子程序调用,例如:
BLDELAY
BX指令:
带状态切换的跳转指令,例如BXR0;
跳转到R0指定的地址,并根据R0的最低位来切换处理器的状态
MCR:
ARM寄存器到协处理器寄存器的数据传送指令
MRC:
协处理器寄存器到ARM寄存器的数据传送指令
MRC/MCR指令格式如下:
MRC/MCR{cond}coproc,opcode1,Rd,CRn,CRm{,opcode2}
coproc是指令操作的协处理器名,标准名为pn,n为0-15
opcode1协处理器的特定操作码
Rd
MRC操作时,作为目标寄存器的协处理器寄存器,MCR操作时,作为ARM处理器的寄存器
CRn存放第1个操作数的协处理器寄存器
CRm存放第2个操作数的协处理器寄存器
opcode2可选的协处理器特定操作码
MRC/MCR指令举例如下:
mcr/mrcp15,0,r0,c1,c0,0
SWI指令:
SWI指令用于产生中断,从而实现用户模式变换到管理模式,CPSR保存到管理模式的SPSR中,执行转移到SWI向量
SWI0x123456
软中断,中断立即数0x123456
在SWI异常中断处理程序中,取出SWI立即数的步骤为:
首先确定引起软中断的SWI指令是ARM指令还是THUMB指令,这可通过对SPSR访问得到,然后要取得该SWI指令的地址,这可通过访问LR寄存器得到,接着读出指令,分解出立即数
程序代码如下:
T_bitEQU0x20
00100000
SWI_Hander
STMFDSP!
{R0-R3,R12,LR}
现场保护
MRS
R0,SPSR
读取SPSR
{R0}
保存SPSR
TSTR0,#T_bit
测试T标志位,0为ARM,1为THUMB
LDRNEH
R0,[LR,#-2]
若是THUMB指令,读出产生中断的指令码(16位)
BICNE
R0,R0,#0xFF00
取得THUMB指令的8位立即数
LDREQ
R0,[LR,#-4]
若是ARM指令,读取产生中断的指令码(32位)
BICEQR0,R0,#0xFF000000
取得ARM指令的24位立即数
BL
C_SWI_Handler
LDMFDSP!
{R0-R3,R12,PC}^
SWI异常中断返回
MRS指令:
读状态寄存器指令,在ARM处理器中,只有MRS指令可以从状态寄存器CPSR或SPSR读出到通用寄存器
MRSR1,CPSR
将CPSR状态寄存器读取,保存到R1
MRSR2,SPSR
将SPSR状态寄存器读取,保存到R2
MRS应用:
1、使能IRQ中断
ENABLE_IRQ
MRSR0,CPSR
BICR0,R0,#0x80
10000000
MSRCPSR,R0
MOVPC,LR
2、禁止IRQ中断
DISABLE_IRQ
ORRR0,R0,#0x80
MSR:
写状态寄存器指令,在ARM处理器中,只有MSR指令可以直接设置状态寄存器CPSR或SPSR
ARM伪指令介绍
ARM伪指令不是ARM指令集中的指令,只是为了编程方便编译器定义了伪指令
ARM地址读取伪指令有四条,分别是
ADR
伪指令
ADRL
NOP
作用的范围不一样,由小到大:
ADR,ADRL,LDR
ADR、ADRL指令将基于PC相对偏移的地址读取到存储器中,例如
R0,DISP_TAB
加载转换表地址
R1,[R0,R2]
使用R2作为参数,进行查表
DISP_TAB
DCB
0xc0,0xf9,0xa4,0x99,0x92,0x82,0xf8,0x80
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器,前加=
LDRR0,=0x123456
加载32位立即数0x123456
LDRR0,=DATA_BUF+60
加载DATA_BUF地址+60
NOP是空操作伪指令
宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏,当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令
符号定义伪指令
1、全局变量声明:
GBLA、GBLL和GBLS
2、局部变量声明:
LCLA、LCLL和LCLS
3、变量赋值:
SETA、SETL、和SETS
4、为一个通用寄存器列表定义名称:
RLIST
5、为一个协处理器的寄存器定义名称:
CN
6、为一个协处理器定义名称:
CP
最后一个字符A代表算术变量,初始值为0,L代表逻辑变量,初值为FALSE,S代表字符串,初值为空
伪指令应用举例如下:
MACRO
声明一个宏
SENDDAT$dat
宏的原型$表示后面是变量
LCLAbitno
声明一个局部算术变量
...
bitnoSETA8
设置变量值为8
MEND
结束
RLIST指令格式:
nameRLIST{reglist},例如:
LoRegRLIST{R0-R7}
定义寄存器列表LoReg
CN指令的用法:
nameCNexpr,其中name是要定义的协处理器的寄存器名称,expr对应的协处理器的寄存器编号,数值范围0~15
MemSetCN1
将协处理器的寄存器1名称定义为MemSet
CP指令的用法,举例如下:
DivRunCP5
将协处理器5名称定义为DivRun
数据定义伪指令:
1、声明一个文字池:
LTORG
2、定义一个结构化的内存表的首地址:
MAP或^
3、定义结构化内存表中的一个数据域:
FIELD或#
4、分配一块内存空间,并用0初始化:
SPACE或%
5、分配一段字节内存单元,并用指定的数据初始化:
DCB
6、分配一段字的内存单元,并用指令的数据初始化:
DCD和DCDU
7、分配一段双字的内存单元,并用64位整数数据初始化:
DCQ和DCQU
8、分配一段半字的内存单元,并用指定的数据初始化:
DCW和DCWU
LTORG用于声明一个文子池,在使用LDR伪指令时,要在适当的地址加入LTORG声明文子池,这样就会把要加载的数据保存在文子池内,再用ARM的加载指令读出数据(若没有使用LTORG声明文子池,则汇编器会在程序末尾自动声明)
LTORG伪指令应用举例如下:
LDRR0,=0x12345678
ADDR1,R1,R0
LTORG
声明文子池
DCD
0x333
DCD0x555
MAP用于定义一个结构化的内存表的首地址,^与MAP同义
MAP0x00,R9
定义内存表的首地址为R9
FIELD用于定义一个结构化内存表的数据域,#与FIELD同义
^_ISR_STARTADDRESS
^issynonymforMAP
HandleReset
#
4
定义数据域HandleReset,长度为4字节
SPACE用于分配一块内存单元,并用0初始化,%与SPACE同义
AREADataRAM,DATA,READWROTE
声明一数据段,名为DataRAM
DataBufSPACE
1000
分配1000字节空间
DCB伪指令格式:
{label}DCBexpr{,expr}...
加{}的代表可有可无,DCD、DCW指令格式与DCB基本相同
ASSERT为断言错误伪指令,在汇编编译器对汇编程序的第二遍扫描中,若其中ASSERT条件不成立,ASSERT伪指令将报告该错误信息
ASSERTTop<
Temp
断言Top不等于Temp
ASSERT:
DEF:
ENDIAN_CHANGE
汇编控制伪指令
1、条件汇编控制:
IF、ELSE和ENDIF
IF、ELSE和ENDIF伪指令能够根据条件把一段代码包括在汇编程序内或将其排除在程序之外
[与IF同义,|与ELSE同义,]与ENDIF同义
[{CONFIG}=16
[代表IF
BL__rt_udiv_1
|
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 常用 ARM 汇编 指令