常用ARM v4指令集及汇编
- 格式:docx
- 大小:254.14 KB
- 文档页数:91
ARM常用汇编指令arm 2009-12-19 15:51:59 阅读113 评论0 字号:大中小LDR 和STR——用于字和无符号字节指令格式:LDR/STR{cond}{T} Rd,<地址>LDR/STR{cond}B{T} Rd,<地址>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。
地址部分可用的形式有4种:∙零偏移(zero offset) [Rn],Rn的值作为传送数据的地址。
如:LDR R0,[R1];∙前索引偏移(pre-indexed offset) [Rn,Flexoffset]{!}在数据传送之前,将偏移量Flexoffse t加到Rn 中。
其结果作为传送数据的存储器地址。
若使用后缀“!”,则结果写回到Rn 中,且Rn 不允许是R15,如:LDRB R0,[R1,#8]LDR R0,[R1,#8]!∙程序相对偏移(program relative) label(label 必须是在当前指令的土4KB范围内) 。
程序相对偏移是前索引形式的另一种版本。
从PC 计算偏移量,并将PC 作为Rn 生成前索引指令,不能使用后缀“!”,如:LDR R0,place ;place地址装入R0∙后索引偏移(post-indexed offset) [Rn],Flexoffset。
arm汇编逻辑指令-回复ARM汇编逻辑指令ARM汇编逻辑指令是一种基于RISC(Reduced Instruction Set Computing)的指令集架构,在数字电子设备中被广泛使用。
逻辑指令主要用于实现基本的逻辑操作,例如布尔运算、比较和分支跳转等。
本文将深入探讨ARM汇编逻辑指令的各个方面,包括指令格式、操作数和指令示例等。
一、指令格式ARM汇编逻辑指令的指令格式通常包括操作码、目标寄存器和操作数等字段。
下面是一个典型的ARM汇编逻辑指令的格式:<操作码>{xx}{cond} <目标寄存器>, <操作数1>, <操作数2>其中,操作码用于指定具体的逻辑操作,xx字段用于指定操作的类型(例如AND、OR或XOR等),cond字段用于指定条件执行的条件码,目标寄存器用于存储运算结果,操作数1和操作数2分别是参与运算的操作数。
二、操作数ARM汇编逻辑指令的操作数可以是寄存器或立即数。
寄存器是存储在CPU内部的高速存储器单元,用于存储临时数据。
ARM架构通常提供了16个通用寄存器(R0-R15),其中R0-R7用于存储一般性目的数据,R8-R15用于存储特殊用途数据。
立即数是直接写在指令中的常数值,通常用于表示较小的数据。
立即数的宽度取决于具体的指令和操作码。
例如,对于AND指令,立即数可以是8位或32位的。
三、指令示例以下是一些常见的ARM汇编逻辑指令示例:1. AND指令AND指令用于将两个操作数逐位进行与运算,并将结果存储在目标寄存器中。
例如,下面的指令将执行R1 = R2 AND 3:AND R1, R2, 32. OR指令OR指令用于将两个操作数逐位进行或运算,并将结果存储在目标寄存器中。
例如,下面的指令将执行R1 = R2 OR R3:ORR R1, R2, R33. XOR指令XOR指令用于将两个操作数逐位进行异或运算,并将结果存储在目标寄存器中。
算术和逻辑指令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 后缀来更改进位标志。
ADD : 加法(Add ition)ADD{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 + op_2ADD将把两个操作数加起来,把结果放置到目的寄存器中。
操作数 1 是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即值:ADD R0, R1, R2 ; R0 = R1 + R2ADD R0, R1, #256 ; R0 = R1 + 256ADD R0, R2, R3,LSL#1 ; R0 = R2 + (R3 << 1)加法可以在有符号和无符号数上进行。
AND : 逻辑与(logical AND)AND{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 AND op_2AND将在两个操作数上进行逻辑与,把结果放置到目的寄存器中;对屏蔽你要在上面工作的位很有用。
arm汇编指令作者不详,如果作者看到请与我联系...ARM指令系统特点ARM指令系统属于RISC指令系统。
标准的ARM指令每条都是32位长,有些ARM核还可以执⾏Thmub指令集,该指令集是ARM指令集的⼦集,每条指令只有16位。
1 数据类型ARM处理器⼀般⽀持下列6种数据类型:l8位有符号字节类型数据;l8位⽆符号字节类型数据;l16位有符号半字类型数据;l16位⽆符号半字类型数据;l32位有符号字类型数据;l32位⽆符号字类型数据;有些ARM处理器不⽀持半字和有符号字节数据类型。
在ARM内部,所有指令都是32操作数据。
短的数据数据类型只有在数据传送类指令中才被⽀持当1个字节数据取出后,被扩展到32位,在内部数据处理时,作为32位的什进⾏处理,并且ARM指令以字为边界。
所有Thumb指令都是16位指令时,并且以2个字节为边界。
ARM协处理器可以⽀持另外的数据类型,包括⼀套浮点数据类型,ARM的核并没有明确的⽀持。
2 存储器组织图3-1所⽰为存储器组织。
ARM这的地址的低三下四位必须为00,半字地址的最低位为0。
字的内容在存储器中的存放通常有两种⽅式,即⼩端(little-endian)和⼤端(big-endian),这两种⽅式的不同在于最低位字节的地址是否在最⾼位字节的地址之前。
⼩端⽅式每个字的低位字节在后,例如0x12345678⼩端⽅式存放如下:地址内容A 78A+1 56A+2 34A+3 12⼤端⽅式的存放如下:地址内容A 12A+1 34A+2 56A+3 78⼤多数的ARM处理器芯⽚都不得可以⽀持上⾯两种⽅式,⼀般缺省为⼩端。
2322212019181716word1615141312half-world12 half-word14111098word87654byte6 half-word43210byte3 byte2 byte1 byte02021222316171819word1612131415half-world12 half-word14891011word84567Byte5 half-word6Byte0 byte1 byte2 byte3(a)⼩端存储器组织(b)⼤端存储器组织图3-1 存储器组织3 ARM指令特点1.每条指令的多功能ARM指令⼀个重要的特点是它所有的指令都带有条件,例如⽤户可以测试某个寄存器的什但是直到下次使⽤同⼀条件进⾏测试时,才能有条件的执⾏这些指令。
arm 汇编指令一、arm 汇编简介1.1 什么是 arm 汇编1.2 arm 汇编的应用领域1.3 arm 汇编与高级语言的对比二、arm 汇编基础2.1 寄存器2.1.1 通用寄存器2.1.2 特殊寄存器2.2 数据传输指令2.2.1 加载指令2.2.2 存储指令2.3 算术指令2.3.1 加法指令2.3.2 减法指令三、arm 汇编进阶3.1 分支指令3.1.1 无条件分支3.1.2 有条件分支3.2 比较指令3.2.1 比较指令的作用3.2.2 比较指令的使用方法3.3 位操作指令3.3.1 与操作3.3.2 或操作3.3.3 异或操作四、arm 汇编优化技巧4.1 减少存取操作4.2 使用预处理器4.3 循环展开4.4 减少分支操作4.5 使用内联汇编五、arm 汇编的应用案例5.1 arm 汇编在嵌入式系统中的应用5.2 arm 汇编在图形处理中的应用5.3 arm 汇编在操作系统中的应用六、总结6.1 arm 汇编的优势和不足6.2 arm 汇编的未来发展6.3 arm 汇编学习的建议arm 汇编指令一、arm 汇编简介1.1 什么是 arm 汇编arm 汇编是一种底层的编程语言,用于直接操作处理器的指令集。
它与高级语言相比更接近机器语言,能够更加精细地控制硬件资源。
arm 汇编通常用于需要对性能和资源进行高度优化的场景,如嵌入式系统开发、驱动程序编写和底层图形处理等。
1.2 arm 汇编的应用领域arm 汇编广泛应用于各种领域,包括嵌入式系统、移动设备、游戏开发、图形处理、操作系统等。
由于 arm 汇编的高效性和精确性,它能够在这些领域中发挥重要作用。
例如,在嵌入式系统中,arm 汇编可以直接访问硬件资源,提供更高的执行效率和更低的资源消耗。
1.3 arm 汇编与高级语言的对比arm 汇编与高级语言相比有着明显的区别。
在高级语言中,程序员不需要关注底层的机器细节,只需要编写抽象的代码即可。
必须知道的ARM指令集常用的ARM指令集我们知道CPU能直接识别的是机器码,也就是0和1组合的东东。
不同的组合代表不同的含义,CPU就做不同的事情。
按照道理来说,我们写的代码都应该是0和1组成的东西,但是如果真的是那样,那结果....。
人类是聪明的,发明了汇编语言,汇编语言是用一些助记符,来代替机器码。
当然,汇编语言是不能给CPU识别的,需要编译器将其编译成机器码。
汇编语言是和特定的CPU关联的,不同的CPU对应不同的汇编指令。
好在,现在大多数嵌入式CPU都是使用ARM架构的,这样我们只需要学会ARM的汇编指令集,我们写的汇编程序就可以在这些使用ARM 架构的CPU上运行。
ARM的汇编指令很多,很难将其全部记住,其实也没必要,我们只需要学会一些常用的ARM汇编指令即可。
其他的用到再去查即可。
下面我们就开始,必须知道的ARM指令学习。
一、ARM指令格式ARM指令的基本格式如下:其中<>号内是必须的,{}号内的项是可选的。
各项的说明如下:opcode :指令助记符cond :执行条件S :是否影响CPSR寄存器的值Rd :目标寄存器(一般用来存放指令执行最后的结果)Rn :第1个操作数的寄存器operand2 :第2个操作数1. 其中,我们必须要研究一下operand2这个操作数,它有如下表现形式(1)#immed_8r——常数表达式该常数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到,这个数我们也成立即数。
例如:MOV R0,#1AND R1,R2,#0x0例如:0x04800000它可以拿0x12循环右移位10位得到,所以它是一个合法的立即数。
有人会问,是不是每次我都要去判断一个数是不是立即数,我就需要从0x00~0xff里面找出一个数,将它循环右移偶数个位看是否能的得到,那太麻烦了。
有没有一些快速识别的方法呢?肯定是有的呀,当然也不能完全依赖哦,最好就是拿编译器验证,不是,编译器就会报错。
目的操作数1 + 操作数2 + !C 目的操作数1 + 操作数2目的操作数1 & 操作数2跳转至目的地, PC目标地址(PC R14,跳转)(PC R14,跳转并切换为thumb)目的操作数1 XOR 操作数2 LDC P3,C4,[R0] ;P3: C4 [R0]register MemeryRegister<存储器地址>目的操作数1 * 操作数2 + 操作数3 目的源操作数Register状态寄存器CPSR或SPSR<域> 操作数结果MODE(2^32),目的操作数1 * 操作数2 目的~(取反) 源操作数目的操作数1 OR 操作数2目的操作数2 - 操作数1目的操作数2 - 操作数1 - !C=64目的L(操作1 * 操作2)L+ 目的L 目的H(操作1 * 操作2)H +目的HSTC P3,C4,[R0] ;P3:C4[R0]Mem Register<存储器地址>Register 目的操作数1 –操作数2ARM汇编伪指令ARM条件码CPSR位[31:24]为条件位域,用f表示;位[23:16]为状态位域,用s表示;位[15:8] 为扩展位域,用x表示;位[7:0] 为控制位域,用c表示;与指令MSR相关关于移位中断向量表APCS寄存器使用约定Load and Store指令LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。
LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0。
LDR R0,[R1,R2] !;将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1。
LDR R0,[R1,#8] !;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址 R1+8写入R1。
LDR R0,[R1],R2 ;将存储器地址为R1的字数据读入寄存器R0,并将新地址 R1+R2写入R1。
常用ARM v4指令集及汇编前言零零散散用了大概一周的时间,在《常用ARM指令集及汇编》(2003年12月1日)的基础上,大致学习了一遍ARM指令集和汇编,看的过程当中更正了一些错误的地方,并结合其它资料适当添加了一些内容,也做了一些删减,现分享出来,希望能帮助到需要的人。
文中必然还有一些错误还有待改进,有些地方还需要解释的更加详细,本人精力有限,希望有心的读者,订正并增加注释,最好也分享出来,以方便大家对ARM指令的深入理解。
作为刚入行的新手,不谦虚的推荐几本书:《ARM体系结构与编程-杜春雷》,《嵌入式系统体系结构、编程与设计-Raj Kamal著,贾建斌译》,《嵌入式系统:采用公开源代码和StrongARM_XScale处理器-毛德操》。
这几本书到底好不好,看个人需求和喜好吧,仁者见仁智者见智。
最后,感谢《常用ARM指令集及汇编》的原作者和其它资料的作者让我有机会学习我不熟悉的东西,谢谢。
learllp2015-11-09目录常用ARM v4指令集及汇编 (I)前言 ............................................................................................................................. I I 目录 ............................................................................................................................ I II ARM v4指令集及汇编.. (1)一、ARM处理器寻址方式 (1)寄存器寻址 (1)立即寻址 (1)寄存器偏移寻址 (2)寄存器间接寻址 (2)基址寻址 (3)多寄存器寻址 (3)堆栈寻址 (3)块拷贝寻址 (4)相对寻址 (4)二、指令集介绍 (5)ARM指令集 (5)指令格式 (5)基本格式 (5)第2个操作数 (5)1.#immed_8r常数表达式 (5)2.Rm 寄存器方式 (6)3.Rm,shift寄存器移位方式 (6)条件码 (7)ARM 存储器访问指令 (8)◆LDR和STR (8)◆LDM和STM (11)◆SWP (14)ARM 数据处理指令 (15)数据传送指令 (15)算术逻辑运算指令 (16)ARM 跳转指令 (21)ARM 协处理器指令 (22)ARM 杂项指令 (24)ARM 伪指令 (26)Thumb 指令集 (29)Thumb 指令集与ARM 指令集的区别 (29)跳转指令 (29)数据处理指令 (29)单寄存器加载和存储指令 (29)批量寄存器加载和存储指令 (30)Thumb 存储器访问指令 (30)伪指令 (31)符号定义伪指令 (32)数据定义伪指令 (34)报告伪指令 (39)汇编控制伪指令 (41)杂项伪指令 (43)◆AREA (45)◆CODE16 和CODE32 (46)◆END (46)◆ENTRY (46)◆EQU (47)◆EXPORT 和GLOBAL (47)◆IMPORT 和EXTERN (47)◆GET 和INCLUDE (48)◆INCBIN (48)◆KEEP (49)◆NOFP (49)◆REQUIRE (49)◆PEQUIRE8 和PRESERVE8 (49)◆RN (49)◆ROUT (50)ARM 伪指令 (50)◆ADR (50)◆NOP (51)◆LDFD (51)◆LDFS (51)三、ARM汇编程序设计 (51)文件格式 (51)ARM 汇编的一些规范 (52)汇编语句格式 (52)标号 (52)基于PC 的标号 (53)基于寄存器的标号 (53)绝对地址 (53)局部标号 (53)符号 (54)常量 (54)数字常数 (54)字符常量 (54)布尔常量 (55)段定义 (55)宏定义及其作用 (55)子程序的调用 (56)数据比较跳转 (57)循环 (57)数据块复制 (57)栈操作 (58)特殊寄存器定义及应用 (58)散转功能 (58)查表操作 (58)长跳转 (59)对信号量的支持 (59)伪指令使用 (59)一个完整的例子 (59)外围部件控制 (60)四、C与汇编混合编程 (60)内嵌汇编 (60)内嵌汇编的指令用法 (62)内嵌汇编器与armasm 汇编器的差异 (63)内嵌汇编注意事项 (63)访问全局变量 (65)C与汇编相互调用 (65)寄存器的使用规则 (66)堆栈使用规则 (66)参数传递规则 (66)C程序调用汇编程序 (67)调用汇编的C函数: (67)汇编程序调用C程序 (68)五、ARM 指令集列表 (69)ARM 存储器访问指令表列表 (69)ARM 数据处理指令列表 (70)ARM 乘法指令列表 (71)ARM 跳转指令列表 (72)ARM 协处理器指令列表 (73)ARM 杂项指令列表 (74)ARM 伪指令列表 (75)六、Thumb 指令集列表 (120)Thumb 存储器访问指令列表 (120)Thumb 数据处理指令列表 (121)Thumb 跳转指令及软中断指令列表 (122)Thumb 伪指令列表 (123)七、汇编预定义变量及伪指令 (124)预定义的寄存器和协处理器名 (124)通用寄存器 (124)程序状态寄存器 (124)浮点数寄存器 (124)协处理器及协处理器寄存器 (125)八、内置变量列表 (125)九、伪指令列表 (126)十、指令条件码列表 (128)十一、CPSR 和S PSR 分配图 (129)ARM v4指令集及汇编ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制较为简单,具有32 位ARM 指令集和16 位Thumb 指令集。
ARM 指令集效率高,但是代码密度低,而Thumb 指令集具有更好的代码密度,却仍然保持ARM 的大多数性能上的优势,它是ARM 指令集的子集,主要用于编译器设计。
所有ARM 指令都是可以有条件执行的,而Thumb 指令仅有一条指令具备条件执行功能。
ARM 程序和Thumb 程序可相互调用,相互之间的状态切换开销几乎为零。
一、ARM处理器寻址方式寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM 处理器有9 种基本寻址方式。
寄存器寻址操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作。
寄存器寻址指令举例如下:MOV R1,R2 ;R2 -> R1SUB R0,R1,R2 ;R1 - R2->R0立即寻址立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数)。
立即寻址指令举例如下:SUBS R0,R0,#1 ;R0–1 ->R0MOV R0,#0xff00 ;0xff00 ->R0立即数要以“#”为前缀,表示16 进制数值时以“0x”表示。
1寄存器偏移寻址寄存器偏移寻址是ARM 指令集特有的寻址方式,当第 2 操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。
寄存器偏移寻址方式指令举例如下:MOV R0,R2,LSL #3 ;R2 的值左移3 位,结果放入R0,即R0 = R2 * 8ANDS R1,R1,R2,LSL R3 ;R2 的值左移R3 位,然后和R1 相与操作,结果放入R1 可采用的移位操作如下:LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补0。
LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补0。
ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补0,否则补1。
ROR:循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位。
RRX:带扩展的循环右移(Rotate Right extended by 1place),操作数右移一位,高端空出的位用原 C 标志值填充。
各移位操作如下图所示:寄存器间接寻址寄存器间接寻址指令中的地址码给出的是一个通用寄存器编号,所需要的操作数2保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。
寄存器间接寻址指令举例如下:LDR R1,[R2] ;将R2 中的数值作为地址,取出此地址中的数据保存在R1 中SWP R1,R1,[R2];将如中的数值作为地址,取出此地址中的数值与R1 中的值交换基址寻址基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。
基址寻址指令举例如下:LDR R2,[R3,#0x0F] ;将R3中的数值加0x0F作为地址,将该地址保存在R2中STR R1,[R0,#-2] ;将R0中的数值减2作为地址,把R1中的内容保存到此地址多寄存器寻址多寄存器寻址就是一次可以传送几个寄存器值,允许一条指令传送16 个寄存器的任何子集或所有寄存器。
多寄存器寻址指令举例如下:LDMIA R1!,{R2-R7,R12} ;将[ R1] 单元中的数据读出到R2-R7,R12,R1自动加1STMIA R0!,{R3-R6,R10} ;将R3-R6,R10中的数据保存到[R0],R0自动加1使用多寄存器寻址指令时,寄存器子集的顺序由小到大的顺序排列,连续的寄存器可用“-”连接,否则用“,”分隔书写。
堆栈寻址堆栈是特定顺序进行存取的存储区,操作顺序分为“后进先出”和“先进后出”,堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元就是堆栈的栈顶。
存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈。
向下生长:向低地址方向生长,称为递减堆栈。
堆栈指针指向最后压入堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,称为空堆栈。
这样就有4种类型的堆栈表示。
满递增:堆栈通过递增存储器的地址向上增长,堆栈指针指向堆栈内含有效数据项的最高地址。
指令如LDMFA,STMFA 等。
空递增:堆栈通过递增存储器的地址向上增长,堆栈指针指向堆栈内的第一个空位置。
指令如LDMEA,STMEA 等。
3满递减:堆栈通过递减存储器的地址向下增长,堆栈指针指向堆栈内含有效数据项的最低地址。