ARM体系结构与编程-第二章_第1页
ARM体系结构与编程-第二章_第2页
ARM体系结构与编程-第二章_第3页
ARM体系结构与编程-第二章_第4页
ARM体系结构与编程-第二章_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章ARM指令分类及寻址方式第2章目录1.ARM指令的分类和ARM指令的一般格式2.ARM处理器寻址方式第2章目录1.ARM指令的分类和ARM指令的一般格式2.ARM处理器寻址方式ARM指令的分类 跳转指令、数据处理指令、程序状态传输指令、Load/Store指令、协处理器和异常中断产生指令6类2.1ARM指令的一般格式

说明Cond

指令执行的条件编码Opcode

指令操作符编码S

决定指令的操作是否影响CPSR的值Rd

操作目标寄存器编码Rn

包含第一操作数的寄存器编码Shifter_operand

表示第二操作数指令的编码格式2.1ARM指令的一般格式一条指令代码的举例:ADDEQR5,R7,R3,LSL#2;若条件满足Z=1,将R3左移2位与R7相加放入R5这条指令的二进制编码是:

0000条件码cond00001000指令编码Sopcode0111源寄存器Rn0101目标寄存器Rd00010000移位数移位方式0011第二操作寄存器031Shifter-operandEQADDR7R52左移R3201216

ARM指令的基本书写格式如下:2.1ARM指令的一般格式ARM指令集——条件码<opcode>{<cond>}{S}<Rd>,<Rn>,<shifter_operand>

ADDEQR5,R7,R3,LSL#2

使用条件码“cond”可以改变程序的执行顺序,提高代码效率。

当条件满足时执行该指令,条件不满足时该指令不被执行。所有的ARM指令都可以条件执行,如果指令不标明条件代码,将默认为无条件(AL)执行。操作码条件助记符标志含义0000EQZ=1相等0001NEZ=0不相等0010CS/HSC=1无符号数大于或等于0011CC/LOC=0无符号数小于0100MIN=1负数0101PLN=0正数或零0110VSV=1溢出0111VCV=0没有溢出1000HIC=1且Z=0无符号数大于1001LSC=0或Z=1无符号数小于或等于1010GEN=V有符号数大于或等于

1011LTN!=V有符号数小于

1100GTZ=0,N=V有符号数大于

1101LEZ=1,N!=V有符号数小于或等于

1110AL(always)任何无条件执行

(指令默认条件)1111NV任何从不执行(不要使用)指令条件码表2.1ARM指令的一般格式ARM指令——条件码C代码:if((a!=10)&&(b!=20)) a=a+b;对应的汇编代码:CMP R0,#10 ;比较R0是否为10CMPNE R1,#20 ;若Z=0,R0不是10,则比较R1是否为20ADDNE R0,R0,R1

;若Z=0,R0不为10且R1不为20,则执行指令

R0=R0+R1示例:若两个条件均成立,则将两个数值相加。2.1ARM指令的一般格式ARM指令——条件码C代码:If((a!=10)&&(b==20)) a=a+b;对应的汇编代码:

CMPR0,#10;比较R0是否为10 BEQlable ;若R0=10则不必后面的比较,跳转至lable CMPNE R1,#20 ;R0!=10,再比较R1 ADDEQ R0,R0,R1

LableMOVR8,R11示例:若两个条件均成立,则将两个数值相加。对应的错误汇编代码:CMP R0,#10 ADDNE R0,R0,R1

CMPEQ R1,#20 ADDNE R0,R0,R1

对应的汇编代码:CMP R0,#10 ;比较R0是否为10CMPEQ R1,#20 ;若Z=1,即R0为10,则比较R1是否为20

;若Z=1,即R0不为10,则本指令不执行ADDNE R0,R0,R1

;若R0不为10

或R1不为20,

则执行R0=R0+R1。2.1ARM指令的一般格式ARM指令——条件码C代码:If((a!=10)||(b!=20)) a=a+b;示例:若两个条件有一个成立,则将两个数值相加。2.1ARM指令的一般格式ARM指令——指令格式2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式

ARM指令的基本书写格式如下:<opcode>{<cond>}{S}<Rd>,<Rn>,<shift_operand>

第2个操作数“shift_operand”有如下3种形式(见教材25页*):#<immediate>——立即数表达式MOVR0,#0X04800000 ;R0=0X04800000<Rm>——寄存器方式SUBR0,R1,R2 ;R0=R1-R2<Rm>,shift——寄存器移位方式ADDR0,R1,R1,LSL

#2 ;R0=R1+R1*42.2.1数据处理指令的操作数寻址方式2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式先介绍:#<immediate>——立即数MOVR0,#0X04800000 ;R0=0X04800000在数据处理指令中,规定这个立即数必须是一个8bit的常数通过循环右移偶数位得到。循环右移10位0x12000100100x00000000000x00000000000x00000000000x00000000000x00000000000x80100000000x04000001008位常数2.2.1数据处理指令的操作数寻址方式合法的立即数(参见教材25页图)〈immediate〉=immed_8循环右移(2Xrotate_imm)8bit4bit(0—15)范围:0—30最大为0xffADDr1,r2,#0xFF0000;uses0xFF(immed_8)ror16(rotate_imm=8)MOVR0,#0X04800000;immed_8=0x12,rotate_imm=5 ;将0x12循环右移10(2*rotate_imm)位判断合法立即数的方法0-0xff之间的一个8位数。在满足不超8位的情况下,若最右侧的“1”的右侧0形成偶数位时,从最右侧的“1”算起,否则为奇数时在右侧多取一个0,向高位(向左),得到这个8位数。类型为0xf000000f的除外,(合法立即数)。循环右移偶数位。练习下面哪些立即数是数据处理指令中有效的数据?a)0x000003FCb)0x000001FEc)0xF0000000d)0x0000FFFFe)0xF0000001f)0xF0000010g)0x0000010824页书上√0xFF>>30×√0xF0>>8×√0x1F>>4或0x7C>>6×√0x42>>300x800000100x108 循环右移4位得到0x800000100001

00001000取0x42循环右移30位可以得到0x10801000010那么,0x42循环右移34位可以得到0x80000010也就是0x42循环右移两位就可得到0x80000010。0x80000010为合法立即数0x20000010

0x102 循环右移4位得到0x200000100001

0000

0010取0x81循环右移31位可以得到0x102,移位为奇数,则0x102非法。那么0x20000010为非法。蓝色数值合法即合法,非法即非法。立即数(2)一个合法的立即数可能有多种编码方法。如0x3f0是一个合法的立即数,它可以采用下面两种编码方法生成:

Immed_8=0x3f,rotate_imm=14循环右移28位或者

Immed_8=0xfc,rotate_imm=15循环右移30位

MOVR0,#4096;uses(immed_8=0x40)ror26(rotate_imm=13);将0x40循环右移26位,也就相当于0X40左移6位;亦可immed_8=0x01ror(rotate_imm=10)。;也就是将0x01循环右移20位,也可以得到。ARM汇编编译器按照下面的规则来生成立即数编码:当立即数数值在0—0xff范围内时,令<immediate>=immed_8,rotate_imm=0其它情况下,汇编编译器选择rotate_imm数值最小的编码方法。装载32bit常数 为允许装载较大的立即数,汇编器提供了一条伪指令:

LDRRd,=const

推荐使用这种方法把常数装入寄存器如,LDRR1,=0XFFFFFF00操作数的值存放在寄存器中,指令执行时直接取出寄存器值来操作。寄存器寻址指令举例如下:MOVR1,R2

;将R2的值存入R1SUBR0,R1,R2;将R1的值减去R2的值,结果保存到R0

0xAA0x55R2R1<Rm>——寄存器方式MOVR1,R20xAA2.2.1数据处理指令的操作数寻址方式<opcode>{<cond>}{S}<Rd>,<Rn>,<shift_operand>

可以采取的移位操作如下:LSL:逻辑左移(LogicalShiftLeft)LSR:逻辑右移(LogicalShiftRight)ASR:算术右移(ArithmeticShiftRight)ROR:循环右移(ROtateRight)RRX:扩展为1的循环右移(RotateRighteXtendedby1place)寄存器移位寻址2.2.1数据处理指令的操作数寻址方式<opcode>{<cond>}{S}<Rd>,<Rn>,<shift_operand>

LSL逻辑左移:右侧用0填充,最后移出位入C0LSR逻辑右移:左侧用0填充,最后移出位入C0ASR算术右移:用符号位填充,最后移出位入CROR循环右移:最后移出位入CRRX扩展的循环右移(只移一位)右侧移出入C,C入左侧一位CCCC2.2.1数据处理指令的操作数寻址方式2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式Load指令用于从存储器(包括内存和外存)中读取数据加载到寄存器中;Store指令用于将寄存器的数据保存到存储器。各种类型的Load/Store指令中寻找的地址由两部分组成:

1〉基址寄存器:一般使用通用寄存器

2〉地址偏移量:立即数、寄存器、寄存器及一个移位常数。

需要的地址=基址寄存器+地址偏移量2.2.2字及无符号字节的Load/Store指令的寻址方式寄存器移位寻址是ARM指令集特有的寻址方式。0x55R0R20x01寄存器移位寻址MOVR0,R2,LSL#30x080x08逻辑左移3位2.2.1数据处理指令的操作数寻址方式变址寻址就是将基址寄存器中的地址与指令中给出的偏移量相加/减,形成有效地址。变址寻址用于访问基址附近的存储单元,常用于查表、数组操作、功能部件寄存器(与通用寄存器R0-R12不同)访问等。变址寻址0x55R2R30x400000000xAA0x4000000CLDRR2,[R3,#0x0C]0xAAR3+0x0C作为地址2.2.2字及无符号字节的Load/Store指令的寻址方式LDR指令的语法格式如下:(访问的数据的地址)LDR{<cond>}{B}{T}<Rd>,<address_mode>;T后缀,在特权模式下对存储器的访问,将被存储器看成是用户模式(即非特权)的访问,操作的寄存器也是用户模式下的。(destination目的地)(书上34页*,35页*)其中,<

address_mode>

有下面9种格式(Rn为基址寄存器):

1.[<Rn>,#+/-<offset_12>]立即数,注定在Rn的4k范围

2.[<Rn>,+/-<Rm>]寄存器

3.[<Rn>,+/-<Rm>,<shift>#<shift_imm>]寄存器移位

LDRR0,[R1,#4];将[R1+4]中的字读取到R0寄存器

4.[<Rn>,#+/-<offset_12>]!注定在Rn的4k范围

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

LDRR0,[R1,#4]!;将[R1+4]中数据放到R0寄存器,更新R1为R1+4 7.[<Rn>],#+/-<offset_12>注定在Rn的4k范围

8.[<Rn>],+/-<Rm> 9.[<Rn>],+/-<Rm>,<shift>#<shift_imm> LDRR0,[R1],#4;将[R1]中数据放入R0寄存器,更新R1为R1+4偏移量方法不更新基址寄存器事先更新(前变址)(前索引)事后更新(后变址)(后索引)偏移量方法LDRR0,[R1,R2,LSL#2];R0←[R1+R2*4],R1不变事先更新基址(前索引)(前变址)

操作之前,先改变基址寄存器。LDRR0,[R1,R2,LSL#2]!;R0←[R1+R2*4],更新R1为R1+R2*4事后更新基址(后索引)(后变址)操作之后,再改变基址寄存器。LDRR0,[R1],R2,LSL#2;R0←[R1],更新R1为R1+R2*4举例:这里R1为基址寄存器地址=基址+偏移地址PreorPostIndexedstore寻址I=0,立即数偏移I=1,寄存器偏移P=1,偏移量/前索引P=0,后索引U=1,加偏移U=0,减偏移W=1,后缀有!回写基址寄存器W=0,后缀无!不回写基址寄存器B=1,对字节进行操作B=0,对字进行操作L=0,存储操作L=1,加载操作LOAD/STORE指令中出现的位(34页*1):2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式(见教材)批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式(见教材)批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式批量Load/Store指令的寻址方式多(批量)寄存器寻址 先增加地址(IB):STMIB,LDMIB;每次传送前指针加4

后增加地址(IA):STMIA,LDMIA;每次传送后指针加4

先减少地址(DB):STMDB,LDMDB;每次传送前指针减4

后减少地址(DA):STMDA,LDMDA;每次传送后指针减4

I:Increment

D:Decrement

B:Before

A:Afterr10+4r10r10+8r10+cAddressing_mode为IA、IB、DA、DB其中xx为IA、IB、DA、DBr10+4r10+8r10+cAddressing_mode为IA、IB、DA、DB其中xx为IA、IB、DA、DBdata7data5data3data5data3data3data1data5data9data8data4data6r4

r1r0r4

r1r0r102.2ARM处理器寻址方式寻址方式分类——堆栈寻址栈底栈顶栈区SP

堆栈存储区栈顶栈底栈区

SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈Ascending

栈Descending

栈高地址高地址低地址低地址增减栈顶SP

栈顶SP

栈底空堆栈栈底满堆栈堆栈指针指向最后压入的堆栈的有效数据项,称为满(Full)堆栈;堆栈指针指向下一个待压入数据的空(Empty)位置,称为空堆栈。2.2ARM处理器寻址方式寻址方式分类——堆栈寻址0x123456780x12345678栈顶SP

0x12345678栈顶SP

压栈压栈所以可以组合出四种类型的堆栈方式(须注意皆指入栈):满递增:堆栈向上增长,堆栈指针指向最高有效数据项。指令如STMFA、LDMFA等;空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如STMEA、LDMEA等;满递减:堆栈向下增长,堆栈指针指向最低有效数据项。指令如STMFD、LDMFD等;空递减:堆栈向下增长,堆栈指针指向堆栈下的第一个空位置。指令如STMED、LDMED等。2.2ARM处理器寻址方式寻址方式分类——堆栈寻址2.2ARM处理器寻址方式多(批量)寄存器寻址和堆栈寻址之间的关系增长先后入栈时堆栈向上生长入栈时堆栈向下生长满空满空增加之前STMIBSTMFALDMIBLDMED之后STMIASTMEALDMIALDMFD减少之前LDMDBLDMEASTMDBSTMFD之后LDMDALDMFASTMDASTMEDSTMFAr13!,{r0-r5};←PushontoaFullAscendingStackLDMFAr13!,{r0-r5};→PopfromaFullAscendingStackSTMFDr13!,{r0-r5};←

PushontoaFullDescendingStackLDMFDr13!,{r0-r5};→PopfromaFullDescendingStackSTMEAr13!,{r0-r5};←PushontoanEmptyAscendingStackLDMEAr13!,{r0-r5};→PopfromanEmptyAscendingStackSTMEDr13!,{r0-r5};←PushontoEmptyDescendingStackLDMEDr13!,{r0-r5};→PopfromanEmptyDescendingStack2.2ARM处理器寻址方式高地址低地址2.2ARM处理器寻址方式寻址方式分类

寻址方式是寻找真实操作数地址的方式。ARM处理器具有5种基本寻址方式。数据处理指令的操作数的寻址方式字及无符号字节的Load/Store指令的寻址方式杂类Load/Store指令的寻址方方式(见教材)批量Load/Store指令的寻址方式协处理器Load/Store指令的寻址方式数据块传送存储堆栈操作压栈数据块传送加载堆栈操作出栈STMDASTMEDLDMDALDMFASTMIASTMEALDMIALDMFDSTMDBSTMFDLDMDBLDMEASTMIBSTMFALDMIBLDMED;使用数据块传送指令进行堆栈操作STMDB R0!,{R5-R7}...LDMIA R0!,{R5-R7};使用堆栈指令进行堆栈操作STMFD R0!,{R5-R7}...LDMFD R0!,{R5-R7}

两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后后缀一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。堆栈操作和数据块传送指令类似,也有4种模式,它们之间的关系如下表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论