文档详情

嵌入式系统原理与开发:第三章 ARM体系结构与指令集

壹****1
实名认证
店铺
PPT
1.14MB
约146页
文档ID:569221776
嵌入式系统原理与开发:第三章 ARM体系结构与指令集_第1页
1/146

第三章 ARM体系结构与指令集 主要内容nARM处理器的寻址方式nARM指令集合nThumb指令集合n伪指令 ARM处理器的寻址方式寻址方式:根据指令编码中给出的地址码字段来寻找真实操作数的方式n立即寻址立即寻址n寄存器寻址寄存器寻址n寄存器偏移寻址寄存器偏移寻址n寄存器间接寻址寄存器间接寻址n基址加偏址寻址基址加偏址寻址n多寄存器寻址多寄存器寻址 n相对寻址相对寻址n堆栈寻址堆栈寻址 n块拷贝寻址块拷贝寻址 立即寻址指令中的操作码字段后面的地址码部分即是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(这样的数称为立即数)立即寻址指令举例如下:立即寻址指令举例如下: SUBSSUBSR0,R0,#1R0,R0,#1 ;R0减1,结果放入R0,并且影响标志位MOVMOVR0,#0xFF000R0,#0xFF000 ;将立即数0xFF000装入R0寄存器 •书写立即数时,要求以“#”为前缀•十六进制数,#后加 0x或&,如 #0x3f,#&3f.•二进制数,#后加 0b, 如 #0b1011•十进制数,#后加 0d或缺省,如#0d678,#7890x55R0MOV R0,#0xFF00程序存储(1).立即寻址MOV R0,#0xFF00MOV R0,#0xFF000xFF00从代码中获得数据 有效立即数问题n该常数必须对应8位位图,即一个8 8位的常数通位的常数通过循环右移偶数位过循环右移偶数位得到。

循环右移10位0x120 0 0 1 0 0 1 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x801 0 0 0 0 0 0 00x040 0 0 0 0 1 0 08位常数合法常量:0x3FC、0、0xF0000000、200、0xF0000001 非法常量:0xlFE、511、0xFFFF、0x1010、0xF0000010 操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值来操作 寄存器寻址指令举例如下:寄存器寻址指令举例如下: MOV R1,R2MOV R1,R2 ; ;将R2的值存入R1 SUB R0,R1,R2SUB R0,R1,R2 ; ;将R1的值减去R2的值,结果保存到R0 0xAA0x55R2R1(2).寄存器寻址MOV R1,R2MOV R1,R20xAA 寄存器移位寻址是ARM指令集特有的寻址方式。

当第2个操作数是寄存器移位方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作寄寄存存器器移移位位寻寻址指令举例如下:址指令举例如下:MOVMOVR0,R2,LSL R0,R2,LSL #3#3 ;R2的值左移3位,结果放入R0, ;即是R0=R2×8 ANDSANDSR1,R1,R2,LSL R1,R1,R2,LSL R3R3 ;R2的值左移R3位,然后和R1相 ;“与”操作,结果放入R10x55R0R20x01(3).寄存器偏移寻址MOV R0,R2,LSL #3MOV R0,R2,LSL #30x080x08逻辑左移3位 n第二操作数移位方式第二操作数移位方式qLSLLSL:逻辑左移,空出的最低有效位用:逻辑左移,空出的最低有效位用0 0填充qLSRLSR:逻辑右移,空出的最高有效位用:逻辑右移,空出的最高有效位用0 0填充031 0031 0(3).寄存器偏移寻址 ›ASLASL::算术左移,由于左移空出的有效位用算术左移,由于左移空出的有效位用0 0填充,因填充,因此它与此它与LSLLSL同义。

同义›ASRASR::算术右移算术右移 (Arithmetic Shift Right) (Arithmetic Shift Right) 算术移算术移位的对象是带符号数,移位过程中必须保持操作数的位的对象是带符号数,移位过程中必须保持操作数的符号不变如果源操作数是正数,空出的最高有效位符号不变如果源操作数是正数,空出的最高有效位用用0 0填充,如果是负数用填充,如果是负数用1 1填充 30 0 (3).寄存器偏移寻址 nROR::循环右移循环右移(Rotate Right),,移出的字的最低有效移出的字的最低有效位依次填入空出的最高有效位位依次填入空出的最高有效位 31 0 nRRX::带扩展的循环右移带扩展的循环右移(Rotate Right Extended) 。

将寄存器的内容将寄存器的内容循环右移循环右移1位位,空位用原来,空位用原来C进位标志进位标志位填充 31 0 C(3).寄存器偏移寻址 (1).指令格式:第第2 2个操作数个操作数LSL移位操作:0LSR移位操作:0ASR移位操作:ROR移位操作:RRX移位操作:C 寄存器偏移方式应用举例:寄存器偏移方式应用举例:ADD R1ADD R1,,R1R1,,R1R1,,LSL #3 LSL #3 ;;R1=R1×8R1=R1×8SUB R1SUB R1,,R1R1,,R2R2,,LSR #2 LSR #2 ;;R1=R1-R2×4R1=R1-R2×4 寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针寄寄存存器器间间接寻址指令举例如下:接寻址指令举例如下: LDRLDRR1,[R2]R1,[R2];将R2指向的存储单元的数据读出;保存在R1中 SWPSWPR1,R1,[R2]R1,R1,[R2];将寄存器R1的值和R2指定的存储;单元的内容交换 0x55R0R2 0x400000000xAA0x40000000(4).寄存器间接寻址LDR R0,[R2]LDR R0,[R2]0xAA 基址寻址就是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址。

基址寻址指令举例如下: LDRLDRR2,[R3,#0x0C]R2,[R3,#0x0C] ;读取R3+0x0C地址上的存储单元 ;的内容,放入R2 STRSTRR1,[R0,#-4]!R1,[R0,#-4]!;先R0=R0-4,然后把R1的值 ;到保存到R0指定的存储单元 (5).基址加偏址寻址0x55R2R3 0x400000000xAA0x4000000CLDR R2,[R3,#0x0C]LDR R2,[R3,#0x0C]0xAA将R3+0x0C作为地址装载数据 n有三种加偏址的方式:n前变址模式前变址模式(不修改基址寄存器):: n ——先基址+偏址,生成操作数地址,做指令指定的操作0x50x5r1r10x2000x200基址基址寄存器寄存器0x200r0r00x50x5源寄存器源寄存器for STRfor STR偏移量偏移量12120x20cn Pre-indexed: STR r0,[r1,#12](5).基址加偏址寻址 n自动变址模式自动变址模式(修改基址寄存器):: n ——①先基址+偏移,生成操作数地址,做指令指定的操作。

②然后自动修改基址寄存器n例如:LDR R0,[R1,#4]! ;R0←mem32 [R1+4];R1←R1+4 ! ——表示更新基址寄存器5).基址加偏址寻址 后变址模式后变址模式(修改基址寄存器):: ——①基址寄存器不加偏移作为操作数地址 ②完成指令操作后,用(基址+偏移)的值修改基址寄存器0x50x5r1r10x2000x200原基址原基址寄存器寄存器0x200r0r00x50x5源寄存器源寄存器for STRfor STR偏移量偏移量12120x20cr1r10x20c更新基址寄存器n Post-indexed: STR r0,[r1],#12(5).基址加偏址寻址 n偏移地址n ——可以是一个立即数,也可以是另一个寄存器,并且在加到基址寄存器前还可以经过移位操作,如下所示:nLDR r0,[r1,r2] ;r0<—mem32[r1+r2]nLDR r0,[r1,r2,LSL #2];r0<—mem32[r1+r2*4]n常用的是立即数偏移的形式5).基址加偏址寻址 多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。

多寄存器寻址指令举例如下:多寄存器寻址指令举例如下: LDMIAR1!,{R2-R7,R12} ;将R1指向的单元中的数据读出到 ;R2~R7、R12中(R1自动加1) STMIAR0!,{R2-R7,R12} ;将寄存器R2~R7、R12的值保 ;存到R0指向的存储; 单元中 ;(R0自动加1) 使用多寄存器寻址指令时,寄存器子集的顺序是按由小到大的顺序排列,连续的寄存器可用“-”连接;否则用“,”分隔书写6).多寄存器寻址0x40000000R1R20x??0x010x400000000x??R3R40x??R60x??0x020x030x040x400000040x400000080x4000000C存储器LDMIA R1!,{R2-R4,R6} LDMIA R1!,{R2-R4,R6} 0x400000100x010x020x030x04 相对寻址是基址寻址的一种变通由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址 相对寻址指令举例如下:相对寻址指令举例如下:BL BL SUBRlSUBRl ;调用到SUBRl子程序. . .SUBR1…SUBR1…MOV PC,R14MOV PC,R14 ;返回(7). 相对寻址 堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出” 。

堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶存储器堆栈可分为两种:存储器堆栈可分为两种: §向上生长向上生长::向高地址方向生长,称为递增堆栈§向下生长向下生长::向低地址方向生长,称为递减堆栈(8).堆栈寻址 (8).堆栈寻址栈底栈顶栈区SPSP堆栈存储区栈顶栈底栈区SPSP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈 栈顶SPSP栈顶SPSP栈底空堆栈栈底满堆栈 堆栈指针指向最后压入的堆栈的有效数据项,称为满满堆堆栈栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈空堆栈 (8).堆栈寻址0x123456780x12345678栈顶SPSP0x12345678栈顶SPSP压栈压栈 所以可以组合出四种类型的堆栈方式:§满满递递增增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址指令如LDMFA、STMFA等; §空空递递增增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置指令如LDMEA、STMEA等; §满满递递减减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。

指令如LDMFD、STMFD等;§空空递递减减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置指令如LDMED、STMED等 (8).堆栈寻址 多寄存器传送指令用于将一块数据从存储器的某一位置拷贝到另一位置 如:STMIASTMIAR0!,{R1-R7}R0!,{R1-R7};将R1~R7的数据保存到存储器R0中存储指针在保存第一个值之后增加,;增长方向为向上增长STMIBSTMIBR0!,{R1-R7}R0!,{R1-R7};将R1~R7的数据保存到存储器R0中存储指针在保存第一个值之前增加,;增长方向为向上增长 (9).块拷贝寻址 n4 种寻址操作: LDMIALDMIA / / STMIASTMIAI Increment A After(先传送,后地址加4) LDMIB / STMIBLDMIB / STMIBI Increment B Before(先地址加4 ,后传送) LDMDA / STMDALDMDA / STMDAD Decrement A After (先传送,后地址减4) LDMDB / STMDBLDMDB / STMDBD Decrement B Before (先地址减4,后传送)例:例:STMxxSTMxx r1, {r5 r1, {r5--r7}r7} 增加 之前STMIBSTMFALDMIBLDMED 之后STMIASTMEALDMIALDMFD 减少 之前LDMDBLDMEASTMDBSTMFD 之后LDMDALDMFASTMDASTMED 向上生长 向下生长 满 空 满 空 增长的方向增长的先后多寄存器传送指令映射 (3). ARM存储器访问指令 ARM处理器是典型的RISC处理器,对存储器的访问只能使用加载和存储指令实现。

ARM处理器是冯•诺依曼存储结构,程序空间、RAM空间及I/O映射空间统一编址,除对RAM操作以外,对外围IO、程序数据的访问均要通过加载/存储指令进行 存储器访问指令分为单单寄寄存存器器操操作作指指令令和多寄存器操作指令寄存器操作指令 助记符说明操作条件码位置LDR Rd,addressing 加载字数据Rd←[addressing],addressing索引LDR{cond}LDRB Rd,addressing 加载无符号字节数据Rd←[addressing],addressing索引LDR{cond}BLDRT Rd,addressing以用户模式加载字数据Rd←[addressing],addressing索引LDR{cond}TLDRBT Rd, addressing 以用户模式加载无符号字节数据Rd←[addressing],addressing索引LDR{cond}BTLDRH Rd, addressing 加载无符号半字数据Rd←[addressing],addressing索引LDR{cond}HLDRSB Rd, addressing 加载有符号字节数据Rd←[addressing],addressing索引LDR{cond}SBLDRSH Rd, addressing加载有符号半字数据 Rd←[addressing],addressing索引 LDR{cond}SH (3). ARM存储器访问指令:单寄存器加载单寄存器加载 助记符说明操作条件码位置STR Rd, addressing 存储字数据[addressing]←Rd,addressing索引STR{cond}STRB Rd,addressing 存储字节数据[addressing]←Rd,addressing索引STR{cond}BSTRT Rd,addressing 以用户模式存储字数据[addressing]←Rd, addressing索引STR{cond}TSTRBT Rd,addressing 以用户模式存储字节数据[addressing]←Rd,addressing索引STR{cond}BTSTRH Rd,addressing 存储半字数据[addressing] ←Rd,addressing索引STR{cond}H(3). ARM存储器访问指令:单寄存器存储单寄存器存储 LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等。

若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转 说明:说明: 所有单寄存器加载/存储指令可分为“字和无符号字节加载存储指令字和无符号字节加载存储指令” “半字和有符号字节加载存储指令半字和有符号字节加载存储指令 •LDR和STR——字和无符号字节加载/存储指令 LDR指令用于从内存中读取单一字或字节数据存入寄存器中,STR指令用于将寄存器中的单一字或字节数据保存到内存指令格式如下:(3). ARM存储器访问指令:单寄存器存储单寄存器存储 LDR{cond}{TLDR{cond}{T} } Rd,< Rd,<地址地址> > ;将指定地址上的字数据读入Rd STR{cond}{TSTR{cond}{T} } Rd,< Rd,<地址地址> > ;将Rd中的字数据存入指定地址 LDR{cond}B{TLDR{cond}B{T} Rd,<} Rd,<地址地址> > ;将指定地址上的字节数据读入Rd STR{cond}B{TSTR{cond}B{T} Rd,<} Rd,<地址地址> > ;将Rd中的字节数据存入指定地址注意:注意:T为可选后缀。

若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看成是在用户模式下进行的T在用户模式下无效 (3). ARM存储器访问指令:单寄存器存储单寄存器存储•LDR和STR——字和无符号字节加载/存储指令编码指令执行的条件码I为0时,偏移量为12位立即数,为1时,偏移量为寄存器移位P表示前/后变址U表示加/减B为1表示字节访问,为0表示字访问W表示回写为指令的寻址方式Rd为源/目标寄存器Rn为基址寄存器L用于区别加载(L为1)或存储(L为0) (3). ARM存储器访问指令:单寄存器存储单寄存器存储•LDR和STR——字和无符号字节加载/存储指令 LDR/STR指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量地址偏移量有以下3种格式: §立立即即数数::立即数可以是一个无符号的数值这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值 §寄寄存存器器::寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值 §寄寄存存器器及及移移位位常常数数::寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

指令举例如下:指令举例如下:指令举例如下:指令举例如下:LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,#0x12] #0x12] #0x12] #0x12] ;将;将;将;将R0+0x12R0+0x12R0+0x12R0+0x12地地地地址处的数据读出,保存到址处的数据读出,保存到址处的数据读出,保存到址处的数据读出,保存到RlRlRlRl中中中中(R0(R0(R0(R0的值不变的值不变的值不变的值不变) ) ) )LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,# -0x12] # -0x12] # -0x12] # -0x12] ;将;将;将;将R0-0x12R0-0x12R0-0x12R0-0x12地地地地址处的数据读出,保存到址处的数据读出,保存到址处的数据读出,保存到址处的数据读出,保存到R1R1R1R1中中中中(R0(R0(R0(R0的值不变的值不变的值不变的值不变) ) ) ) 指令举例如下:指令举例如下:指令举例如下:指令举例如下:LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,R2] R2] R2] R2] ;将;将;将;将R0+R2R0+R2R0+R2R0+R2地址处的数地址处的数地址处的数地址处的数据读出,保存到据读出,保存到据读出,保存到据读出,保存到R1R1R1R1中中中中LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,-R2] -R2] -R2] -R2] ;将;将;将;将R0-R2R0-R2R0-R2R0-R2地址处的数地址处的数地址处的数地址处的数据读出,保存到据读出,保存到据读出,保存到据读出,保存到R1R1R1R1中中中中指令举例如下:指令举例如下:指令举例如下:指令举例如下:LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,R2R2R2R2,,,,LSL #2]LSL #2]LSL #2]LSL #2];将;将;将;将R0+R2×4R0+R2×4R0+R2×4R0+R2×4地址处的数据读出,保存到地址处的数据读出,保存到地址处的数据读出,保存到地址处的数据读出,保存到R1R1R1R1中中中中(R0(R0(R0(R0、、、、R2R2R2R2的值不变的值不变的值不变的值不变) ) ) )LDR R1LDR R1LDR R1LDR R1,,,,[R0[R0[R0[R0,,,,-R2-R2-R2-R2,,,,LSL #2]LSL #2]LSL #2]LSL #2];将;将;将;将R0-R2×4R0-R2×4R0-R2×4R0-R2×4地址处的数据读出,保存到地址处的数据读出,保存到地址处的数据读出,保存到地址处的数据读出,保存到R1R1R1R1中中中中(R0(R0(R0(R0、、、、R2R2R2R2的值不的值不的值不的值不变变变变) ) ) ) (3). ARM存储器访问指令:单寄存器存储单寄存器存储 从寻址方式的地址计算方法分,加载/存储指令有以下4种格式: §零偏移零偏移:如:LDR Rd,[Rn] §前变址偏移前变址偏移:如:LDR Rd,[Rn,#0x04]! LDR Rd,[Rn,# -0x04]§程序相对偏移程序相对偏移:如:LDR Rd,labe1 §后变址偏移后变址偏移:如:LDR Rd,[Rn],#0x04•LDR和STR——字和无符号字节加载/存储指令注意:注意: 大大多多数数情情况况下下,,必必须须保保证证字字数数据据操操作作的的地地址址是是3232位对齐的。

位对齐的 •LDR和STR——半字和有符号字节加载/存储指令 这类LDR/STR指令可加载有符号半字或字节,可加载/存储无符号半字偏移量格式、寻址方式与加载/存储字和无符号字节指令相同 注意:注意: 1.有符号位半字/字节加载是指用符号位加载扩展到32位,无符号 半字加载是指用零扩展到32位;3.地址对齐——半字读写的指定地址必须为偶数,否则将产生不可 靠的结果3). ARM存储器访问指令:单寄存器存储单寄存器存储 LDR{cond}SB Rd,<地址> ;将指定地址上的有符号字节读入Rd LDR{cond}SH Rd,<地址> ;将指定地址上的有符号半字读入Rd LDR{cond}H Rd,<地址> ;将指定地址上的半字数据读入Rd STR{cond}H Rd,<地址> ;将Rd中的半字数据存入指定地址 (3). ARM存储器访问指令:单寄存器存储单寄存器存储•LDR和STR——半字和有符号字节加载/存储指令编码 举例如下举例如下::LDRSB R1,[R0,R3] ;将R0+R3地址上的字节数据读到R1,高24位 ;用符号位扩展LDRSH R1,[R9] ;将R9地址上的半字数据读出到R1,高16位用符号 ; 位扩展LDRH R6,[R2],#2;将R2地址上的半字数据读出到R6,高16位用零扩 ; 展,R2=R2+2STRH R1,[R0,#2]! ;将R1的数据保存到R0+2地址中,只存储低2 ;字节数据,R0=R0+2 说明:说明: LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等等。

若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转 (3). ARM存储器访问指令: LDM和STM指令可以实现在一组寄存器和一块连续的内存单元之间传输数据 LDM为加载多个寄存器; STM为存储多个寄存器 允许一条指令传送1616个寄存器的任何子集或所有寄存器 指令格式如下: LDM{condLDM{cond}<}<模式模式> > Rn{!},reglistRn{!},reglist{^} {^} STM{condSTM{cond}<}<模式模式> > Rn{!},reglistRn{!},reglist{^}{^}多寄存器存取多寄存器存取LDM和STM的主要用途主要用途是现场保护、数据复制、常数传递等 (3). ARM存储器访问指令:多寄存器存取多寄存器存取 多寄存器加载/存储指令的8种模式如下表所示,右边四种为堆栈操作、左边四种为数据传送操作模式说明模式说明IA每次传送后地址加4FD满递减堆栈IB每次传送前地址加4ED空递减堆栈DA每次传送后地址减4FA满递增堆栈DB每次传送前地址减4EA空递增堆栈数据块传送操作堆栈操作 进行数据复制时,先设置好源数据指针和目标指针,然后使用 块 拷 贝 寻 址 指 令 LDMIA/STMIA、 LDMIB/STMIB、 LDMDA/STMDA、LDMDB/STMDB进行读取和存储 。

进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆 栈 寻 址 指 令 STMFD/LDMFD 、 STMED/LDMED、 STMFA/LDMFA和STMEA/LDMEA实现堆栈操作 Ø 指令格式中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15Ø 后缀“!”表示最后的地址写回到Rn中Ø寄存器列表reglist可包含多于一个寄存器或包含寄存器范围,使用“,”分开,如{R1,R2,R6~R9},寄存器按由小到大排列Ø 后缀“^”不允许在用户模式或系统模式下使用若在LDM指令且寄存器列表中包含有PC时使用,那么除了正常的多寄存器传送外,将SPSR也拷贝到CPSR中,这可用于异常处理返回Ø 使用后缀“^”进行数据传送且寄存器列表不包含PC时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器 ØØ 当Rn在寄存器列表中且使用后缀“!”时,对于STM指令,若Rn为寄存器列表中的最低数字的寄存器,则会将Rn的初值保存;其它情况下Rn的加载值和存储值不可预知。

Ø 地址对齐—这些指令忽略地址位[1:0] 举例如下:举例如下: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} ;恢复现场,异常处理返回 (3). ARM存储器访问指令: SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中使用SWP可实现信号量操作 指令格式如下:SWP{cond}{BSWP{cond}{B} } Rd,Rm,[RnRd,Rm,[Rn] ] 其中,B B为可选后缀,若有B,则交换字节,否则交换32位字;RdRd用于保存从存储器中读入的数据;RmRm的数据用于存储到存储器中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。

SWPSWP指令应用示例:指令应用示例:SWPSWPR1,R1,[R0]R1,R1,[R0];将R1的内容与R0指向的存储单元的内容进行交换 SWPBSWPBR1,R2,[R0R1,R2,[R0];将R0指向的存储单元内的容读取一字节数据到R1中;(高24位清零),并将R2的内容写入到该内存单元中;(最低字节有效) 寄存器和存储器交换指令寄存器和存储器交换指令 ARM指令的基本格式如下:(1).指令格式< {<> {} {S} ,<>} {S} ,{,} >{,} 其中<>号内的项是必须的,{}号内的项是可选的各项的说明如下:opcodeopcode:指令助记符;condcond:执行条件;S S:是否影响CPSR寄存器的值;RdRd:目标寄存器; RnRn:第1个操作数的寄存器;operand2operand2:第2个操作数;ARM指令集合 ØLDR R0,[R1] ;读取R1地址上的存储器单元内容,执行条件为ALØBEQ D1   ;分支指令,执行条件EQ,即相等则跳转到D1ØADDS R1,R1,#1 ;加法指令,R1+1=>R1,影响CPSR;寄存器(S)指令格式举例如下:指令格式举例如下: (1).指令格式: 灵活的使用第2个操作数“operand2operand2”能够提高代码效率。

它有如下的形式:§#immed_8r#immed_8r——常数表达式;§RmRm——寄存器方式;§Rm,shiftRm,shift——寄存器移位方式;第第2 2个操作数个操作数 (1).指令格式:第第2 2个操作数个操作数§#immed_8r——常数表达式 该常数必须对应8位位图,即一个8 8位位的的常常数数通过循环右移偶数位通过循环右移偶数位得到循环右移10位0x120 0 0 1 0 0 1 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x000 0 0 0 0 0 0 00x801 0 0 0 0 0 0 00x040 0 0 0 0 1 0 08位常数 (1).指令格式:第第2 2个操作数个操作数§Rm——寄存器方式 在寄存器方式下,操作数即为寄存器的数值寄存器方式应用举例:SUB R1,R1,R2 ;R1-R2→R1MOV PC,R0 ;PC=R0,程序跳转到指定地址LDR R0,[R1],-R2 ;Rl所指存储器单元 内容存人R0,且R1 = R1 - R2 (1).指令格式:第第2 2个操作数个操作数§Rm,shift——寄存器移位方式 将寄存器的移位结果作为操作数,但Rm值保持不变,移位方法如下:操作码说明操作码说明ASR #n算术右移n位ROR #n循环右移n位LSL #n逻辑左移n位RRX带扩展的循环右移1位LSR #n逻辑右移n位Type RsType为移位的一种类型,Rs为偏移量寄存器,低8位有效。

ARM指令的基本格式如下:(2).条件码< {<> {} {S} ,<>} {S} ,{,<>{,} >} 使用条件码“condcond”可以实现高效的逻辑操作,提高代码效率 所有的ARM指令都可以条件执行,而Thumb指令只有B(跳转)指令具有条件执行功能如果指令不标明条件代码,将默认为无条件(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任何无条件执行 (指令默认条件) 1111NV任何从不执行(不要使用) •指令条件码表 2、ARM指令详解q数据处理指令;qLoad/Store指令;q程序状态寄存器处理指令;q跳转指令;q异常中断产生指令;q协处理器指令。

n一、数据处理指令一、数据处理指令nARM的数据处理指令主要完成寄存器中数据的算术和逻辑运算操作nARM数据处理指令的特点:q所有的操作数要么来自寄存器,要么来自立即数,不会来自存储器q如果有结果,则结果一定是为32位宽,并且放在一个寄存器中,不会写入存储器有一个例外:长乘法指令产生64位结果)q每一个操作数寄存器和结果寄存器都在指令中独立指出,即:ARM指令采用3地址模式: Rd, Rn, Rm nARM数据处理指令大致可分为6类:q算术运算指令: ADDADD ADC ADC SUB SUB SBC SBC RSB RSB RSC RSCq逻辑运算指令: ANDAND ORR EOR ORR EOR BIC BICq数据传送指令: MOVMOV MVN MVNq比较指令: CMP CMNCMP CMNq测试指令: TST TEQTST TEQq乘法指令:MUL MLA UMULL UMLAL SMULL SMLALMUL MLA UMULL UMLAL SMULL SMLALq上述指令只能对寄存器操作,不能针对存储器。

n后缀后缀s sn数据处理指令可以选择s后缀,以影响状态标志但是比较指令(cmp、cmn、tst和teq)不需要后缀s,它们总会直接影响cpsr中的状态标志n在数据处理指令中,除了比较指令以外,其它的指令如果带有s后缀,同时又以pc为目标寄存器进行操作,则操作的同时从spsr恢复cpsr比如:qmovs pc, #0xff/* cpsr = spsr; pc = 0xff */qadds pc, r1, #0xffffff00 /* cpsr = spsr; pc = r1 + 0xffffff00 */qands pc, r1, r2/* cpsr = spsr; pc = r1 & r2; */n如果在user或者system模式下使用带有s后缀的数据处理指令,同时以pc为目标寄存器,那么会产生不可预料的结果因为user和system模式下没有spsr n当选择后缀S时:q如果结果为负,则N标志位置1;否则清0q如果结果为0,则Z标志位置1;否则清0q如果是算术运算指令或比较指令时,C标志位设置为ALU的进位输出;否则设置为移位器的进位输出如果不需要移位,则C保持不变q在非算术操作中,V标志位保持原值。

在算术操作中,如果有溢出,则置1;不发生溢出,则清0 结果结果操作数操作数1BarrelShifter操作数操作数2ALU n数据处理指令的二进制编码如下:add r0, r1, #0xffadd r0, r1, r1, LSL r2add r0, r1, r1, LSL #31 n数据处理指令的详细列表如下:操作码[24:21]助记符意义效果0000AND逻辑位与Rd = Rn AND Op20001EOR逻辑位异或Rd = Rn EOR Op20010SUB减Rd = Rn - Op20011RSB反向减Rd = Op2 – Rn0100ADD加Rd = Rn + Op20101ADC带进位加Rd = Rn + Op2 + C0110SBC带进位减Rd = Rn - Op2 + C -10111RSC反向带进位减Rd = Op2 - Rn + C -11000TST测试根据Rn AND Op2设置条件码1001TEQ测试相等根据Rn EOR Op2设置条件1010CMP比较根据Rn - Op2设置条件码1011CMN负数比较根据Rn + Op2设置条件码1100ORR逻辑位或Rd = Rn OR Op21101MOV传送Rd = Op21110BIC位清零Rd = Rn AND NOT Op21111MVN求反Rd = NOT Op2 n算术运算指令:① ① ADD——加法运算指令   ADD指令将operand2的数据与Rn的值相加,结果保存到Rd寄存器。

   指令格式如下:  ADD{cond}{SADD{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:ADDS R1,R1,#1       ;R1=R1+1ADDS R3,R1,R2,LSL #2  ; R3=R1+R2<<2 ②② ADC——带进位加法指令  ADC指令将operand2的数据与Rn的值相加,再加上CPSR中的C条件标志位,结果保存到Rd寄存器指令格式如下:ADC{cond}{SADC{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下: ADDS R4,R0,R2 ;使用ADC实现64位加法,ADC R5,R1,R3 ;(R5、R4)=(R1、R0)+(R3、R2) ③③ SUBSUB————减法运算指令减法运算指令 SUB指令用寄存器Rn减去operand2,结果保存到Rd中 指令格式如下:SUB{cond}{SSUB{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:SUBS R0,R0,#l ;R0=R0-1SUB R6,R7,#0x10 ;R6=R7-0x10 ④④SBC——带进位减法指令 SBC指令用寄存器Rn减去operand2,再减去CPSR中的C条件标志位的反码,结果保存到Rd中。

指令格式如下:SBC{cond}{SSBC{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:SUBS R4,R0,R2 ;使用SBC实现64位减法,SBC R5,R1,R3 ;(R5,R4)=(R1,R0)-(R3,R2) ⑤ ⑤ RSBRSB————反向减法指令反向减法指令 RSB指令用寄存器operand2减去Rn,结果保存到Rd中 指令格式如下:RSB{cond}{SRSB{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:RSB R3,R1,#0xFF00 ;R3=0xFF00-R1RSBS R1,R2,R2,LSL #2 ;R1R2<<2-R2 ;(R1 =R2×3) n⑥ ⑥ RSCRSC——带进位反向减法指令nRSC 指令用寄存器operand2减去Rn,再减去CPSR中的C条件标志位的反码,结果保存到Rd中n指令格式如下:nRSC{cond}{SRSC{cond}{S} Rd} Rd,,RnRn,,operand2operand2n指令举例如下:nRSBS R2,R0,#0nRSC R3,R1,#0 ;使用RSC指令实现 ;求64位数值的负数 n逻辑运算指令:①①AND——逻辑“与”操作指令AND指令将operand2的值与寄存器Rn的值按位逻辑“与”操作,结果保存到Rd中。

指令格式如下:AND{cond}{SAND{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:ANDS R0,R0,#0x01 ;R0=R0&0x01 ;取出最低位数据AND R2,R1,R3 ;R2=R1&R3 AND指令可用于提取寄存器中某些位的值 ②② ORR——逻辑“或”操作指令ORR指令将operand2的值与寄存器Rn的值按位逻辑“或”操作,结果保存到Rd中指令格式如下: ORR{cond}{SORR{cond}{S} Rd} Rd,,RnRn,,operand2 operand2 指令举例如下: ORR R0,R0,#0x0F ;将R0的低4位置1 ORR指令用于将寄存器中某些位的值设置成1 ③③ EOR——逻辑“异或”操作指令 EOR指令将operand2的值与寄存器Rn的值按位逻辑“异或”操作,结果保存到Rd中指令格式如下:EOR{cond}{SEOR{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下: EOR R1,R1,#0x0F ;将Rl的低4位取反 EORS R0,R5,#0x01 ;将R0R5异或0x01, ;并影响标志位 EOR指令可用于将寄存器中某些位的值取反。

将某一位与0异或,该位值不变;与1异或,该位值被求反 ④④BIC——位清除指令BIC指令将寄存器Rn的值与operand2的值的反码按位逻辑“与”操作,结果保存到Rd中指令格式如下:BIC{cond}{SBIC{cond}{S} Rd} Rd,,RnRn,,operand2operand2指令举例如下:BIC R1,R1,#0x0F ;将R1的低4位清0, ;其它位不变 BIC指令可用于将寄存器中某些位的值设置成0将某一位与1做BIC操作,该位值被设置成0;将某一位与0做BIC操作,该位值不变 n数据传送指令:① ① MOVMOV————数据传送指令数据传送指令MOV指令将operand2传送到目标寄存器Rd中指令格式如下:MOV{cond}{SMOV{cond}{S} Rd} Rd,,operand2operand2指令举例如下:MOVS R3,R1,LSL #2 ;R3=R1<<2 ;影响标志位MOV PC,LR ;PCLR,子程序返回 nMOV指令可以完成以下功能:q将数据从一个寄存器传送到另一个寄存器中。

q将一个常数传送到一个寄存器中q实现单纯的移位操作q当PC寄存器作为目标寄存器时可以实现程序跳转这种跳转可以实现子程序调用以及从子程序中返回 q当PC寄存器作为目标寄存器且指令中S位被设置时,指令在执行跳转操作的同时,将当前处理器模式的SPSR寄存器内容复制到CPSR中这样可以实现从某些异常中断中返回 n② ② MVNMVN————求反指令求反指令MVN指令将operand2按位取反后传送到目标寄存器Rd中指令格式如下:MVN{cond}{SMVN{cond}{S} Rd} Rd,,operand2operand2指令举例如下:MVN R1,#0xFFMVN R2 ,R1 n比较指令:① ① CMP——比较指令 CMP指令将寄存器Rn的值减去operand2的值,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行指令格式如下:CMP{condCMP{cond} } RnRn,,operand2operand2指令举例如下:CMP R1,#10 ;R1与10比较,设置相关标志位 CMP指令与SUBS指令的区别? n②CMN——负数比较指令nCMN指令将寄存器Rn的值加上operand2的值,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。

n指令格式如下:nCMN{condCMN{cond} } RnRn,,operand2operand2n指令举例如下:nCMN R0,#1 ;R0+1,判断R0是否为1的补码 ;若是,则Z位置1nCMN指令与ADDS指令的区别在于CMN指令不保存运算结果CMN指令可用于负数比较,比如“CMN R0,#1”指令则表示R0与-1比较若R0为-1(即1的补码),则Z置位;否则Z复位 n测试指令:n①① TST——位测试指令 TST指令将寄存器Rn的值与operand2的值按位逻辑“与”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行 指令格式如下:TST{condTST{cond} } RnRn,,operand2operand2 指令举例如下: TST R0,#0x01 ;判断R0的最低位是否为0 TST R1,#0x0F ;判断R1的低4位是否为0TST指令与ANDS指令的区别在于TST指令不保存运算结果。

TST指令通常与EQ、NE条件码配合使用当所有测试位均为0时,EQ有效而只要有一个测试位不为0,则NE有效 n②② TEQ——测试相等指令 TEQ指令将寄存器Rn的值与operand2的值按位逻辑“异或”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行 指令格式如下:TEQ{condTEQ{cond} } RnRn,,operand2operand2 指令举例如下:TEQ R0,R1 ;比较R0与R1是否相等 ;(不影响V位和C位) TEQ指令与EORS指令的区别在于TEQ指令不保存运算结果使用TEQ进行相等测试时,常与EQ、NE条件码配合使用当两个数据相等时,EQ有效;否则NE有效 n乘法指令乘法指令nARM有两类乘法指令:q32位的乘法指令,即乘法操作的结果为32位;q64位的乘法指令,即乘法操作的结果为64位 n①① MUL——32位乘法指令 MUL指令将Rm和Rs中的值相乘,结果的低32位保存到Rd中指令格式如下:MUL{cond}{S} Rd,Rm,Rs ;RdRm*Rs指令举例如下:MUL R1,R2,R3 ;R1=R2×R3MULS R0,R3,R7 ;R0=R3×R7, ;设置CPSR的N位和Z位 n②② MLA——32位乘加指令 MLA指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的低32位保存到Rd中。

指令格式如下: MLA{cond}{S} Rd,Rm,Rs,Rn ; RdRm*Rs+Rn 指令举例如下: MLA R1,R2,R3,R0 ;R1=R2×R3+R0 n③③ UMULL—64位无符号乘法指令 UMULL指令将Rm和Rs中的值作无符号数相乘,结果的低32位保存到RdLo中,高32位保存到RdHi中指令格式如下: UMULL{cond}{S} RdLo,RdHi,Rm,Rs ; RdHi, RdLo Rm*Rs指令举例如下: UMULL R0,R1,R5,R8 ;(R1,R0)R5×R8 n④④ UMLAL—64位无符号乘加指令 UMLAL指令将Rm和Rs中的值作无符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中 指令格式如下: UMLAL{cond}{S} RdLo,RdHi,Rm,Rs ;RdHi, RdLo Rm*Rs+ RdHi, RdLo指令举例如下: UMLAL R0,R1,R5,R8 ;(R1,R0)R5×R8+(R1,R0) n⑤ ⑤ SMULL—64位有符号乘法指令 SMULL指令将Rm和Rs中的值作有符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。

指令格式如下:SMULL{cond}{S} RdLo,RdHi,Rm,Rs ; RdHi, RdLo Rm*Rs指令举例如下: SMULL R2,R3,R7,R6 ;(R3,R2)R7×R6 n⑥⑥ SMLAL—64位有符号乘加指令 SMLAL指令将Rm和Rs中的值作有符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,高32位保存到RdHi中 指令格式如下:SMLAL{cond}{S} RdLo,RdHi,Rm,Rs ; RdHi, RdLo Rm*Rs+ RdHi, RdLo指令举例如下:SMLAL R2,R3,R7,R6 ; ;(R3,R2)R7×R6+(R3,R2) n乘法指令的特点:q不支持第2操作数为立即数q结果寄存器不能与第一源寄存器相同nRd、RdHi、RdLo不能与Rm为同一寄存器nRdHi和RdLo不能为同一寄存器。

q避免将R15定义为任一操作数或结果寄存器q早期的ARM处理器仅支持32位乘法指令ARM7版本和后续的在名字中有M的处理器才支持64位乘法指令 n当在乘法指令中设置了位S时,则:q对于产生32位结果的指令形式,将标志位N设置为Rd的第31位的值;对于产生长结果的指令形式,将其设置为RdHi的第31位的值q如果Rd或RdHi、RdLo为0,则标志位Z置位q乘法指令不影响V标志位qARM v5及以上的版本不影响C标志位; ARM v5以前的版本,C标志位数值不确定 n二、二、 Load/StoreLoad/Store指令指令 ——加载/存储指令n 对于存储器的读/写只能用此类指令n 因为ARM处理器对外设寄存器、I/O映射空间与存储器统一编址,对外围设备的I/O操作也用此类指令n共有三种加载/存储指令:q单寄存器的存取指令(LDR,STR)q多寄存器存取指令(LDM,STM)q单寄存器交换指令(SWP) 1 1、单寄存器的存取指令、单寄存器的存取指令 n 单寄存器加载/存储指令是ARM在寄存器和存储器间传送单个字节和字的最灵活方式。

根据传送数据的类型不同,单个寄存器存取指令又可以分为以下两类:q单字和无符号字节的加载/存储指令q半字和有符号字节的加载/存储指令 n((1 1)单字和无符号字节的加载/存储指令)单字和无符号字节的加载/存储指令nLDR指令从内存中取32位字或8位无符号字节数据放入寄存器;nSTR指令将寄存器中的32位字或8位无符号字节数据保存到存储器中n注意:q字节传送时用0将8位的操作数扩展到32位 n指令格式如下: LDR{cond}{TLDR{cond}{T} Rd} Rd,,< <地址地址> > ;加载指定地址上的字数据,放入Rd中 STR{cond}{TSTR{cond}{T} Rd} Rd,,< <地址地址> > ;存储Rd中字数据,到指定地址的存储单元 LDR{cond}B{TLDR{cond}B{T} Rd} Rd,,< <地址地址> > ;加载字节数据到Rd中, Rd最低字节有效,高24位为0 STR{cond}B{TSTR{cond}B{T} Rd} Rd,,< <地址地址> > ;存储Rd中字节数据, Rd中最低字节为传送数据。

nT后缀qT为可选后缀,若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看成是处理器是在用户模式下q用于存储器保护q不能与前变址模式、自动变址模式一起使用qT在用户模式下无效 n指令寻址方式: qLDR/STR指令寻址非常灵活,由两部分组成:n一部分为一个基址寄存器,可以为任一个通用寄存器;n另一部分为一个地址偏移量q地址偏移量有以下3种格式:n立即数n寄存器n寄存器及移位常数 n①立即数n——12位立即数可以是一个无符号的数值这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值n指令举例如下:nLDR R1,[R0,#0x12] ;将R0+0x12地址处的数据读出,保存到R1中(R0的值不变)nLDR R1,[R0,# -0x12] ;将R0-0x12地址处的数据读出,保存到R1中(R0的值不变) n②寄存器n——寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值指令举例如下:nLDR R1LDR R1,,[R0[R0,,R2]R2] ;将R0+R2地址处的数据读出,保存到R1中nLDR R1LDR R1,,[R0[R0,,-R2]-R2] ;将R0-R2地址处的数据读出,保存到R1中 n③寄存器及移位常数n——寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

n指令举例如下:nLDR R1,[R0,R2,LSL #2] ;将R0+R2×4地址处的数据读出,保存到R1中(R0、R2的值不变)nLDR R1,[R0,-R2,LSL #2] ;将R0-R2×4地址处的数据读出,保存到R1中(R0、R2的值不变) 注意:移位位数只能是5位的立即数,不能使用寄存器指定移位位数 nPC的使用:q使用PC作为基址时,使用的数值是指令的地址加8个字节qPC不能用做偏移寄存器,也不能用于任何变址寻址模式q把一个字加载到PC将使程序转移到所加载的地址,这是一个公认的实现跳转的方法应当避免将一个字节加载到PCq把PC存到存储器的操作在不同体系结构的处理器中产生不同的结果,应尽可能避免 n((2 2)半字和有符号字节的加载/存储指令)半字和有符号字节的加载/存储指令n这类LDR/STR指令可实现半字(有符号和无符号)、有符号字节数据的传送n特点:q偏移量格式、寻址方式与加载/存储字和无符号字节指令基本相同q立即数偏移量限定在8位,寄存器偏移量不可经过移位得到 n指令格式如下:指令格式如下:n LDR {LDR {cond}Hcond}H Rd Rd,,< <地址地址> > ;;加载无符号半字数据到Rd的低16位,高16位清零。

n LDR {LDR {cond}SBcond}SB Rd Rd,,< <地址地址> > ;加载指定地址上有符号字节到Rd中,高24位用符号位扩展nLDR {LDR {cond}SHcond}SH Rd Rd,,< <地址地址> > ;加载指定地址上的有符号半字到Rd中,高16位用符号位扩展n STR{cond}HSTR{cond}H Rd Rd,,< <地址地址> > ;;存储Rd中的低16位半字数据 存储有符号数据和无符号数据之间没有差别 n说明:q有符号位字节或有符号半字的传送是用“符号位”扩展到32位;无符号半字传送是用0扩展到32位q地址对齐——对半字传送的地址必须为偶数非半字对齐的半字加载将使Rd内容不可靠;非半字对齐的半字存储将使指定地址的2字节存储内容不可靠 n指令举例:nLDRSB R1,[R0,R3] ;将R0+R3地址上的字节数据读到R1,高24位用符号位扩展nLDRSH R1,[R9] ;将R9地址上的半字数据读出到R1,高16位用符号位扩展nLDRH R6,[R2],#2 ;将R2地址上的半字数据读出到R6,高16位用零扩展,R2=R2+2nSTRH R1,[Ro,#2]! ;将R1的数据保存到R0+2地址中,只存储低2字节数据,R0=R0+2 3. 3. 多寄存器的多寄存器的存取指令指令n LDM和STM指令可以实现在一组寄存器和一块连续的内存单元之间存/取数据。

LDM为加载多个寄存器;STM为存储多个寄存器允许一条指令传送16个寄存器的任何子集或所有寄存器n指令格式如下:nLDM{condLDM{cond}<}<模式模式> > RnRn{!}{!},,< {^}>{^}n STM{condSTM{cond}<}<模式模式> > RnRn{!}{!},,< {^}>{^} n指令格式中,指令格式中,q寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15q后缀“!”表示最后的地址写回到Rn中q寄存器列表reglist可包含多个寄存器或包含寄存器的范围,使用“,”分开,如{R1,R2,R6~R9} 其中寄存器和存储器的对应关系满足规则:编号低的寄存器对应于存储器中低地址单元,编号高的寄存器对应于存储器中高地址单元 n后缀“^ ^”q使用后缀“^”进行数据传送且寄存器列表不包含PC时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器q后缀“^”不允许在用户模式或系统模式下使用q若在LDM指令中使用后缀“^”且寄存器列表中包含有PC时,除了正常的多寄存器传送外,将SPSR也拷贝到CPSR中,此用法可用于异常处理返回。

n当Rn在寄存器列表中且使用后缀“!”时:q对于STM指令,若Rn为寄存器列表中的最低数字的寄存器,则会将Rn的初值保存;q其它情况下Rn的加载值和存储值不可预知 nLDM/STM的主要用途是现场保护、数据复制和参数传送等其模式有如下8种(前面4种用于数据块的传输,后面4种是堆栈操作):qIA: 每次传送后地址加4;qIB: 每次传送前地址加4;qDA: 每次传送后地址减4;qDB: 每次传送前地址减4;qFD: 满递减堆栈;qED: 空递减堆栈;qFA: 满递增堆栈;qEA: 空递增堆栈 举例如下:nLDMIA R0!LDMIA R0!,,{R3 - R9}{R3 - R9} ;;加载R0指向地址上的多字数据,保存到R3~R9中,R0值更新nSTMIA R1!STMIA R1!,,{R3 - R9}{R3 - R9} ;;将R3~R9的数据存储到R1指向的地址上,R1值更新 nSTMFD SP!STMFD SP!,,{R0 - R7{R0 - R7,,LR}LR} ;现场保存,将R0~R7、LR入栈nLDMFD SP!LDMFD SP!,,{R0 - R7{R0 - R7,,PC} PC} ;;恢复现场,异常处理返回 3. 3. 单寄存器交换指令单寄存器交换指令(SWP) SWP指令用于将一个存储单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该存储单元中。

指令格式如下:nSWP{cond}{BSWP{cond}{B} Rd} Rd,,RmRm,,[ [RnRn] ]q其中,B为可选后缀,若有B,则交换字节,否则交换32位字;qRd为被加载的寄存器;Rm的数据用于存储到Rn所指的地址中若Rm与Rd相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同 n指令举例如下:n SWP R1SWP R1,,R1R1,,[R0][R0] ;将R1的内容与R0指向的存储单元的内容进行交换n SWPB R1SWPB R1,,R2R2,,[R0][R0] ;将R0指向的存储单元的内容读取1字节数据到R1中(高24位清零),并将R2的内容写入到该内存单元中(最低字节有效) 三、三、 程序状态寄存器处理指令程序状态寄存器处理指令n ARM指令中有两条指令,用于在状态寄存器和通用寄存器之间传送数据修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的 这两条指令分别是:› 状态寄存器到通用寄存器的传送指令(MRS)› 通用寄存器到状态寄存器的传送指令(MSR) nMRSMRS 在ARM处理器中,只有MRS指令可以将状态寄存器CPSR或SPSR读出到通用寄存器中。

指令格式如下:MRS{condMRS{cond} Rd} Rd,,psrpsr ;; Rd  psr 其中: Rd —— 目标寄存器Rd不允许为R15 psr —— CPSR或SPSR指令举例如下:MRS R1,CPSR ; R1 CPSRMRS R2,SPSR ; R2  SPSR n MRS指令读取CPSR,可用来判断ALU的状态标志,或IRQ、FIQ中断是否允许等n在异常处理程序中,读SPSR可知道进行异常前的处理器状态等nMRS与MSR配合使用,实现CPSR或SPSR寄存器的读—修改—写操作,可用来进行处理器模式切换、允许/禁止IRQ/FIQ中断等设置 nMSRMSR 在ARM处理器中,只有MSR指令可以直接设置状态寄存器CPSR或SPSR 指令格式如下:MSR{condMSR{cond} } psr_fieldspsr_fields,,# #immedimmedMSR{condMSR{cond} } psr_fieldspsr_fields,,RmRm 注:不可以使用S后缀。

其中: n psr: CPSR或SPSRn immed: 要传送到状态寄存器指定域的立即数n Rm: 要传送到状态寄存器指定域的数据的源寄 存器nfields 指定传送的区域fields可以是以下的一种或多种(字母必须为小写):q c 控制域 (psr[7…0]);q x 扩展域(psr[15…8]);(暂未用)q s 状态域 (psr[23…16]);(暂未用)q f 标志位域 (psr[31…24]) 程序状态寄存器2731N Z C V Q2867I F T mode162381554024fsxc U n d e f i n e dJ n指令举例如下:nMSR MSR CPSR_fCPSR_f,,#0xF0000000#0xF0000000 ; CPSR[31:28]=0xF(0b1111),即N,Z,C,V均被置1n修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的 CPSR的读—修改—写操作举例如下:n例1:设置进位位CnMRSR0, CPSR ;R0CPSRnORR R0,R0,#0X20000000 ;置1进位位CnMSRCPSR_f, R0 ;CPSRR0n例2:从管理模式切换到IRQ模式nMRS R0, CPSR ;R0CPSRnBIC R0,R0,#0X1F ;低5位清零nORR R0,R0,#0X12 ;设置为IRQ模式nMSR CPSR_c, R0 ;传送回CPSR n注意:只有在特权模式下才能修改状态寄存器的控制域[7:0],以实现处理器模式转换,或设置开/关异常中断 。

程序中不能通过MSR指令直接修改CPSR中的T控制位来实现ARM状态/Thumb状态的切换,必须使用BX指令完成处理器状态的切换用户模式下不能对CPSR[23:0]做修改 n例例nMRS R0MRS R0,,CPSRCPSRnBIC R0, R0, #0x1F ; R0后5位清0 nORR R0, R0, #0x1F ; R0后5位赋值为0b11111nMSR CPSR, R0 ;根据模式位[4 : 0]切换工作模式到系统模式nMOV R13, #1nMOV R14, #2nMRS R0MRS R0,,CPSRCPSR nBICR0, R0, #0x1F ; R0后5位清0nORR R0, R0, #0x11 ; R0后5位赋值为0b10001nMSR CPSR, R0 ;根据模式位[4 : 0]切换工作模式到FIQ模式nMOV R13, #33nMOV R14, #44nMRS R0MRS R0,,CPSRCPSR nBIC R0, R0, #0x1F ; R0后5位清0 nORR R0, R0, #0x10 ; R0后5位赋值为0b10000nMSR CPSR, R0 ;根据模式位[4 : 0]切换工作模式到用户模式 n四、四、 跳转指令跳转指令n在ARM中有两种方式可以实现程序的跳转:q一种是使用转移转移指令直接跳转;q另一种则是直接向PC寄存器赋值来实现跳转。

n ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转,根据完成的功能它可以分为以下4种 : B 转移指令 BL 带链接的转移指令 BX 带状态切换的转移指令 BLX 带链接和状态切换的转移指令 n①① B B————转移指令转移指令 B指令跳转到指定的地址执行程序 指令格式如下: B{condB{cond} label} label 指令举例如下: B WAITA ;跳转到WAITA标号处 B 0x1234 ;跳转到绝对地址0x1234处转移指令B限制在当前指令的±32 MB的范围内 n指令举例如下:n 无条件跳转: B label …… label ……n执行10次循环: MOV R0, #10 LOOP: …… SUBS R0, #1 BNE LOOP n② ② BLBL————带链接的转移指令带链接的转移指令 BL指令先将下一条指令的地址拷贝到LR 链接寄存器中,然后跳转到指定地址运行程序。

指令格式如下: BL{condBL{cond} label} label指令举例如下: BL SUB1 ;LR下条指令地址 ;转至子程序SUB1处 …SUB1 … MOV PC, LR注意:转移地址限制在当前指令的±32 MB的范围内BL指令用于子程序调用 n指令举例如下: CMP R1, #5 BLLT ADD11 ;< BLGE SUB22 ; ≧ …ADD11: …SUB22: … v注:如果R1<5,只有ADD11不改变条件码,本例才能正常工作 BL SUB1 ……SUB1 …… BL SUB2 ……SUB2 ……注:在保存R14之前子程序不应再调用下一级的嵌套子程序否则,新的返回地址将覆盖原来的返回地址,就无法返回到原来的调用位置。

STMFD R13!,{R0-R3,R14} n③③BXBX————带状态切换的转移指令带状态切换的转移指令n BX指令跳转到Rm指定的地址执行程序若Rm的位[0]为1,则跳转时自动将CPSR中的标志T置位,即把目标地址的代码解释为Thumb代码;若Rm的位[0]为0,则跳转时自动将CPSR中的标志T复位,即把目标地址的代码解释为ARM代码n指令格式如下: BX{condBX{cond} } RmRm ; ; RmRm::该寄存器中为跳转的目标地址当Rm寄存器的bit[0]为0时,目标地址处的指令为ARM指令;当bit[0]为1时,目标地址处的指令为Thumb指令 n指令举例如下: ADRL R0,ThumbFun+1 BX R0 ;跳转到R0指定的地址,并 根据R0的最低位来切换处 理器到Thumb状态ThumbFun: … n④ ④ BLXBLX —— ——带链接和状态切换的转移指令带链接和状态切换的转移指令n BLX指令先将下一条指令的地址拷贝到R14 (即LR)连接寄存器中,然后跳转到指定地址处执行程序。

目前只有V5T ARM 支持BLX)n指令格式如下: BLX BLX n转移地址限制在当前指令的±32 MB的范围内 五、五、 异常中断产生指令异常中断产生指令n异常中断指令可以分为以下几种:n 软件中断指令(SWI) n 断点指令(BKPT—仅用于v5T体系)n 前导0计数(CLZ—仅用于v5T体系) n① SWI——软件中断指令 软件中断指令SWI产生SWI异常中断,用来实现用户模式到特权模式的切换用于在用户模式下对操作系统中特权模式的程序的调用;它将处理器置于管理(_svc)模式,中断矢量地址为0x08汇编格式如下: SWI {}>} <24 <24位立即数位立即数> > n说明:q主要用于用户程序调用操作系统的APIq参数传递通常有两种方法:n指令中的24bit立即数指定API号,其它参数通过寄存器传递n忽略指令中的24bit立即数,r0指定API号,其它参数通过其它寄存器传递 n② BKPTBKPT————断点指令断点指令 断点中断指令BKPT用于产生软件断点,供调试程序用。

仅用于v5T体系汇编格式如下: BKPT { immed_16} BKPT { immed_16} immed_16:16位的立即数该立即数被调试软件用 来保存额外的断点信息 断点指令用于软件调试;它使处理器停止执行正常指令而进入相应的调试程序 n③ CLZ——前导0计数指令 前导0计数指令CLZ 对Rm中的前导0的个数进行计数,结果放到Rd中仅用于v5T体系)汇编格式: CLZ{} Rd, >} Rd, RmRm举例如下: MOV R2, #0X17F00;R2=0b0000 0000 0000 0001 0111 1111 0000 0000 CLZ R3, R2 ;R3=15 六、六、 协处理器指令协处理器指令n ARM支持16个协处理器,用于各种协处理器操作,最常使用的协处理器是用于控制片上功能的系统协处理器,例如控制高速缓存和存储器的管理单元,浮点ARM协处理器等,还可以开发专用的协处理器。

ARM协处理器指令根据其用途主要分为以下三类: 数据操作指令; 协处理器寄存器和内存单元之间数据存/取指令; ARM寄存器与协处理器寄存器的数据传送指令 n① CDP——协处理器数据操作指令 ARM处理器通过CDP指令通知ARM协处理器执行特定的操作协处理器数据操作完全是协处理器内部的操作,用于初始化ARM协处理器,完成协处理器寄存器的状态改变 指令特点:q该操作由协处理器完成,即对命令参数的解释与协处理器有关,指令的使用取决于协处理器q若协处理器不能成功地执行该操作,将产生未定义指令异常中断 n指令格式如下:CDP{} >} ,,,,CRdCRd,,CRnCRn,,CRmCRm{ {,,}}n其中: CP# 指令操作的协处理器名标准名为pn,n为0~15 Cop1 协处理器的特定操作码 CRd 作为目标寄存器的协处理器寄存器 CRn 存放第1个操作数的协处理器寄存器 CRm 存放第2个操作数的协处理器寄存器。

Cop2 可选的协处理器特定操作码n指令举例如下:n CDP p7,0,c0,c2,c3,0 ;协处理器7执行操作码1为0和可选操作码2为0的操作n CDP p6,1,c3,c4,c5 ;协处理器6执行操作码为1的操作 n② ② LDC/STCSTC————协处理器数据存协处理器数据存/ /取指令取指令 协处理器数据存/取指令从存储器读取数据装入协处理器寄存器,或将协处理器寄存器的数据存入存储器qLDC——协处理器数据读取指令 LDC指令从某一连续的内存单元将数据读取到协处理器的寄存器中进行协处理器数据的数据传送时,由协处理器来控制传送的字数若协处理器不能成功地执行该操作,将产生未定义指令异常中断 n指令格式如下: LDC{cond}{L} ,,CRdCRd,, <地址>n其中: L 可选后缀,指明是长整数传送 CP# 指令操作的协处理器名。

标准名为pn,n为0~15 CRd 作为目标寄存的协处理器寄存器 <地址> 指定的内存地址n指令举例如下:nLDC p5,c2,[R2,#4] ;读取R2+4指向的内存单元的数据,传送到协处理器p5的c2寄存器中nLDC p6,c2,[R1] ;读取R1指向的内存单元的数据,传送到协处理器p6的c2寄存器中 qSTC——协处理器数据存入指令 将协处理器的寄存器数据存入到某一连续的内存单元中,由协处理器来控制写入的字数 若协处理器不能成功地执行该操作,将产生未定义指令异常中断n指令格式如下:nSTC{cond}{LSTC{cond}{L} CP#} CP#,,CRdCRd,,< <地址地址> > 其中格式说明同 LDC 指令n指令举例如下:nSTC p5,c1,[R0]nSTC p5,c1,[R0,#0x04] n③ MCR/MRCMCR/MRC————ARM寄存器与协处理器寄存器的数据传送指令qMCR ——ARM寄存器到协处理器寄存器的数据传送指令 MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。

若协处理器不能成功地执行该操作,将产生未定义指令异常中断n指令格式如下:nMCR{condMCR{cond} CP# , Cop1, Rd, } CP# , Cop1, Rd, CRnCRn, , CRmCRm{, }{, } 其中格式说明同 CDP 指令n指令举例如下: MCR p14,3,R7,c7,c11,6 ;从ARM寄存器中将数据传送到协处理器p14的寄存器中,其中R7为ARM寄存器,存放源操作数;c7和c11位协处理器寄存器,为目标寄存器;操作码1为3;操作码2为6 qMRC——协处理器寄存器到ARM寄存器的数据传送指令 MRC指令将协处理器寄存器中的数据传送到ARM处理器的寄存器中若协处理器不能成功地执行该操作,将产生未定义指令异常中断n指令格式如下: MRC{condMRC{cond} CP# , Cop1, Rd} CP# , Cop1, Rd,,CRnCRn,,CRmCRm{, }{, }其中格式说明同 CDP 指令n指令举例如下:nMRC p5,2,R2,c3,c2 n(四)一些基本的(四)一些基本的ARMARM指令功能段指令功能段n4.1 算数逻辑运算指令的应用n例1: 实现乘法的指令段MOV R0,R0,LSL #n ;R0=R0<

n①两个64位数据的加法运算,结果保存到R0和R1中 ADDS R0,R0,R2 ;低32位相加,设置CPSR的C标志位 ADC R1,R1,R3 ;高32位的带位相加n②两个64位数据的减法运算,结果保存到R0和R1中 SUBS R0,R0,R2 ;低32位相减,设置CPSR的C标志位 SBC R1,R1,R3 ;高32位的带位相减 n③两个64位数据的比较操作,并设置CPSR中的条件标志位 CMP R1,R3 ;比较高32位 CMPEQ R0,R2 ;如果高32位相等,比较低32位 n例3:转换内存中数据存储方式n将寄存器R0中的数据存储方式转换成另一种存储方式指令执行前R0中数据存储方式为:R0=A,B,C,D;指令执行后R0中数据存储方式为:R0=D,C,B,A EOR R1,R0,R0, ROR #16 ;R1=A^C,B^D,C^A,D^B BIC R1,R1,#OxFF0000 ;R1=A^C,0,C^A,D^B MOV R0,R0,ROR #8 ;R0=D,A,B,C EOR RO,RO,R1,LSR #8 ;R0=D,C,B,A n跳转指令的应用n例1:子程序的调用 BL指令在执行跳转操作的同时保存下一条指令的地址,用于从被调用的子程序中返回。

…… BL function ;调用子程序function …… ;子程序结束后,程序将返回到这里执行 ……function ;子程序的程序体 …… MOV PC,LR ;子程序中的返回语句 n例2:条件执行n实现类似于C语言中的if-else功能的代码段下例的功能为求最大公约数nC语言代码为:int gcb (int a,int b) { while (a!=b) { if (a>b) a=a-b; else b=b-a; } return a;} v对应的ARM代码段代码执行前R0中存放a,R1中存放b;代码执行后R0中存放最大公约数gcbCMP R0,R1 ;比较a和b的大小SUBGT R0,R0,R1 ;if(a>b) a=a-bSUBLT R1,R1,R0 ;if(b>a) b=b-aBNE gcb ;if(a!=b)跳转到gcb继续执行MOV PC,LR ;子程序结束,返回 n例3:循环语句n下面代码段实现了程序循环执行。

MOV R0,#loopcount ;初始化循环次数 loop ;循环体 …… SUBS R0,R0,#1 ;循环计数器减1,设置条件标志 BNE loop ;循环计数器不为0,跳到loop继续执行 …… ;循环计数器为0,程序继续执行 nload/store指令的应用n例:链表操作n下面代码段在链表中搜索与某一数据相等的元素链表的每个元素包括两个字,第1个字中包含一个字节数据;第2个字中包含指向下一个链表元素的指针,当这个指针为0时表示链表结束代码执行前R0指向链表的头元素,R1中存放将要搜索的数据;代码执行后R0指向第1个匹配的元素,或者当没有匹配元素时,R0为0search CMP R0,#0 ;R0指针是否为空 LDRNEB R2,[R0] ;读取当前元素中的字节数据 CMPNE R1,R2 ;判断数据是否为搜索的数据 LDRNE R0,[R0,#4] ;如果不是,指针R0指向下一个元素 BNE search ;跳转到search执行 MOV PC,LR ;搜索完成,程序返回 。

下载提示
相似文档
正为您匹配相似的精品文档
相关文档