ARM指令大全
ARM常见指令
C代码:对应的汇编代码:If(a > b) CMP R0,R1 ;R0(a)与R1(b)比较a++; ADDHI R0,R0,#1 ;若R0>R1,则R0=R0+1Else ADDLS R1,R1,#1 ;若R0≤1,则R1=R1+1b++;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,[Ro,#2]! ;将R1的数据保存到R0+2地址中,只存储低2;字节数据,R0=R0+2MOV PC,R0 ;PC=R0,程序跳转到指定地址LDR R0,[R1],-R2 ;Rl所指存储器单元内容存人R0,且R1 = R1 - R2(1).寄存器寻址MOV R1,R2 ;将R2的值存入R1SUB R0,R1,R2 ;将R1的值减去R2的值,结果保存到R0MOV PC,R0 ;PC=R0,程序跳转到指定地址(R0)(2).立即数寻址SUBS R0,R0,#1 ;R0减1,结果放入R0,并且影响标志位MOV R0,#0xFF000 ;将立即数0xFF000装入R0寄存器(3).寄存器移位寻址MOV R0,R2,LSL #3 ;R2的值左移3位,结果放入R0,即是R0=R2×8ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相“与”操作,结果放入R1 ADD R3,R2,R1,LSL #3 ;R3←R2+8*R1(LSL:逻辑左移LSR:逻辑右移ASR算术右移ROR循环右移RRX扩展为1的循环右移)(4).寄存器间接寻址LDR R1,[R2] ;将R2指向的存储单元的数据读出保存在R1中SWP R1,R1,[R2] ;将寄存器R1的值和R2指定的存储单元的内容交换(5).基址寻址LDR R2,[R3,#0x0C] ;读取R3+0x0C地址上的存储单元的内容,放入R2STR R1,[R0,#-4]! ;先R0=R0-4,然后把R1的值寄存到保存到R0指定的存储单元基址加偏移-前索引寻址LDR R0,[R1,#4] ;R0←[R1+4]基址加偏移-带自动索引的前索引寻址LDR R0,[R1,#4]!;R0←[R1+4]、R1←R1+4基址加偏移-后索引寻址LDR R0,[R1],#4 ;R0←[R1]、R1←R1+4基址加索引寻址LDR R0,[R1,R2] ;R0←[R1+R2](6).多寄存器寻址LDMIA R1!,{R2-R7,R12} ;将R1指向的单元中的数据读出到R2~R7、R12中(R1自动加1)STMIA R0!,{R2-R7,R12} ;将寄存器R2~R7、R12的值保存到R0指向的存储单元中;(R0自动加1)(7).堆栈寻址向上生长:向高地址方向生长,称为递增堆栈向下生长:向低地址方向生长,称为递减堆栈堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。
常用ARM指令汇总
常用ARM指令集及汇编一、ARM处理器的寻址方式二、指令集学习(一)ARM指令集1.指令格式2.条件码3.ARM存储器访问指令1)LDR/ STR-加载/ 存储指令2)LDM/ STM-多寄存器加载/ 存储指令3)SWP-寄存器和存储器交换指令4.ARM数据处理指令1)数据传送指令a)MOV-数据传送指令b)MVN-数据非传送指令2)算术逻辑运算指令a)ADD-加法运算指令b)SUB-减法运算指令c)RSB-逆向减法指令d)ADC-带进位加法指令e)SBC-带进位减法指令f)RSC-带进位逆向减法指令g)AND-逻辑“与”h)ORR-逻辑“或”i)EOR-逻辑“异或”j)BIC-位清除指令3)比较指令a)CMP-比较指令b)CMN-负数比较指令c)TST-位测试指令d)TEQ-相等测试指令4)乘法指令a)MUL-32位乘法指令b)MLA-32位乘加指令c)UMULL-64位无符号乘法指令d)UMLAL-64位无符号乘加指令e)SMULL-64位有符号乘法指令f)SMLAL-64位有符号乘加指令5.ARM分支指令1)B-分支指令2)BL-带连接的分支指令3)BX-带状态切换的分支指令6.ARM协处理器指令1)CDP-协处理器数据操作指令2)LDC-协处理器数据读取指令3)STC-协处理器数据写入指令4)MCR-ARM处理器到协处理器的数据传送指令5)MRC-协处理器到ARM处理器的数据传送指令7.ARM杂项指令1)SWI-软中断指令2)MRS-读状态寄存器指令3)MSR-写状态寄存器指令8.ARM伪指令1)ADR-小范围的地址读取伪指令2)ADRL-中等范围的地址读取伪指令3)LDR-大范围的地址读取伪指令4)NOP-空操作伪指令(二)Thumb指令集1.Thumb指令集和ARM指令集的区别2.Thumb存储器访问指令1)LDR/ STR-加载/ 存储指令2)PUSH/ POP-寄存器入栈 / 出栈指令3)LDMIA/ STMIA-多寄存器加载/ 存储指令3.Thumb数据处理指令1)数据传送指令a)MOV-数据传送指令b)MVN-数据非传送指令c)NEG-数据取负指令2)算术逻辑运算指令a)ADD-加法运算指令b)SUB-减法运算指令c)ADC-带进位加法指令d)SBC-带进位减法指令e)MUL-乘法运算指令f)AND-逻辑“与”g)ORR-逻辑“或”h)EOR-逻辑“异或”i)BIC-位清除指令j)ASR-算术右移指令k)LSL-逻辑左移指令l)LSR-逻辑右移指令m)ROR-循环右移指令3)比较指令a)CMP-比较指令b)CMN-负数比较指令c)TST-位测试指令4.Thumb分支指令1)B-分支指令2)BL-带连接的分支指令3)BX-带状态切换的分支指令5.Thumb杂项指令1)SWI-软中断指令6.Thumb伪指令1)ADR-小范围的地址读取伪指令2)LDR-大范围的地址读取伪指令3)NOP-空操作伪指令。
常用ARM指令
常⽤ARM指令常⽤ARM指令1:数据处理指令 mov mvn MOV(MOVE)指令可完成从另⼀个寄存器、被移位的寄存器或将⼀个⽴即数加载到⽬的寄存器MOV R0,R1;R1的值传到R0MOV R3,#3 ;把常数3传给R3MVN( MOVE Negative)取反后再传值,⽐MOV多了⼀步取反MVN R0, #0 ;把0取反(即-1)传给R0MVN R1,R2 ;把R2的值取反传给R1 算术指令 add sub rsb adc sbc rsc ADD加法指令 ADD R0,R1,R2; R0=R1+R2 ADD R0,R1,#3 ;R0=R1+3 ADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来 通常⽤于⼤数(超过32Bit整数)相加,这时单⽤ADD不能处理,必须折成两步,其中⼀步⽤ADC. 以下是做64Bit的加法 ADDS R0,R1,R2; R0=R1+R2,ADDS中S表⽰把进位结果写⼊CPSR ADC R5,R3,R4 ;R5=R3+R4+C 逻辑指令 and orr eor bic AND位与指令 AND R0,R1,R2; R0=R1 & R2 AND R0,R1,#0xFF ;R0=R1 & 0xFF ORR位或指令 ORR R0,R1,R2; R0=R1 | R2 ORR R0,R1,#0xFF ;R0=R1 | 0xFF TST测试某⼀位是否为1,并把结果写⼊CPSR,供下⼀句使⽤ TST R1,#0xffe; 等同于if(R1 & 0xffe) TST R1,#%1;测试最低位是否为1,%表⽰⼆进制 BIC清位操作 BIC R0,R0,#0xF;等同于 R0 &=~(0xF) BIC R0,R0,#%1011;该指令清除 R0 中的位 0 1 3,其余的位保持; %表⽰是⼆进制,0x表⽰⼗六进制 ⽐较指令 cmp cmn tst teq CMP⽐较两个操作数,并把结果存⼊CPSR供下⼀句语句使⽤ CMP R0,R1; ⽐较R0,R1 乘法指令 mvl mla umull umlal smull small MUL R0,R1,R2 ;R0 = R1 × R2MULS R0,R1,R2 ;R0 = R1 × R2,同时设置CPSR中的相关条件标志位 MLA R0,R1,R2,R3 ;R0 = R1 × R2 + R3MLAS R0× R2 + R3,同时设置CPSR中的相关条件标志位 SMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32位 ;R1 = (R2 × R3)的⾼32位 加载/存储指令 LDR,STR LDR R0,[R1]; R1的值当成地址,再从这个地址装⼊数据到R0 (R0=*R1) LDR R1,=0x30008000 ; 把地址0x30008000的值装⼊到R1中 STR R0,[R1] ; 把R0的值,存⼊到R1对应地址空间上(*R1 = R0)。
arm 汇编 指令
arm 汇编指令ARM汇编指令是一种用于编写ARM处理器程序的语言。
ARM处理器广泛应用于嵌入式系统和移动设备等领域。
ARM汇编指令与x86汇编指令有所不同,它基于RISC(精简指令集计算机)架构。
下面是一些基本的ARM汇编指令:1. 数据传输指令:用于在寄存器之间传输数据。
例如:- mov:将数据从一个寄存器传输到另一个寄存器。
- ldr:将数据从内存传输到寄存器。
2. 算术指令:用于执行加法、减法、乘法和除法等操作。
例如:- add:加法操作。
- sub:减法操作。
- mull:乘法操作。
- div:除法操作。
3. 逻辑指令:用于执行逻辑操作,如与、或、非等。
例如:- and:与操作。
- or:或操作。
- xor:异或操作。
4. 移位指令:用于对数据进行左移、右移或无符号右移。
例如:- lsr:无符号右移。
- asr:带符号右移。
- ror:循环右移。
5. 比较指令:用于比较两个寄存器的值。
例如:- cmp:比较两个寄存器的值,若相等则返回0,否则返回1。
6. 跳转指令:用于改变程序的执行流程。
例如:- b:条件跳转。
- bl:无条件跳转。
- bx:带状态跳转。
7. 循环指令:用于实现循环操作。
例如:- loop:内部循环。
- ldp:外部循环。
8. 调用指令:用于实现函数调用。
例如:- blx:带状态调用。
- bx:不带状态调用。
9. 系统调用指令:用于实现与操作系统交互的功能。
例如:- swi:执行系统调用。
10. 存储器访问指令:用于访问内存数据。
例如:- str:将数据存储到内存。
- ldr:从内存中加载数据。
以上仅为ARM汇编指令的一部分,实际上,ARM汇编指令还有很多其他功能。
为了更好地理解和使用ARM汇编指令,可以参考相关的教程和手册,并进行实际操作。
ARM指令集
ARM指令集6种类型(53种主要助记符):数据处理指令(22种主要助记符)跳转指令(4种主要助记符)Load/Store指令(16种主要助记符)程序状态寄存器指令(2种主要助记符)协处理器指令(5种主要助记符)软件中断指令(2种主要助记符)数据处理指令数据处理指令大致可分为3类:数据传送指令;算术逻辑运算指令;乘法指令比较指令。
数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。
所有ARM数据处理指令均可选择使用S后缀,并影响状态标志。
数据处理指令1MOV 数据传送指令格式:MOV{<cond>}{S} <Rd>,<op1>;功能:Rd=op1op1可以是寄存器、被移位的寄存器或立即数。
例如:MOV R0,#5 ;R0=5MOV R0,R1 ;R0=R1MOV R0,R1,LSL#5 ;R0=R1左移5位数据处理指令22.MVN 数据取反传送指令格式:MVN{<cond>}{S} <Rd>,<op1>;功能:将op1表示的值传送到目的寄存器Rd中,但该值在传送前被按位取反,即Rd=!op1;op1可以是寄存器、被移位的寄存器或立即数。
例如:MVN R0,#0 ;R0=-1数据处理指令33.ADD 加法指令格式:ADD{<cond>}{S} <Rd>,<Rn>,<op2>;功能:Rd=Rn+op2op2可以是寄存器,被移位的寄存器或立即数。
例如:ADD R0,R1,#5 ;R0=R1+5ADD R0,R1,R2 ;R0=R1+R2ADD R0,R1,R2,LSL#5 ;R0=R1+R2左移5位数据处理指令44.ADC 带进位加法指令格式:ADC{<cond>}{S} <Rd>,<Rn>,<op2>;功能:Rd=Rn+op2+carryop2可以是寄存器、被移位的寄存器或立即数;carry为进位标志值。
实用ARM指令全
在讲指令之前,先简单地介绍一下Cortex-M3 中支持的算术与逻辑标志。
本书在后面还会展开论述。
它们是:APSR 中的5 个标志位4.2.1 分类指令表表4.2 16位数据操作指令表4.3 16位转移指令IT If-Then表4.4 16位存储器数据传送指令16 数据传送指令没有任何新内容,因为它们是Thumb 指令,在v4T 时就已经定格了——译注表4.5 其它16位指令表4.6 32位数据操作指令UXTH 半字被无符号扩展到32 位(高16 位清0——译注)表4.7 32位存储器数据传送指令表4.8 32位转移指令表4.9 其它32位指令4.2.2 未支持的指令有若干条Thumb 指令没有得到Cortex-M3 的支持,下表列出了未被支持的指令,以及不支持的原因。
表4.10 因为不再是传统的架构,导致有些指令已失去意义未支持的指令以前的功能BLX #im 在使用立即数做操作数时,BLX 总是要切入ARM 状态。
因为Cortex-M3 只在Thumb 态下运行,故以此指令为代表的,凡是试图切入ARM 态的操作,都将引发一个用法fault。
SETEND由ARMv6 引入的,在运行时改变处理器端设置的指令(大端或小端)。
因为Cortex-M3 不支持动态端的功能,所以此指令也将引发faultCM3 也不支持有少量在ARMv7-M 中列出的指令。
比如,ARMv7M 支持Thumb2 的协处理器指令,但是CM3 却不能挂协处理器。
表4.11 列出了这些与协处理器相关的指令。
如果试图执行它们,则将引发用法fault(NVIC 中的NOCP (No CoProcessor)标志置位)。
表4.11 不支持的协处理器相关指令未支持的指令以前的功能MCR 把通用寄存器的值传送到协处理器的寄存器中MCR2把通用寄存器的值传送到协处理器的寄存器中MCRR 把通用寄存器的值传送到协处理器的寄存器中,一次操作两个MRC把协处理器寄存器的值传送到通用寄存器中MRC2 把协处理器寄存器的值传送到通用寄存器中MRRC把协处理器寄存器的值传送到通用寄存器中,一次操作两个LDC 把某个连续地址空间中的一串数值传送至协处理器中STC从协处理器中传送一串数值到地址连续的一段地址空间中还有一个是改变处理器状态指令(CPS),它的一些用法也不再支持。
Arm常用指令
1、 内存访问指令 基本指令:
LDR:memory -> register (memory 包括 映射到内存空间的非通用寄存器)
STR:register -> memory
语法:
op{cond }{B}{T} Rd , [Rn ]
op{cond }{B} Rd , [Rn , FlexOffset ]{!}
;引用外部符号
EXPORT令定义程序
的开始
start
;此处定义了一个label
start
MOV r0, #10
MOV r1, #3
ADD r0, r0, r1
;r0 =r0 +r1
prog1
;此处定义了一个label
prog1
MOV r0, #0x18
;
7、 跳转指令 基本指令:
B:跳转 BL:跳转并将下一指令的地址存入 lr 寄存 器
语法:
op{cond} label label:要跳向的地址
例子:
loop1
~~~ b loop1
; 跳到地址 loop1 处
bl sub1
; 将下一指令地址写入 lr,并跳
至 sub1
~~~
sub1
~~~
mov pc, lr
op{cond }{B} Rd , label
op{cond }{B}{T} Rd , [Rn ],FlexOffset op:基本指令,如 LDR、STR cond:条件执行后缀 B:字节操作后缀 T:用户指令后缀 Rd:源寄存器,对于 LDR 指令,Rd 将保存从 memory 中读取的数值;对于 STR 指令,Rd 保存着将写入 memory 的数值 Rn:指针寄存器 FlexOffset:偏移量
ARM指令
堆栈指针指向下一个要放入数据的空位置
5.ARM指令集
(1)跳转指令
B指令: B{条件} 目的地址
B指令是最简单的跳转指令。
如: B Label ;无条件跳到Label处执行
如:MOV R1,R0
MOV PC,R14 ;将寄存器R14的值传送到PC,常用于子程序返回
MOV R1,R0,LSL#3 ;将寄存器R0的值左移三位然后传送到R1
MVN{条件}{S} 目的寄存器,源操作数
当未定义的指令执行时进入该模式,可用于支持硬件
说明:除用户模式,其他的称为特权模式或非用户模式
除用户模式和系统模式,其他的又被称为异常模式,常用于处理中断和 要访问受保护的系统资源等情况。
2.寄存器
1.说明:ARM有37个32寄存器,其中31个为通用寄存器,6个位状态寄存器,可访问情况取决ARM工作模式及状态,通用寄存器R14-R0,程序计数器PC,一个状态寄存器都可访问。
AND指令把操作数1与操作数2的逻辑与结果放入目的寄存器,操作数1应 是一个寄存器,操作数2可以是寄存器或者被移位的寄存器,或者立即 数,ADD和SUB也一样。
ORR指令和AND差不多,ORR是逻辑或运算
0b10001 FIQ PC,R14_FIQ-R8_FIQ,R7~R0,CPSR,SPSR_FIQ
0b10010 IRQ PC,R14_IRQ-R13_IRQ,R12~R0,CPSR,SPSR_IRQ
0B10011 SUPERVISOR PC,R14_SVC-R13_SVC,R12~R0,CPSR,SPSR_SVC
(3)寄存器间接寻址
以寄存器中的数作为操作数中的地址,而操作数本身存放在存储器中
arm指令
一、加减法指令:1、MOV(move):数据传送指令2、MVN(move negative):数据取反传送指令3、ADD(add):加法4、ADC(add with carry):带进位加法5、SUB(subtract):减法6、RSB(reverse subtract):反向减法7、SBC(subtract with carry):带借位的减法SBC{<cond>}{S} <Rd>,<Rn>,<op2> ;Rd=Rn-op2-carry8、RSC(reverse subtract with carry):带借位的反向减法RSC{<cond>}{S} <Rd>,<Rn>,<op3> ;Rd= op3-Rn-!carry二、逻辑指令1、AND:逻辑与2、ORR(logical or):逻辑或3、EOR(exclusive or):逻辑异或4、BIC(bit clear):位清零5、CLZ(count leading zeros):位计数。
CLZ{<cond>} <Rd>,<Rm>;计算存储在Rm寄存器中各位为0的总个数。
三、乘法指令1、MUL(multiply):32位乘法2、MLA(multiply accumulate):32位乘加MLA{<cond>} {S} <Rd>,<Rn>,<op2>,<op3>;3、SMULL(signed multiplication long):64位有符号数乘法SMULL {<cond>}{S} <Rdl>,<Rdh>,<Rn>,<op2>;Rdh Rdl=Rn×op2,结果的高32位存入Rdh,低32位存入Rdl。
ARM指令总结
移位指令(操作)LSL # n ;逻辑左移n位(1≤n≤31),低端空位补0LSR # n ;逻辑右移n位(1≤n≤32) ,高端空位补0ASR # n ;算术右移n位(1≤n≤32),保持符号位不变ROR # n ;循环右移n位(1≤n≤31),低端移出位填入高端RRX ;带扩展的循环右移1位,第31位用原进位C填入程序状态寄存器指令MRS程序状态寄存器到通用寄存器的数据传送指令指令格式:MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR)MSR通用寄存器到程序状态寄存器的数据传送指令指令格式:MSR{条件} 程序状态寄存器(CPSR或SPSR)_<域>,操作数其中,操作数可以为通用寄存器或立即数。
<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器可分为4个域:位[31:24]为条件标志位域,用f表示;位[23:16]为状态位域,用s表示;位[15:8]为扩展位域,用x表示;位[7:0]为控制位域,用c表示;该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR指令中指明将要操作的域。
数据交换指令SWP 字交换指令。
将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中指令格式:SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]SWPB字节交换指令。
将源寄存器2所指向的存储器中的字节数据传送到目的寄存器中,目的寄存器的高24清零,同时将源寄存器1中的字节数据传送到源寄存器2所指向的存储器中指令格式:SWP{条件}B 目的寄存器,源寄存器1,[源寄存器2]跳转指令B 跳转指令指令格式:B{条件} 目标地址BL 带返回的跳转指令。
跳转之前,会在寄存器R14中保存PC的当前内容指令格式:BL{条件} 目标地址BX 带状态切换的跳转指令。
跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令指令格式:BX{条件} 目标地址BLX带返回和状态切换的跳转指令。
arm 32 常见汇编指令 对应的机器码
arm 32 常见汇编指令对应的机器码
ARM 32位汇编指令是一种用于ARM架构的低级编程语言,它将人类可读的汇编指令转换为机器码,从而实现对计算机硬件的直接控制。
以下是几个常见的ARM 32位汇编指令及其对应的机器码:
1. MOV指令:将一个数据从一个位置复制到另一个位置。
机器码:0xMOV Rd, Rn
2. ADD指令:将两个数据相加并将结果存储在目标寄存器中。
机器码:0xADD Rd, Rn, Rm
3. SUB指令:将两个数据相减并将结果存储在目标寄存器中。
机器码:0xSUB Rd, Rn, Rm
4. CMP指令:比较两个数据的大小,并根据比较结果设置条件代码。
机器码:0xCMP Rn, Rm
5. LDR指令:从内存中加载数据到寄存器中。
机器码:0xLDR Rd, [Rn, #offset]
6. STR指令:将寄存器中的数据存储到内存中。
机器码:0xSTR Rd, [Rn, #offset]
7. B指令:无条件跳转到指定的地址。
机器码:0xB label
8. BEQ指令:如果上一次比较结果为相等,则跳转到指定的地址。
机器码:0xBEQ label
以上是ARM 32位汇编指令的一些常见例子,每个指令都有对应的机器码。
通过编写汇编程序,程序员可以直接对计算机硬件进行控制,实现各种功能。
虽然汇编语言比高级语言更难以理解和编写,但它提供了更高的灵活性和效率,特别适合对性能要求较高的应用。
ARM指令集详解(超详细!带实例!)
ARM指令集详解(超详细!带实例!)算术和逻辑指令ADC : 带进位的加法(Ad dition with C arry)ADC{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 + op_2 + carryADC 将把两个操作数加起来,并把结果放置到⽬的寄存器中。
它使⽤⼀个进位标志位,这样就可以做⽐ 32 位⼤的加法。
下列例⼦将加两个 128 位的数。
128 位结果: 寄存器 0、1、2、和 3第⼀个 128 位数: 寄存器 4、5、6、和 7第⼆个 128 位数: 寄存器 8、9、10、和 11。
ADDS R0, R4, R8 ; 加低端的字ADCS R1, R5, R9 ; 加下⼀个字,带进位ADCS R2, R6, R10 ; 加第三个字,带进位ADCS R3, R7, R11 ; 加⾼端的字,带进位如果如果要做这样的加法,不要忘记设置 S 后缀来更改进位标志。
这两个指令与普通指令在对操作数的限制上有所不同:1. 给出的所有操作数、和⽬的寄存器必须为简单的寄存器。
2. 你不能对操作数 2 使⽤⽴即值或被移位的寄存器。
3. ⽬的寄存器和操作数 1 必须是不同的寄存器。
4. 最后,你不能指定 R15 为⽬的寄存器。
译注:CMP 和 CMP 是算术指令,TEQ 和 TST 是逻辑指令。
把它们归⼊⼀类的原因是它们的 S 位总是设置的,就是说,它们总是影响标志位。
CMN : ⽐较取负的值(C o m pare N egative)CMN{条件}{P} <op 1>, <op 2>status = op_1 - (- op_2)CMN 同于 CMP,但它允许你与⼩负值(操作数 2 的取负的值)进⾏⽐较,⽐如难于⽤其他⽅法实现的⽤于结束列表的 -1。
这样与 -1 ⽐较将使⽤:CMN R0, #1 ; 把 R0 与 -1 进⾏⽐较详情参照 CMP 指令。
ARM指令大全
同时更新CPSR(状态寄存器)
5、TST测试某一位是否被设置了
例如:TST R1,#%1(%表示二进制)
6、ADD指令:ADD{条件}{S}目的寄存器,操作数1、操作数2
SUB是减法运算,用法同上
AND是逻辑与运算,用法同上
ORR是逻辑或
除去用户模式外其他被称为非用户模式
除去用户和系统模式外 其他的被称为异常模式
模式的改变:软件改变或用中断改变
寄存器ARM状态:
1、不分组寄存器:R1-R7
2、分组寄存器:R8-R14
R13:堆栈指针寄存器SP
R14:子程序链接寄存器LR
3、程序计数器:R15
寻址方式:
1、立即寻址
2、寄存器寻址
3、寄存器间接寻址
4、基址变址寻址
5、堆栈寻址
ARM指令集:
1、跳转指令:B{条件} 目标地址 BL跳转并返回
2、MOV指令:MOV {条件}{S}目的寄存器,源操作数
有S的决定指令的操作是否影响CPSR中条件标志
3、MVN指令与MOV基本一样,是将取反后的值进行移动
ADS是ARM的开发工具,有命令行和图形化两种开发工具
1)ARM状态:执行32位ARM指令集 最大寻址空间:4GB,字对齐 支持两种存储字的方法 大端格式:字数据的高字节放在低地址
2)Thumb状态:执行16位Thumb指令集
七种工作模式:1、用户模式:正常运行 2、快速中断模式:高速数据传输 3、外部中断模式 4、管理模式 5、数据访问终止模式 6、系统模式 7、未定义指令终止模式
IF 逻辑表达式
ARM常用指令
ARM常用指令ARM常用指令一、数据传送指令1、 mov指令格式: mov{}{s} Rd,op操作: Rd = op;2、 mvn指令格式: mvn{}{s} Rd,op操作: Rd = ~op;二、算术指令1、 add加法指令格式: add{}{s} Rd,Rn,op操作: Rd = Rn + op;2、 adc带进位加法指令格式: adc{}{s} Rd,Rn,op操作: Rd = Rn + op + C;3、 sub减法指令格式: sub{}{s} Rd,Rn,op操作:Rd = Rn - op;4、 sbc带借位减法指令格式: sbc{}{s} Rd,Rn,op操作: Rd = Rn - op - (~C);5、 rsb逆向减法指令格式: rsb{}{s} Rd,Rn,op操作: Rd = op - Rn;6、 rsc带借位的逆向减法指令格式: rsc{}{s} Rd,Rn,op操作: Rd = op - Rn - (~C);三、移位1、 op立即数: #number //#label寄存器: Rm寄存器移位: Rm,<移位符> #number 或 Rm,<移位符> Rs 举例: mov r0,#100 //r0 = 100mov r0,r1 //r0 = r1mov r0,r1,lsr #1 //r0 = r1 >> 1mov r0,r1,lsr r2 //r0 = r1 >> r2add r0,r1,r2,lsr #1 //r0 = r1 + r2 >> 12、移位符lsl 逻辑左移 (unsigned)x << y说明:无符号左移补0lsr 逻辑右移 (unsigned)x >> y说明:无符号右移补0asl 算术左移 (signed)x << y说明:有符号左移补0注意:逻辑左移和算术左移结果一样asr 算术右移 (signed)x >> y说明:有符号右移正数补0,负数补1ror 循环右移 ((unsigned)x >> y) | (x << (32 - y))说明: x逻辑右移y | x逻辑左移 (32 - y)rrx 扩展循环右移 (C << 31) | ((unsigned)x >> 1) 说明:相当于33位循环右移注意:没有y,只移一位四、逻辑指令1、 and逻辑与指令格式: and{}{s} Rd,Rn,op操作: Rd = Rn & op;2、 orr逻辑或指令格式: orr{}{s} Rd,Rn,op操作: Rd = Rn | op;3、 eor逻辑异或指令格式: eor{}{s} Rd,Rn,op操作: Rd = Rn ^ op;4、 bic位清除指令格式: bic{}{s} Rd,Rn,op操作: Rd = Rn & (~op);五、比较指令(默认带S位)1、 cmp比较指令格式: cmp{} Rn,op操作: Rn - op2、 cmn反比较指令格式: cmn{} Rn,op操作: Rn + op3、 tst位测试指令格式: tst{} Rn,op操作: Rn & op4、 teq相等测试指令格式: teq{} Rn,op操作: Rn ^ op六、数据处理指令位图1、 op为寄存器xxxx 000a aaas nnnn dddd cccc cttt mmmm2、 op为立即数xxxx 001a aaas nnnn dddd rrrr bbbb bbbb3、条件xxxx见ARMv4v5v6.pdf P112只有条件为真时才会执行指令,否则忽略该指令,继续下一条4、数据处理指令aaaa见ARMv4v5v6.pdf P1155、条件标志s指令含s则该位为 1 ,否则为 06、寄存器Rd,Rn,Rm分别对应dddd,nnnn,mmmmR0 ---> R150000 ---> 1111没有寄存器的则对应位置为 0,如:mov没有Rn寄存器nnnn位为 0000 ,cmp没有Rd寄存器dddd位为 00007、移位数ccccc立即数方式:最大为 0x1f寄存器方式:第 1 - 4 个c为寄存器编号,第 5 个c为 08、移位符ttt移位符: lsl lsr asr ror立即数编码: 000 010 100 110寄存器编码: 001 011 101 111asl 与 lsl 的编码相同ttt == 110 && ccccc == 00000 表示 rrx9、立即数构造立即数= bbbb bbbb 循环右移 rrrr * 2 次这种方式并不能把所有的32位数都构造出来如: #12345,#0xffff七、常量的装载1、 ldr伪指令格式: ldr Rd,= //ldr只有带'='号时才是伪指令说明:将number或label的值赋给Rd,该指令会伪造成mov、mvn、ldr等可能的指令举例: ldr r0,=0x100 //mov r0,#0x100ldr r0,=0x0 //mvn r0,#0x0ldr r0,=0x12345 //ldr r0,[pc,#offset] //offset是该指令到.word 的偏移量减去8//...//.word 0x123452、 adr / adrl伪指令格式: adr Rd,=label说明:此指令不能用立即数,其他基本和ldr一样,小范围时用adr,大范围用时adrl八、乘法指令1、 mul乘法指令格式: mul{}{s} Rd,Rm,Rs操作: Rd = Rm * Rs;2、 mla乘累加指令格式: mla{}{s} Rd,Rm,Rs,Rn操作: Rd = Rm * Rs + Rn;九、分支指令1、分支指令格式: b{l}{} label位图: xxxx 101L jjjj jjjj jjjj jjjj jjjj jjjj汇编: code[23:0] = (offset - 8) >> 2//offset是label的地址减去当前指令的地址,正数向前跳,负数向后跳code[24] = Lcode[27:25] = 101code[31:28] =操作: if(L == 1)lr = pc - 8 + 4;//保存下一条指令,当把lr的值赋给pc时可实现函数返回pc = pc + (SignExtend_30(code[23:0]) << 2);//SignExtend_30表示有符号扩展30位ARM指令是按每 4 个字节对齐的(所有指令的地址最低两位都为所以可以先右移 2 位保存,取出值后再左移 2 位offset的有效位数是26,共64M,前后各32M2、分支切换指令格式: bx{} Rm操作: pc = Rm & 0xfffffffc;T = Rm[0];格式: blx{} Rm操作: lr = pc + 4 - 8;pc = Rm & 0xfffffffc;T = Rm[0];格式:blx{} label //label必须为thumb指令函数,只能前后各跳32M十、单寄存器load-store指令1、 ldr 32 位数据读取指令格式: ldr{} Rd,addr //addr用法请见内存寻址方式操作: val = *(int *)addr;2、 ldr 16 位数据读取指令格式: ldr{}h Rd,addr操作: Rd = *(short *)addr & 0x0000ffff;3、 ldr 16 位有符号数据读取指令格式: ldr{}sh Rd,addr操作: Rd = *(short *)addr & 0x0000ffff;if(Rd[15] == 1)Rd |= 0xffff0000;4、 ldr 8 位数据读取指令格式: ldr{}b Rd,addr操作: Rd = *(char *)addr & 0x000000ff;5、 ldr 8 位有符号数据读取指令格式: ldr{}b Rd,addr操作: Rd = *(char *)addr & 0x000000ff; if(Rd[7] == 1)Rd |= 0xffffff00;6、 str 32 位数据写入指令格式: str{} Rd,addr操作: *(int *)addr = Rd;7、 str 16 位数据写入指令格式: str{}h Rd,addr操作: *(short *)addr = Rd[15:0];8、 str 8 位数据写入指令格式: str{}b Rd,addr操作: *(char *)addr = Rd[7:0];注:没有str有符号数据写入指令十一、内存寻址方式1、 label举例: ldr r0,labellebel:.word 0x12345操作: r0 = *(int *)label;2、前变址格式: [Rn,op]操作: addr = Rn + op;注: addr只是地址,还没有取值举例: ldr R0,[R1,#8]操作: addr = R1 + 8;R0 = *(int *)addr;3、回写前变址格式: [Rn,op]!操作: addr = Rn + op;Rn = Rn + op;4、后变址格式: [Rn],op操作: addr = Rn;Rn = Rn + op;5、 ldr、ldrb、str、strb指令的op立即数: #+/-offset_12寄存器: +/-Rm寄存器移位: +/-Rm,<移位符> #number注: #+/-offset_12(与前面的立即数构造方法一样)number最大为0x1f,没有+/-Rm,<移位符> Rs方式的寄存器移位+号可以省略立即数等于 0 可以省略6、 ldrh、ldrsh、ldrsb、strh指令的op立即数: #+/-offset_8寄存器: +/-Rm注: offset_8最大为255,没有寄存器移位7、Rn == pc说明:当Rn == pc时,addr = 当前指令的地址 + 8 + op举例: 0 ldr r0,[pc,#-4]4 .word 0x123458这两行指令等于mov r0,#0x12345,但是0x12345 不能构造成立即数,所以可以通过这种方式来赋值我们不能写成 ldr r0,[pc,#4],因为执行这条指令时pc已经执行地址 8 的指令,应该减去 4 而不是加 4十二、多寄存器方式1、 ldm / stm格式: {}{ia|ib|da|db} Rn{!},R_list//{r0 - r15}^ / {r0,r5,r9,pc},如果顺序不对,编译器会自动按从R0-R15调整// ^表示cpsr --> spsr或spsr -->cpsr操作: if(cond==1){if(ia == 1)//执行后增加,如果寻址模式为空,默认是iaaddr = Rn;else if(ib == 1)//执行前增加addr = Rn + 4;else if(da == 1)//执行后减少addr = Rn - sizeof(R_list) + 4; //sizeof(R_list) == 寄存器数 * 4else //db == 1//执行前减少addr = Rn - sizeof(R_list);if(ldm == 1)ldm_func(addr,R_list);else //stm == 1stm_func(addr,R_list);if(! == 1){if(ia == 1 || ib == 1)Rn += sizeof(R_list);else //da == 1 || db == 1Rn -= sizeof(R_list);}}void ldm_func(addr,R_list) {for(i = 0;i <= 14;i++){if(R_list[i] == 1)R_list[i] = *(int *)addr;addr += 4;}if(R_list[15] == 1){pc = *(int *)addr & 0xfffffffc; }if(^ == 1){cpsr = spsr;}}void stm_func(addr,R_list) {for(i = 0;i <= 15;i++){if(R_list[i] == 1)*(int *)addr = R_list[i];addr += 4;}if(^ == 1){spsr = cpsr;}}2 、更新基地址的指令对,可实现栈的push和pop操作stmia <=======> ldmdbstmib <=======> ldmdastmda <=======> ldmibstmdb <=======> ldmia举例: stmdb sp!,{r1,r2,r3}ldmia sp!,{r1,r2,r3}执行后 sp,r1,r2,r3 的值保持不变3、栈操作栈向高地址扩展的为递增栈(A,ascending),向低地址扩展的为递减栈(D,descending)栈指针(sp)指向的是有效数据称为满栈(F,full),指向的是无效数据称为空栈(E,empty)在ARM-Thumb过程调用标准(ATPCS)中,栈被定义为递减式满栈寻址方式说明 push =stm pop =ldmFA 递增满 stmfa stmib ldmfa ldmdaFD 递减满 stmfd stmdb ldmfd ldmia //arm汇编的push和pop 操作指令EA 递增空 stmea stmia ldmea ldmdbED 递减空 stmed stmda ldmed ldmib十三、程序状态寄存器指令1、 mrs格式: mrs{} Rd,2、 msr格式: msr{} {_fields},fields可以是f、x、s、f的任意组合,表示只对该域操作,默认全部f 表示标志域 psr[31:24]s 表示状态域 psr[23:16]x 表示扩展域 psr[15:8]c 表示控制域 psr[7:0]。
ARM指令全集
ARM汇编指令四、程序状态寄存器访问指令1、MRS 指令MRS 指令的格式为:MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)MRS 指令用于将程序状态寄存器的内容传送到通用寄存器中。
该指令一般用在以下两种情况:Ⅰ.当需要改变程序状态寄存器的内容时,可用MRS 将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
Ⅱ.当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
指令示例:MRS R0,CPSR ;传送CPSR 的内容到R0MRS R0,SPSR ;传送SPSR 的内容到R02、MSR 指令MSR 指令的格式为:MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数MSR 指令用于将操作数的内容传送到程序状态寄存器的特定域中。
其中,操作数可以为通用寄存器或立即数。
<域>用于设置程序状态寄存器中需要操作的位,32 位的程序状态寄存器可分为4 个域:位[31:24]为条件标志位域,用f 表示;位[23:16]为状态位域,用s 表示;位[15:8]为扩展位域,用x 表示;位[7:0]为控制位域,用c 表示;该指令通常用于恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR 指令中指明将要操作的域。
指令示例:MSR CPSR,R0 ;传送R0 的内容到CPSRMSR SPSR,R0 ;传送R0 的内容到SPSRMSR CPSR_c,R0 ;传送R0 的内容到SPSR,但仅仅修改CPSR中的控制位域五、加载/存储指令ARM 微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。
常用的加载存储指令如下:1、LDR 指令LDR 指令的格式为:LDR{条件} 目的寄存器,<存储器地址>LDR 指令用于从存储器中将一个32 位的字数据传送到目的寄存器中。
ARM指令集
IRQ(Interrupt Request)
IRQ异常属于正常的中断请求,可通过对处理器的nIRQ引脚 输入低电平产生,IRQ的优先级低于FIQ,当程序执行进入 FIQ异常时,IRQ可能被屏蔽。
若将CPSR的I位置为1,则会禁止IRQ中断,若将CPSR的I位 清零,处理器会在指令执行完之前检查IRQ的输入。注意只 有在特权模式下才能改变I位的状态。
不管是在ARM状态还是在Thumb状态下进入IRQ模式,IRQ 处理程序均会执行以下指令从IRQ模式返回:
SUBS PC , R14_irq , #4
该指令将寄存器R14_irq的值减去4后,复制到程序计数器PC 中,从而实现从异常处理程序中的返回,同时将SPSR_mode 寄存器的内容复制到当前程序状态寄存器CPSR中。
2、将CPSR复制到相应的SPSR中。 3、根据异常类型,强制设置CPSR的运行模式位。 4、强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相
应的异常处理程序处。
还可以设置中断禁止位,以禁止中断发生。
如果异常发生时,处理器处于Thumb状态,则当异常向量地 址加载入PC时,处理器自动切换到ARM状态。
半字需要2字节对齐(地址的最低位为0)。
5.1 引言--存储器组织
Little- and big-endian memory organizations
5.1 引言—特权模式
ARM operating modes and register usage.
SPSR----每一种特权模式(系统模式除外)都有一个与之相关的程序状态保存寄存器SPSR
0x00
0x00
0x00
0x12
8位常数
00000100100000000000000000000000
ARM指令集
ARM处理器的指令集ARM处理器的指令找了好久都没有找到完整版,在这里我把所有用过的ARM指令都整理下来,方便大家参考。
ADC(不更改状态寄存器): 带进位的加法(Addition with Carry)ADCS(更改状态寄存器)R1, R5, R9 ; R1=R5+R9,带进位ADD : 加法(Addition)ADD R0, R1, #256 ; R0 = R1 + 256AND : 逻辑与(logical AND)AND R0, R0, #3 ; R0 = 保持R0 的位0和1,丢弃其余的位。
BIC : 位清除(Bit Clear)BIC R0, R0, #%1011 ; 清除R0 中的位0、1、和3。
保持其余的不变。
EOR : 逻辑异或(logical Exclusive OR)EOR R0, R0, #3 ; 反转R0 中的位0 和1MOV : 传送(Move)MOV PC, R14 ; PC=R14MOVS PC, R14 ; 退出到调用者并恢复标志位(不遵从32-bit 体系)MVN : 传送取反的值(MoveNegative)MVN R0, #4 ; R0 = -5ORR : 逻辑或(logical OR)ORR R0, R0, #3 ; 设置R0 中位0 和1RSB : 反向减法(Reverse Subtraction)RSB R0, R1, R2 ; R0 = R2 - R1RSC : 带借位的反向减法(Reverse Subtraction with Carry)RSC{条件}{S} <dest>, <op 1>, <op 2>dest = op_2 - op_1 - !carrySBC : 带借位的减法(Subtraction with Carry)SBC{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 - op_2 - !carrySUB : 减法(Subtraction)SUB R0, R1, #256 ; R0 = R1 - 256ARM 处理器组建了可以与数据处理指令(ADC、ADD、AND、BIC、CMN、CMP、EOR、MOV、MVN、ORR、RSB、SBC、SUB、TEQ、TST)一起使用的桶式移位器(barrel shifter)。
ARM总汇编指令集
ARM汇编指令集1 跳转指令1.1 跳转指令B:B LABLE ;跳转到标号LABEL处B 0X1111 ;跳转到绝对地址0X1111处1.2 带连接的跳转指令 BL:START …BL NEXT ;跳转到标号NEXT处,同时保存当前PC到R14中… ;返回地址…NEXT… ;子程序入口MOV PC,R14 ;返回1.3 带状态切换的跳转指令BX:MOV R0, #0X0201BX R0 ;程序跳转到0x0200处,微处理器切换到Thumb状态(地址必须是4的倍数,否则产生不可预知的后果)2算术运算指令2.1不带进位加法指令ADDADD R0, R1, R2 ;R0← (R1)+(R2)ADD R0, R1, #112 ;R0← (R1)+ 112ADD R0, R1, R2, LSL #1 ;R0←(R1)+(R2<<1) ;将R2中的值左移1位,再与R1值相加,结果送R02.2带进位加法指令 ADCADDS R0, R3, R6 ;加最低位字节,不带进位ADCS R1, R4, R7 ;加第二个字,带进位ADCS R2, R5,R8 ;加第三个字,带进位;三句话实现了96bit加法运算,由于ARM寄存器宽度只有32bit所以分三次相加2.3 不带进位减法指令SUB ;S—进位标志SUB R0, R1, R2 ;R0←(R1)- (R2)SUB R0, R1, #112 ;R0←(R1)- 112SUB R0, R1 ,R2 LSL#1 ;R0←(R1)- (R2<<1)2.4 带进位减法指令SBCSUBS R0, R3, R6 ;减最低位字节,不带进位SBCS R1, R4, R7 ;减第二个字,带进位SBCS R2, R5, R8 ;减第三个字,带进位;三句话实现了96bit减法运算,由于ARM寄存器宽度只有32bit所以分三次相减2.5 不带进位逆向减法指令RSBRSB R0, R1, R2 ;R0←(R2)- (R1)RSB R0, R1, #112 ;R0← 112- (R1)RSB R0, R1, R2, LSL#1 ;R0←(R2<<1)-R12.6 带进位逆向减法指令RSCRSBS R0, R6, R3 ;减最低字节的字,不带进位RSCS R1, R7, R4 ;减第二个字,带进位RSCS R2, R8, R5 ;减第三个字,带进位;三句话实现了96bit减法运算,由于ARM寄存器宽度只有32bit所以分三次相减2.732位乘法指令MULMUL R0, R1, R2 ;R0←(R1) X(R2)MULS R0, R1, R2 ;R0←(R1) X(R2) ;更新CPSR标志位2.8乘-累加指令 MLAMLA R0, R1, R2, R3 ;R0←(R1) X(R2)+(R3)MLAS R0, R1, R2, R3 ;R0←(R1) X(R2)+(R3) ;更新CPSR标志位2.9 无符号数长乘指令 UMULLMOV R5, #0X01MOV R8, #0X02UMULL R0, R1, R5, R8 ;(R1) (R0)←(R5)X(R8);UMULL指令实现64bit无符号数乘法2.10无符号长乘-累加指令 UMLALMOV R0, #0X01MOV R1, #0X02MOV R5, #0X01MOV R8, #0X02UMLAL R0, R1, R5, R8 ;R0←(R0) +(R5)X(R8)低字节;R1←(R1) +(R5) X(R8)高字节;UMLAL 指令为64位无符号乘-累加指令2.11有符号长乘指令SMULLMOV R5, #0X01MOV R8, #0X02SMULL R0, R1, R5, R8 ;(R1) (R0)←(R5)X(R8);SMULL指令实现64bit有符号数乘法2.12 有符号长乘-累加指令 SMLALMOV R0, #0X01MOV R1, #0X02MOV R5, #0X01MOV R8, #0X02SMLAL R0, R1, R5, R8 ;R0←(R0) +(R5)X(R8)低字节;R1←(R1) +(R5) X(R8)高字节; SMLAL 指令为64位有符号乘-累加指令2.13 比较指令 CMPCMP R1, #0X10 ;比较BGT TAG ;R1> #0X10转到TAG标号处……2.14负数比较指令 CMNCMN R0, #1 ;判断R0中的值是否为1的补码,是则置标志位Z为13逻辑运算指令3.1“与”指令 ANDMOV R0, 0XFFAND R0, R0, #3 ;取出R0的最低2bit3.2“或”指令 ORRMOV R0, 0XFFORR R0, R0, #33.3“异或”指令 EORMOV R0, 0XFFEOR R0, R0, #3 ;R0←(R0)^(0X03)3.4位清除指令 BICMOV R0, 0XFFBIC R0, R0, #B11 ;寄存器R0的低2bit被清零3.5测试比较指令 TSTTST R1, #b11 ;测试寄存器R1中的第0位和第1位,更新CPSR中标志位,应用中会在TST指令后加一条跳转指令。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ARM指令集详解ARM可以用两套指令集:ARM指令集和Thumb指令集。
本文介绍ARM指令集。
在介绍ARM指令集之前,先介绍指令的格式。
1 指令格式(1)基本格式<opcode>{<cond>}{S} <Rd>,<Rn>{,<opcode2>}其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,而{<cond>}为指令执行条件,是可选的,如果不写则使用默认条件AL(无条件执行)。
opcode 指令助记符,如LDR,STR 等cond 执行条件,如EQ,NE 等S 是否影响CPSR 寄存器的值,书写时影响CPSR,否则不影响Rd 目标寄存器Rn 第一个操作数的寄存器operand2 第二个操作数指令格式举例如下:LDR R0,[R1] ;读取R1 地址上的存储器单元内容,执行条件ALBEQ DATAEVEN ;跳转指令,执行条件EQ,即相等跳转到DATAEVENADDS R1,R1,#1 ;加法指令,R1+1=R1 影响CPSR 寄存器,带有SSUBNES R1,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等都是非法常量。
常数表达式应用举例如下:MOV R0,#1 ;R0=1AND R1,R2,#0x0F ;R2 与0x0F,结果保存在R1LDR R0,[R1],#-4 ;读取R1 地址上的存储器单元内容,且R1=R1-4Rm寄存器方式,在寄存器方式下操作数即为寄存器的数值。
寄存器方式应用举例:SUB R1,R1,R2 ;R1-R2=>R1MOV PC,R0 ;PC=R0,程序跳转到指定地址LDR R0,[R1],-R2 ;读取R1 地址上的存储器单元内容并存入R0,且R1=R1-R2Rm, 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位type Rs 其中,type 为ASR,LSL,和ROR 中的一种;Rs 偏移量寄存器,低8位有效,若其值大于或等于32,则第2 个操作数的结果为0(ASR、ROR例外)。
寄存器偏移方式应用举例:ADD R1,R1,R1,LSL #3 ;R1=R1*9SUB R1,R1,R2,LSR#2 ;R1=R1-R2*4R15 为处理器的程序计数器PC,一般不要对其进行操作,而且有些指令是不允许使用R15,如UMULL 指令。
(3)条件码使用指令条件码,可实现高效的逻辑操作,提高代码效率。
表A-1给出条件码表。
表A-1 条件码表对于Thumb指令集,只有B 指令具有条件码执行功能,此指令条件码同表A-?,但如果为无条件执行时,条件码助记符“AL”不能在指令中书写。
条件码应用举例如下:比较两个值大小,并进行相应加1 处理,C 代码为:if(a>b)a++ ;else b++ ;对应的ARM 指令如下。
其中R0为a,R1为b。
CMP R0,R1 ; R0 与R1 比较ADDHI R0,R0,#1 ; 若R0>R1,则R0=R0+1ADDLS R1,R1,#1 ;若R0<=R1,则R1=R1+1若两个条件均成立,则将这两个数值相加,C代码为:If((a!=10)&&(b!=20)) a=a+b;对应的ARM 指令如下,其中R0 为a,R1 为b。
CMP R0,#10 ; 比较R0 是否为10CMPNE R1,#20 ; 若R0 不为10,则比较R1 是否20ADDNE R0,R0,R1 ; 若R0 不为10 且R1 不为20,指令执行,R0=R0+R12 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) 立即数。
立即数可以是一个无符号数值,这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
指令举例如下:LDR R1,[R0,#0x12] ;将R0+0x12 地址处的数据读出,保存到R1 中(R0 的值不变)LDR R1,[R0,#-0x12];将R0-0x12 地址处的数据读出,保存到R1 中(R0 的值不变)LDR R1,[R0] ;将R0 地址处的数据读出,保存到R1 中(零偏移)(2)寄存器。
寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
指令举例值。
指令举例如下:LDR R1,[R0,R2] ;将R0+R2 地址的数据计读出,保存到R1 中(R0 的值不变)LDR R1,[R0,-R2] ;将R0-R2 地址处的数据计读出,保存到R1 中(R0 的值不变)(3)寄存器及移位常数。
寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
指令举例如下:LDR R1,[R0,R2,LSL #2] ;将R0+R2*4地址处的数据读出,保存到R1中(R0,R2的值不变)LDR R1,[R0,-R2,LSL #2];将R0-R2*4地址处的数据计读出,保存到R1中(R0,R2的值不变)从寻址方式的地址计算方法分,加载/存储指令有以下4 种形式:(1)零偏移。
Rn 的值作为传送数据的地址,即地址偏移量为0。
指令举例如下:LDR Rd,[Rn](2)前索引偏移。
在数据传送之前,将偏移量加到Rn 中,其结果作为传送数据的存储地址。
若使用后缀“!”,则结果写回到Rn 中,且Rn 值不允许为R15。
指令举例如下:LDR Rd,[Rn,#0x04]!LDR Rd,[Rn,#-0x04](3)程序相对偏移。
程序相对偏移是索引形式的另一个版本。
汇编器由PC 寄存器计算偏移量,并将PC 寄存器作为Rn 生成前索引指令。
不能使用后缀“!”。
指令举例如下:LDR Rd,label ;label 为程序标号,label 必须是在当前指令的±4KB 范围内(4) 后索引偏移。
Rn 的值用做传送数据的存储地址。
在数据传送后,将偏移量与Rn相加,结果写回到Rn 中。
Rn 不允许是R15。
指令举例如下:LDR Rd,[Rn],#0x04地址对准--大多数情况下,必须保证用于32 位传送的地址是32 位对准的。
加载/存储字和无符号字节指令举例如下:LDR R2,[R5] ;加载R5 指定地址上的数据(字),放入R2 中STR R1,[R0,#0x04] ;将R1 的数据存储到R0+0x04 存储单元,R0 值不变LDRB R3,[R2],#1 ;读取R2 地址上的一字节数据,并保存到R3 中,R2=R3+1STRB R6,[R7] ;读R6 的数据保存到R7 指定的地址中,只存储一字节数据加载/存储半字和带符号字节。
这类LDR/STR 指令可能加载带符字节\加载带符号半字、加载/存储无符号半字。
偏移量格式、寻址方式与加载/存储字和无符号字节指令相同。
指令格式如下:LDR{cond}SB Rd,<地址> ;加载指定地址上的数据(带符号字节),放入Rd 中LDR{cond}SH Rd,<地址> ;加载指定地址上的数据(带符号字节),放入Rd 中LDR{cond}H Rd,<地址> ;加载半字数据,放入Rd中,即Rd最低16 位有效,高16位清零STR{cond}H Rd,<地址> ;存储半字数据,要存储的数据在Rd,最低16 位有效说明:带符号位半字/字节加载是指带符号位加载扩展到32 位;无符号位半字加载是指零扩展到32 位。
地址对准--对半字传送的地址必须为偶数。
非半字对准的半字加载将使Rd 内容不可靠,非半字对准的半字存储将使指定地址的2 字节存储内容不可靠。
加载/存储半字和带符号字节指令举例如下:LDRSB R1[R0,R3] ;将R0+R3 地址上的字节数据读出到R1,高24 位用符号位扩展LDRSH R1,[R9] ;将R9 地址上的半字数据读出到R1,高16 位用符号位扩展LDRH R6,[R2],#2 ;将R2 地址上的半字数据读出到R6,高16 位用零扩展,R2=R2+1SHRH R1,[R0,#2]!;将R1 的数据保存到R2+2 地址中,只存储低2 字节数据,R0=R0+2LDR/STR 指令用于对内存变量的访问,内存缓冲区数据的访问、查表、外设的控制操作等等,若使用LDR 指令加载数据到PC 寄存器,则实现程序跳转功能,这样也就实现了程序散转。