ARM指令集详解资料000001.docx

上传人:b****4 文档编号:6798545 上传时间:2023-05-10 格式:DOCX 页数:18 大小:31.64KB
下载 相关 举报
ARM指令集详解资料000001.docx_第1页
第1页 / 共18页
ARM指令集详解资料000001.docx_第2页
第2页 / 共18页
ARM指令集详解资料000001.docx_第3页
第3页 / 共18页
ARM指令集详解资料000001.docx_第4页
第4页 / 共18页
ARM指令集详解资料000001.docx_第5页
第5页 / 共18页
ARM指令集详解资料000001.docx_第6页
第6页 / 共18页
ARM指令集详解资料000001.docx_第7页
第7页 / 共18页
ARM指令集详解资料000001.docx_第8页
第8页 / 共18页
ARM指令集详解资料000001.docx_第9页
第9页 / 共18页
ARM指令集详解资料000001.docx_第10页
第10页 / 共18页
ARM指令集详解资料000001.docx_第11页
第11页 / 共18页
ARM指令集详解资料000001.docx_第12页
第12页 / 共18页
ARM指令集详解资料000001.docx_第13页
第13页 / 共18页
ARM指令集详解资料000001.docx_第14页
第14页 / 共18页
ARM指令集详解资料000001.docx_第15页
第15页 / 共18页
ARM指令集详解资料000001.docx_第16页
第16页 / 共18页
ARM指令集详解资料000001.docx_第17页
第17页 / 共18页
ARM指令集详解资料000001.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

ARM指令集详解资料000001.docx

《ARM指令集详解资料000001.docx》由会员分享,可在线阅读,更多相关《ARM指令集详解资料000001.docx(18页珍藏版)》请在冰点文库上搜索。

ARM指令集详解资料000001.docx

ARM指令集详解资料000001

ARM指令集详解

ARM可以用两套指令集:

ARM指令集和Thumb指令集。

本文介绍ARM指令集。

在介绍ARM指令集之前,先介绍指令的格式。

1 指令格式

       

(1)基本格式

       {}{S},{,}

       其中,<>内的项是必须的,{}内的项是可选的,如是指令助记符,是必须的,而{}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。

       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

       

(2)第2个操作数

       在ARM指令中,灵活的使用第2个操作数能提高代码效率,第2个操作数的形式如下:

       #immed_8r

       常数表达式,该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到。

       合法常量

       0x3FC、0、0xF0000000、200、0xF0000001等都是合法常量。

       非法常量

       0x1FE、511、0xFFFF、0x1010、0xF0000010等都是非法常量。

       常数表达式应用举例如下:

       MOVR0,#1;R0=1

       ANDR1,R2,#0x0F;R2与0x0F,结果保存在R1

       LDRR0,[R1],#-4;读取R1地址上的存储器单元内容,且R1=R1-4

       Rm

       寄存器方式,在寄存器方式下操作数即为寄存器的数值。

       寄存器方式应用举例:

       SUBR1,R1,R2;R1-R2=>R1

       MOVPC,R0;PC=R0,程序跳转到指定地址

       LDRR0,[R1],-R2;读取R1地址上的存储器单元内容并存入R0,且R1=R1-R2

       Rm,shift

       寄存器移位方式。

将寄存器的移位结果作为操作数,但RM值保存不变,移位方法如下:

       ASR#n 算术右移n位(1≤n≤32)

       LSL#n 逻辑左移n位(1≤n≤31)

       LSR#n 逻辑左移n位(1≤n≤32)

       ROR#n 循环右移n位(1≤n≤31)

       RRX 带扩展的循环右移1位

       typeRs 其中,type为ASR,LSL,和ROR中的一种;Rs偏移量寄存器,低8位有效,若其值大于或等于32,则第2个操作数的结果为0(ASR、ROR例外)。

       寄存器偏移方式应用举例:

       ADDR1,R1,R1,LSL#3;R1=R1*9

       SUBR1,R1,R2,LSR#2;R1=R1-R2*4

       R15为处理器的程序计数器PC,一般不要对其进行操作,而且有些指令是不允许使用R15,如UMULL指令。

       (3)条件码

       使用指令条件码,可实现高效的逻辑操作,提高代码效率。

表A-1给出条件码表。

表A-1 条件码表

       对于Thumb指令集,只有B指令具有条件码执行功能,此指令条件码同表A-?

,但如果为无条件执行时,条件码助记符“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

       若两个条件均成立,则将这两个数值相加,C代码为:

       If((a!

=10)&&(b!

=20))a=a+b;

       对应的ARM指令如下,其中R0为a,R1为b。

       CMPR0,#10         ;比较R0是否为10

       CMPNER1,#20      ;若R0不为10,则比较R1是否20

       ADDNER0,R0,R1      ;若R0不为10且R1不为20,指令执行,R0=R0+R1

2 ARM存储器访问指令

       ARM处理是加载/存储体系结构的典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。

ARM的加载/存储指令是可以实现字、半字、无符/有符字节操作;批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率;SWP指令是一条寄存器和存储器内容交换的指令,可用于信号量操作等。

ARM处理器是冯?

诺依曼存储结构,程序空间、RAM空间及IO映射空间统一编址,除对对RAM操作以外,对外围IO、程序数据的访问均要通过加载/存储指令进行。

表A-2给出ARM存储访问指令表。

表A-2 ARM存储访问指令表

       LDR和STR

       加载/存储字和无符号字节指令。

使用单一数据传送指令(STR和LDR)来装载和存储单一字节或字的数据从/到内存。

LDR指令用于从内存中读取数据放入寄存器中;STR指令用于将寄存器中的数据保存到内存。

指令格式如下:

       LDR{cond}{T}Rd,<地址>;加载指定地址上的数据(字),放入Rd中

       STR{cond}{T}Rd,<地址>;存储数据(字)到指定地址的存储单元,要存储的数据在Rd中

       LDR{cond}B{T}Rd,<地址>;加载字节数据,放入Rd中,即Rd最低字节有效,高24位清零

       STR{cond}B{T}Rd,<地址>;存储字节数据,要存储的数据在Rd,最低字节有效

       其中,T为可选后缀,若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看成是处理器是在用户模式下。

T在用户模式下无效,不能与前索引偏移一起使用T。

       LDR/STR指令寻址是非常灵活的,由两部分组成,一部分为一个基址寄存器,可以为任一个通用寄存器,另一部分为一个地址偏移量。

地址偏移量有以下3种格式:

       

(1)立即数。

立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

指令举例如下:

       LDRR1,[R0,#0x12];将R0+0x12地址处的数据读出,保存到R1中(R0的值不变)

       LDRR1,[R0,#-0x12];将R0-0x12地址处的数据读出,保存到R1中(R0的值不变)

       LDRR1,[R0];将R0地址处的数据读出,保存到R1中(零偏移)

       

(2)寄存器。

寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

指令举例值。

指令举例如下:

       LDRR1,[R0,R2];将R0+R2地址的数据计读出,保存到R1中(R0的值不变)

       LDRR1,[R0,-R2];将R0-R2地址处的数据计读出,保存到R1中(R0的值不变)

       (3)寄存器及移位常数。

寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

指令举例如下:

       LDRR1,[R0,R2,LSL#2];将R0+R2*4地址处的数据读出,保存到R1中(R0,R2的值不变)

       LDRR1,[R0,-R2,LSL#2];将R0-R2*4地址处的数据计读出,保存到R1中(R0,R2的值不变)

       从寻址方式的地址计算方法分,加载/存储指令有以下4种形式:

       

(1)零偏移。

Rn的值作为传送数据的地址,即地址偏移量为0。

指令举例如下:

       LDRRd,[Rn]

       

(2)前索引偏移。

在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储地址。

若使用后缀“!

”,则结果写回到Rn中,且Rn值不允许为R15。

指令举例如下:

       LDRRd,[Rn,#0x04]!

       LDRRd,[Rn,#-0x04]

       (3)程序相对偏移。

程序相对偏移是索引形式的另一个版本。

汇编器由PC寄存器计算偏移量,并将PC寄存器作为Rn生成前索引指令。

不能使用后缀“!

”。

指令举例如下:

       LDRRd,label;label为程序标号,label必须是在当前指令的±4KB范围内

       (4)后索引偏移。

Rn的值用做传送数据的存储地址。

在数据传送后,将偏移量与Rn相加,结果写回到Rn中。

Rn不允许是R15。

指令举例如下:

       LDRRd,[Rn],#0x04

       地址对准--大多数情况下,必须保证用于32位传送的地址是32位对准的。

       加载/存储字和无符号字节指令举例如下:

       LDRR2,[R5];加载R5指定地址上的数据(字),放入R2中

       STRR1,[R0,#0x04];将R1的数据存储到R0+0x04存储单元,R0值不变

       LDRBR3,[R2],#1;读取R2地址上的一字节数据,并保存到R3中,R2=R3+1

       STRBR6,[R7];读R6的数据保存到R7指定的地址中,只存储一字节数据

       加载/存储半字和带符号字节。

这类LDR/STR指令可能加载带符字节\加载带符号半字、加载/存储无符号半字。

偏移量格式、寻址方式与加载/存储字和无符号字节指令相同。

指令格式如下:

       LDR{cond}SBRd,<地址>;加载指定地址上的数据(带符号字节),放入Rd中

       LDR{cond}SHRd,<地址>;加载指定地址上的数据(带符号字节),放入Rd中

       LDR{cond}HRd,<地址>;加载半字数据,放入Rd中,即Rd最低16位有效,高16位清零

       STR{cond}HRd,<地址>;存储半字数据,要存储的数据在Rd,最低16位有效

       说明:

带符号位半字/字节加载是指带符号位加载扩展到32位;无符号位半字加载是指零扩展到32位。

       地址对准--对半字传送的地址必须为偶数。

非半字对准的半字加载将使Rd内容不可靠,非半字对准的半字存储将使指定地址的2字节存储内容不可靠。

       加载/存储半字和带符号字节指令举例如下:

       LDRSBR1[R0,R3];将R0+R3地址上的字节数据读出到R1,高24位用符号位扩展

       LDRSHR1,[R9];将R9地址上的半字数据读出到R1,高16位用符号位扩展

       LDRHR6,[R2],#2;将R2地址上的半字数据读出到R6,高16位用零扩展,R2=R2+1

       SHRHR1,[R0,#2]!

;将R1的数据保存到R2+2地址中,只存储低2字节数据,R0=R0+2

       LDR/STR指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外设的控制操作等等,若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。

       变量的访问

       NumCountEQU0x40003000;定义变量NumCount

       …

       LDRR0,=NumCount;使用LDR伪指令装载NumCount的地址到R0

       LDRR1,[R0];取出变量值

       ADDR1,R1,#1;NumCount=NumCount+1

       STRR1,[R0];保存变量值

       …

       GPIO设置

       GPIO-BASEEQU0Xe0028000;定义GPIO寄存器的基地址

       …

       LDRR0,=GPIO-BASE

       LDRR1,=0x00FFFF00;装载32位立即数,即设置值

       STRR1,[R0,#0x0C];IODIR=0x00FFFF00,IODIR的地址为0xE002800C

       MOVR1,#0x00F00000

       STRR1,[R0,#0x04];IOSET=0x00F00000,IOSET的地址为0xE0028004

       …

       程序散转

       …

       MOVR2,R2,LSL#2;功能号乘上4,以便查表

       LDRPC,[PC,R2];查表取得对应功能子程序地址,并跳转

       NOP

       FUN-TABDCDFUN-SUB0

       DCDFUN-SUB1

       DCDFUN-SUB2

       …

       LDM和STM

       批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。

LDM为加载多个寄存器,STM为存储多个寄存器。

允许一条指令传送16个寄存器的任何子集或所有寄存器。

指令格式如下:

       LDM{cond}<模式>Rn{!

},reglist{^}

       STM{cond}<模式>Rn{!

},reglist{^}

       LDM/STM的主要用途是现场保护、数据复制、参数传送等。

其模式有8种,如下所列:

(前面4种用于数据块的传输,后面4种是堆栈操作)。

       

(1)IA:

每次传送后地址加4

       

(2)IB:

每次传送前地址加4

       (3)DA:

每次传送后地址减4

       (4)DB:

每次传送前地址减4

       (5)FD:

满递减堆栈

       (6)ED:

空递增堆栈

       (7)FA:

满递增堆栈

       (8)EA:

空递增堆栈

       其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀“!

”表示最后的地址写回到Rn中;寄存器列表reglist可包含多于一个寄存器或寄存器范围,使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“^”后缀不允许在用户模式呈系统模式下使用,若在LDM指令用寄存器列表中包含有PC时使用,那么除了正常的多寄存器传送外,将SPSR拷贝到CPSR中,这可用于异常处理返回;使用“^”后缀进行数据传送且寄存器列表不包含PC时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。

       地址对准――这些指令忽略地址的位[1:

0]。

       批量加载/存储指令举例如下:

       LDMIAR0!

{R3-R9};加载R0指向的地址上的多字数据,保存到R3~R9中,R0值更新

       STMIAR1!

{R3-R9};将R3~R9的数据存储到R1指向的地址上,R1值更新

       STMFDSP!

{R0-R7,LR};现场保存,将R0~R7、LR入栈

       LDMFDSP!

{R0-R7,PC}^;恢复现场,异常处理返回

       在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB进行读取和存储。

而进行堆栈操作时,则要先设置堆栈指针,一般使用SP然后使用堆栈寻址指令STMFD/LDMFD、STMED。

LDMED、STMFA/LDMFA、STMEA/LDMEA实现堆栈操作。

       多寄存器传送指令示意图如图A-1所示,其中R1为指令执行前的基址寄存器,R1’则为指令执行完后的基址寄存器。

(a)指令STMIAR1!

{R5-R7}                    (b)指令STMIBR1!

{R5-R7}

             

 

(c)指令STMDAR1!

{R5-R7}                    (d)指令STMDBR1!

{R5-R7}

图A-1 多寄存器传送指令示意图

       数据是存储在基址寄存器的地址之上还是之下,地址是在存储第一个值之前还是之后增加还是减少。

表A-3给出多寄存器传送指令映射示意表。

表A-3 多寄存器传送指令映射示意表

       使用LDM/STM进行数据复制例程如下:

       …

       LDRR0,=SrcData;设置源数据地址

       LDRR1,=DstData;设置目标地址

       LDMIAR0,{R2-R9};加载8字数据到寄存器R2~R9

       STMIAR1,{R2-R9};存储寄存器R2~R9到目标地址

       使用LDM/STM进行现场寄存器保护,常在子程序中或异常处理使用:

       SENDBYTE

       STMFDSP!

{R0-R7,LR};寄存器入堆

       …

       BLDELAY;调用DELAY子程序

       …

       LDMFDSP!

{R0-R7,PC};恢复寄存器,并返回

       SWP

       寄存器和存储器交换指令。

SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。

使用SWP可实现信号量操作。

       指令格式如下:

       SWP{cond}{B}Rd,Rm,[Rn]

       其中,B为可选后缀,若有B,则交换字节,否则交换32位字:

Rd为数据从存储器加载到的寄存器;Rm的数据用于存储到存储器中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。

       SWP指令举例如下:

       SWPR1,R1,[R0];将R1的内容与R0指向的存储单元的内容进行交换

       SWPR1,R2,,[R0];将R0指向的存储单元内容读取一字节数据到R1中(高24位清零)

                                       ;并将R2的内容写入到该内存单元中(最低字节有效)

       使用SWP指令可以方便地进行信号量的操作:

       12C_SEMEQU0x40003000

       …

       12C_SEM_WAIT

       MOVR0,#0

       LDRR0,=12C_SEM

       SWPR1,R1,[R0]      ;取出信号量,并设置其为0

       CMPR1,#0         ;判断是否有信号

       BEQ12C_SEM_WAIT    ;若没有信号,则等待

3 ARM数据处理指令

       数据处理指令大致可分为3类;数据传送指令(如MOV、MVN),算术逻辑运算指令(如ADD,SUM,AND),比较指令(如CMP、TST)。

数据处理指令只能对寄存器的内容进行操作。

       所有ARM数据处理指令均可选择使用S后缀,以影响状态标志。

比较指令CMP、CMN、TST和TEQ不需要后缀S,它们会直接影响状态标志。

ARM数据处理指令列于表A-4中。

表A-4 ARM数据处理指令

       

(1)数据传送指令

       MOV

       数据传送指令。

将8位图立即数或寄存器(operant2)传送到目标寄存器Rd,可用于移位运算等操作。

指令格式如下:

       MOV{cond}{S}Rd,operand2

       MOV指令举例如下:

       MOVR1#0x10;R1=0x10

       MOVR0,R1;R0=R1

       MOVSR3,R1,LSL#2;R3=R1<<2,并影响标志位

       MOVPC,LR  ;PC=LR,子程序返回

       MVN

       数据非传送指令。

将8位图立即数或寄存器(operand2)按位取反后传送到目标寄存器(Rd),因为其具有取反功能,所以可以装载范围更广的立即数。

指令格式如下:

       MVN{cond}{S}Rd,operand2

       MVN指令举例如下:

       MVNR1,#0xFF;R1=0xFFFFFF00

       MVNR1,R2;将R2取反,结果存到R1

       

(2)算术逻辑运算指令

       ADD

       加法运算指令。

将operand2数据与Rn的值相加,结果保存到Rd寄存器。

指令格式如下:

       ADD{cond}{S}Rd,Rn,operand2

      

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2