第3章[1].4_ARM汇编
ARM汇编手册

ARM 汇编手册
版权声明
本手册为北京顶嵌开源科技有限公司内部培训资料,仅 供本公司内部学习使用,在未经本公司授权的情况下,请勿 用作任何商业用途。
400-661-5264
专注嵌入式 Linux 技术
北京顶嵌开源科技有限公司
目录
寄存器装载和存储.............................................................................................................................5 传送单一数据.............................................................................................................................5 传送多个数据.............................................................................................................................7 SWP : 单一数据交换................................................................................................................ 9
乘法指令........................................................................................................................................... 19 MLA : 带累加的乘法..............................................................................................................19 MUL : 乘法..............................................................................................................................19
ARM的汇编指令讲解

汇编知识点的要求:1、能看的懂2、可以做修改3、不需要用汇编直接编写程序汇编代码的应用场合:1、ARM的启动代码必须要汇编,如:uboot最开始初始化硬件的代码2、内核在最开始初始化的位置。
一、ARM汇编指令的编码格式1、编码格式ARM汇编指令编译成机器码以后,机器码的长度是32bits,这32bits的编码有一个固定的格式。
不同ARM 汇编指令,编码格式不同。
2、举例C:if(a==10)a++;elsea--;汇编1:CMP R0, #10;ADDEQ R0,R0,#1SUBNE R0,R0,#1汇编2SUBS R1, R0, #10; //S ---运算的结果会影响条件码标志位:CPSR:NZCVADDEQ R0,R0,#1SUBNE R0,R0,#1提示:空指令NOP,实际上是占用CPU的时间,但是执行后,没有什么意义。
NOP ---- MOV R0,R03、条件码标识10 -10Z = 1C = 0N = 0V = 0=================================================================================二、ARM的寻址方式1、立即数寻址操作数,有立即数。
ADD R0,R0,#1MOV R1,#10ORR R1,R1,#0xf @ R1=R1 | 0xfBIC R1,R1,#0xf @R1 = R1&(~(0xf))错误:ADD R1,#1,#2注意:立即数合法的条件在ARM汇编指令中,并不是所有的立即数,立即数是有一定的限制的。
什么样的立即数是合法的???1、如果一个立即数是小于256的(即该立即数是8bits以内的,0~255),该立即数是合法的。
2、如果一个立即数是大于等于256,该立即数经过循环左移偶数位,可以得到一个小于256的数,则该立即数合法。
256 = 0x100 ------→左移20位0x10000000----→左移4 0x1 合法0x111 非法0x102 非法0x104 合法0xfff0xff000x120000x4500000xab原因:在数据处理指令编码的时候,立即数用12bits来表示:高4bits:循环左移左移偶数位除以2低8bits:循环左移后的结果。
arm汇编指令乘法

arm汇编指令乘法摘要:一、引言二、ARM汇编指令简介1.ARM汇编指令基本概念2.ARM汇编指令分类三、乘法指令在ARM汇编中的表示1.立即数乘法指令2.寄存器乘法指令3.内存乘法指令四、乘法指令的执行过程1.立即数乘法指令执行过程2.寄存器乘法指令执行过程3.内存乘法指令执行过程五、乘法指令的应用实例1.立即数乘法实例2.寄存器乘法实例3.内存乘法实例六、总结正文:一、引言在ARM汇编语言中,乘法指令是用于实现两个数相乘的指令。
了解乘法指令的表示和执行过程,以及其在实际编程中的应用,对于掌握ARM汇编语言至关重要。
二、ARM汇编指令简介1.ARM汇编指令基本概念ARM汇编指令是一种低级编程语言,用于控制ARM处理器执行各种操作。
它与机器码一一对应,通过汇编器将汇编指令转换成机器码,供处理器执行。
2.ARM汇编指令分类ARM汇编指令主要分为四类:数据传送指令、算术指令、逻辑指令和程序控制指令。
其中,乘法指令属于算术指令。
三、乘法指令在ARM汇编中的表示1.立即数乘法指令立即数乘法指令用于实现一个立即数与一个寄存器或内存单元相乘。
在ARM汇编中,立即数乘法指令用“`MOV`”指令表示,例如:```MOV r0, #5 ; r0 = r0 * 5```2.寄存器乘法指令寄存器乘法指令用于实现两个寄存器相乘。
在ARM汇编中,寄存器乘法指令用“`MUL`”指令表示,例如:```MUL r1, r2 ; r0 = r1 * r2```3.内存乘法指令内存乘法指令用于实现一个寄存器与一个内存单元相乘。
在ARM汇编中,内存乘法指令用“`MOV`”和“`MUL`”指令组合表示,例如:```MOV r0, [r1] ; r0 = *r1MUL r2, r0 ; r0 = r0 * r2```四、乘法指令的执行过程1.立即数乘法指令执行过程立即数乘法指令的执行过程较为简单,汇编器在编译时会直接将立即数与寄存器或内存单元相乘,并将结果存回原寄存器或内存单元。
《汇编语言程序设计 —基于ARM体系结构 (第4版)》教学课件—03ARM指令系统

图3-1程序设计语言的层次结构
为了提高程序设计的效率,人们提出了汇编语言的概念。将机器码用指令助记符表示,这样就比机器语言方便得多。不过,在使用汇编语言后,虽然编程的效率和程序的可读性都有所提高,但汇编语言同机器语言非常接近,它的书写风格在很大程度上取决于特定计算机的机器指令,所以它仍然是一种面向机器的语言。 为了更好地进行程序设计,提高程序设计的效率,人们又提出了高级语言程序设计的概念。如C、JAVA等,这类高级语言对问题的描述十分接近人们的习惯,并且还具有较强的通用性。这就给程序员带来极大的方便。当然这类高级语言在执行前必须转换为汇编语言或其它中间语言,最终转换为机器语言。通常有两
3.2 ARM汇编语言
3.2.1指令和指令格式3.2.2指令的可选后缀3.2.3指令的条件执行3.2.4 ARM指令分类
3.2.1指令和指令格式
1.指令和指令系统 指令是指示计算机进行某种操作的命令 指令的集合称为指令系统。指令系统的功能强弱在很大程度上决定了这类计算机智能 的高低,它集中地反映了微处理器的硬件功能和属性。2.指令的表示方法从形式上看,ARM指令在机器中的表示格式是用32位的二进制数表示。计算机根据二 进制代码去完成所需的操作,如ARM中有一条指令为:ADDEQS R0,R1,#8;其二进制代码形式为:
3.1 指令基础
3.1.1程序设计语言的层次结构3.1.2指令周期和时序3.1.3程序的执行过程
3.1.1程序设计语言的层次结构
计算机程序设计语言的层次结构如图3-1所示,分为机器语言级、汇编语言级、高级语言级,机器语言是与计算机硬件最为密切的一种语言,它由微程序解释机器指令统。这一级也是硬件级,是软件系统和硬件系统之间的纽带。
例如:在8MHz的ARM微处理器中,一个 S 周期是125ns,而一个 N 周期 是 250ns。应当注意到这些时序不是 ARM 的属性,而是内存系统 的属性。例如,一个 8MHz的ARM微处理器可以与一个给出125ns 的 N 周期的 RAM 系统相连接。处理器的速率是 8MHz 只是简单 的意味着如果你使任何类型的周期,在长度上小于 125ns 则它不 保证能够工作。图3-2显示一种ARM存储器周期时序。
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汇编⼊门指南本篇⽂章的⽬的是希望以⼀个例⼦的⽅式,能够不那么枯燥的的给⼤家简单介绍⼀下Android或iOS这些移动终端上ARM架构的CPU是如何执⾏ARM汇编指令的。
如果说程序员在学习任何⼀门语⾔的起点都是从学习写helloworld程序开始的,那么本篇⽂章希望的就是成为你学习ARM汇编的那第⼀篇⼊门教程,⼿把⼿的带着你⽤ARM汇编⼿写⼀个helloworld程序。
Hello, ARM⾸先我们这⾥是准备⽤GNU ARM汇编来⼿写⼀个ARM64架构的helloworld程序,那么需要先准备如下⼏个东西:⼀个⽂本编辑器,这⾥我们⽤vim .⼀个ARM64的编译器,这⾥我们⽤的是Android NDK⾥⾯⾃带的clang.伪指令以上准备好了,我们就可以开始新建⼀个⽂件名为main.S的纯⽂本⽂件,然后⽤任意⾃⼰最⼼爱的⽂本编辑器( 对于我⽽⾔它永远是vim) 来打开它,咱们先来起个头:.text.file 'main.c'.globl main // -- Begin function main.p2align 2这⾥我们使⽤是GNU ARM汇编,其中以.开头的是汇编指令 (Assembler Directive ) ⼜或被称为伪指令( Pseudo-operatio),因为它们不属于ARM指令,因此被称为伪指令,这⾥我们先尽量忽略它们,因为我们的主要学习⽬的是学习真正的ARM汇编指令,⽽不是这些伪东西,如果想了解它们可以参考⽂末的附录(伪指令参考表),这⾥只需要看懂其中的⼀句伪指令即可:.globl main这⼀句伪指令它定义了最重要的事情:在我们这个⽂件⾥⾯有⼀个叫做main名称的导出函数,它就是我们helloworld程序的⼊门函数。
main函数然后我们就可以来书写我们的helloworld程序的main函数:.typemain,@functionmain: // @main// %bb.0:subsp, sp, #32 // =32stpx29, x30, [sp, #16] // 16-byte Folded Spilladdx29, sp, #16 // =16movw8, wzrsturwzr, [x29, #-4]adrpx0, .L.straddx0, x0, :lo12:.L.strstrw8, [sp, #8] // 4-byte Folded Spillblprintfldrw8, [sp, #8] // 4-byte Folded Reloadmovw0, w8ldpx29, x30, [sp, #16] // 16-byte Folded Reloadaddsp, sp, #32 // =32ret在GNU ARM汇编⾥⾯所有以:结尾的都会视为标签 ( label ),在这⾥我们定义⼀个叫做main的标签,并且使⽤.type伪指令定义这个标签的类型是⼀个函数(function),到此我们就定义了我们的main函数。
arm的汇编 标准

arm的汇编标准
ARM的汇编语言规范如下:
1. 汇编语句格式:在ARM汇编中,所有标号必须在一行的顶格书写,其后面不要添加“:”,而所有指令均不能顶格书写。
2. 标识符大小写:ARM汇编器对标识符大小写敏感,书写标号及指令时字
母大小写要一致,一个ARM指令、伪指令、寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用。
3. 注释:注释使用“;”,注释内容由“;”开始到此行结束,注释可以在一行的顶格书写。
4. 格式:格式为[标号] <指令条件S> <操作数>[;注释]。
5. 空行和换行:源程序中允许有空行,适当地插入空行可以提高源代码的可读性。
如果单行太长,可以使用字符“”将其分行,“”后不能有任何字符,包括空格和制表符等。
6. 变量和常量:对于变量的设置,常量的定义,其标识符必须在一行的顶格书写。
以上就是ARM汇编的一些规范,供您参考。
如果需要更多信息,建议查阅相关书籍或咨询专业人士。
第3章ARM汇编语言程序设计

2.局部变量定义伪操作LCLA、LCLL和LCLS
(1)语法格式 LCLA、LCLL和LCLS伪指令用于定义一个 ARM程序中的局部变量并将其初始化。 语法格式如下: <lclx> <variable> (2)使用说明 (3)示例
3.变量赋值伪操作SETA、SETL和SETS
(1)语法格式 伪指令SETA、SETL和SETS用于给一个已 经定义的全局变量或局部变量赋值。 语法格式如下: Variable <setx> expr (2)使用说明 (3)示例
(2)用于定义局部变量的LCLA、LCLL和 LCLS。
(3)用于对变量赋值的SETA、SETL和 SETS。
(4)为通用寄存器列表定义名称的RLIST。
1.全局变量定义伪操作GBLA、GBLL和GBLS
(1)语法格式 GBLA、GBLL和GBLS伪操作用于定义一个 ARM程序中的全局变量并将其初始化。 语法格式如下: <gblx> <variable> (2)使用说明 (3)示例
4.通用寄存器列表定义伪操作RLIST
(1)语法格式 RLIST伪操作可用于对一个通用寄存器列 表定义名称,使用该伪操作定义的名称可在 ARM指令LDM/STM中使用。 语法格式如下: Name RLIST {list-of-registers} (2)使用说明 (3)示例
3.2.3 数据定义(Data Definition)伪操作
{label} DCFS{U} fpliteral{,fpliteral}
(2)使用说明 (3)示例
5.DCFD(或DCFDU)
(1)语法格式 DCFD(或DCFDU)伪指令用于为双精度
的浮点数分配一片连续的字存储单元并用伪指 令中指定的表达式初始化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ARM汇编程序设计
宏定义及使用
与C语言中的#define相似,仅在源程序中做字符替换 以MACRO指示符开始,以MEND结束,例:
Macro TestAndBranch $dest, $reg, $cc CMP $reg, #0 B$cc $dest MEND
$label $label
Test … NonZero
ARM汇编程序设计
内置变量1 内置变量
ARM汇编器所定义的内置变量如表4-1所示。值 得注意的是内置变量的设置不能用SETA、SETL 或SETS等指示符来设置,只能用于表达式或条 件语句。例如: IF {ARCHITECTURE} = “4T”
ARM汇编程序设计
表4-1 内置变量
变量 {PC}或. {VAR}或@ {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} 当前指令的地址 存储区位置计数器的当前值 逻辑常量真 逻辑常量假 当前设置列表选项值,OPT用来保存当前列表选项,改变 选项值,恢复它的原始值 如果汇编器汇编ARM代码,则值为32;如果汇编器汇编 Thumb代码,则值为16 如果汇编器在大端模式下,则值为big;如果汇编器在小 端模式下,则值为little 含义
ARM汇编程序设计
AREA Word, CODE, READONLY ; name this block of code num EQU 20 ; Set number of words to be copied ENTRY start LDR r0, =src ; r0 = pointer to source block LDR r1, =dst ; r1 = pointer to destination block MOV r2, #num ; r2 = number of words to copy wordcopy LDR r3, [r0], #4 ; a word from the source STR r3, [r1], #4 ; store a word to the destination SUBS r2, r2, #1 ; decrement the counter BNE wordcopy ; ... copy more stop MOV r0, #0x18 ; angel_SWIreason_ReportException LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit SWI 0x123456 ; ARM semihosting SWI AREA BlockData, DATA, READWRITE src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4 dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 END ; mark the first instruction to call
CMP R0, #0 BNE NonZero
Test TestAndBranch NonZero, R0, NE … NonZero
ARM汇编程序设计
内嵌汇编
在C和C++语言中嵌入汇编语言可以实现一些高级语言中没有的功能。 语法
__asm __ (“instruction ... instruction”); //Linux gcc中支持 __asm{ instruction … instruction };
SUBT
ARM汇编程序设计
[ 或IF 这三个符号连用,进行条件汇编 | 或ELSE 汇编控制指示 符 ] 或ENDIF MACRO MEND MEXIT WHILE WEND 用来在结束前退出宏定义 这二个符号连用,进行重复汇编 这二个符号连用,定义一个宏定义
ARM汇编程序设计
ALIGN AREA CODE16 CODE32 END ENTRY * 或EQU EXPORT或GLOBAL IMPORT或EXTERN GET或INCLUDE INCBIN KEEP NOFP REQUIRE REQUIRE8 PRESERVE8 RN ROUT 从一个字边界开始 指示汇编器汇编一段新的代码或数据部分 指示汇编器将随后的指令作为16位Thumb指令 指示汇编器将随后的指令作为32位ARM指令 表示源程序的结束 指向程序的入口,一个源文件中只能有一个ENTRY 对一个常量赋予一个符号名 说明了由链接器在目标和库文件中使用的符号 提供汇编器在当前汇编中未曾定义的符号名 包含一个文件,在GET处汇编包含的文件 包含一个未被汇编过的文件 指示汇编器保留符号表中的局部符号 在汇编语言程序中禁止浮点指令 指示两段之间的依赖关系 指示当前文件请求堆栈为8字节对准 指示当前文件保持堆栈为8字节对准 给特定的寄存器命名 标记局部标号使用范围的界限
//ADS中支持
asm(“instruction [; instruction]”); //ARM C++中使用
ARM汇编程序设计
C语言中内嵌汇编示例 (ADS可编译通过)
#include <stdio.h> void my_strcpy(char* src, const char* dst){ int ch; __asm{ loop: LDRB ch, [src], #1 STRB ch, [dst], #1 CMP ch, #0 BNE loop }; } int main(void){ const char* a = "Hello World!"; char b[20]; __asm{ MOV R0, a MOV R1, b BL my_strcpy, {R0, R1} }; printf("Original String: %s\n",a); printf(“Copied String: %s\n",b); return 0; }
ARM汇编程序设计
LTORG ^ 或MAP # 或FIELD % 或SPACE = 或DBC & 或DCD 数据定义指示符 DCDU DCDO DCFD DCFDU DCFS DCFSU DCI DCQ DCQU DCW DCWU DATA 指示汇编器汇编当前文字池 置存储映射的起点到一个特定的地址 描述指示符所定义的存储映射中的空间 定义一块值为0的存储器区域 分配一个或多个字节 分配一个或多个字,从4字节边界开始 分配一个或多个字,但不一定从4字节边界开始 分配以字边界开始的存储区域,并指定初始值为到静态基址寄存器 的偏移 分配给双精度浮点数一段以字边界开始的内存区域 分配给双精度浮点数一段以任意边界开始的内存区域 分配给单精度浮点数一段以字边界开始的内存区域 分配给单精度浮点数一段以任意边界开始的内存区域 分配以字边界开始的存储区域,并指定初始值。标记此地址存储的 是代码而不是数据 分配给双精度浮点数一段以4字节边界开始的内存区域 分配给双精度浮点数一段以任意边界开始的内存区域 分配给一个或多个半字以半字边界开始的内存区域 分配给一个或多个半字以任意边界开始的内存区域 标识一个标号是代码段中数据的标号,该符号后是DCB或DCD
ARM汇编程序设计
预定义变量2 预定义变量
·ip和IP(过程调用中间临时寄存器,与r12同义); ·sp和SP(堆栈指针,与r13同义); ·lr和LR(链接寄存器,与r14同义); ·pc和PC(程序计数器,与r15同义); ·cpsr和CPSR(程序状态寄存器); ·spsr和SPSR(程序状态寄存器); ·f0~f7和F0~F7(FPA寄存器); ·s0~s31和S0~S31(VFP单精度寄存器); ·d0~d15和D0~D15(VFP双精度寄存器); ·p0~p15(协处理器0~15); ·c0~c15(协处理器寄存器0~15)。
杂项指示符
ARM汇编程序设计
预定义变量1 预定义变量
ARM汇编器对ARM的寄存器进行了预定义,所 有的寄存器和协处理器名都是大小写敏感的。预 定义的寄存器如下: ·R0~R15和r0~r15; ·a1~a4(参数、结果或临时寄存器,与r0~r3同 义); ·v1~v8(变量寄存器,与r4~r11同义); ·sb和SB(静态基址寄存器,与r9同义); ·sl和SL(堆栈限制寄存器,与r10同义); ·fp和FP(帧指针,与r11同义);
ARM汇编程序设计
ARM汇编程序中每一行的通用格式为: {标号} {指令|指示符|伪指令} {;注解}。 在ARM汇编语言源程序中,除了标号和注释外,指 令、伪指令和指示符都必须有前导空格,而不能顶格 书写。如果每一行的代码太长,可以使用字符“\”将 其分行书写,并允许有空行。指令助记符、指示符和 寄存器名既可以用大写字母,也可以用小写字母,但 不能混用。注释从“;”开始,到该行结束为止。 标号代表一个地址,段内标号的地址值在汇编时确定, 段外标号的地址值在链接时确定。
ARM汇编程序设计[转3.3节]
符号类型 指示符 GBLA GBLL GBLS LCLA 符号定义指示符 LCLL LCLS SETA SETL SETS RLIST CN CP DN SN FN 功能 声明和初始化一个全局算术变量,初始值为0 声明和初始化一个全局逻辑变量,初始值为{FALSE} 声明和初始化一个全局字符串变量,初始值为空 声明和初始化一个局部算术变量,初始值为0。局部算术变量只能 在宏中进行声明。 声明和初始化一个局部逻辑变量,初始值为{FALSE}。局部逻辑变 量只能在宏中进行声明。 声明和初始化一个局部字符串变量,初始值为空。局部字符串变量 只能在宏中进行声明。 给一个局部或全局算术变量置值 给一个局部或全局逻辑变量置值 给一个局部或全局字符串变量置值 给寄存器集命名 给一个协处理器寄存器命名 给一个特定协处理器命名,协处理器号为0~15 给一个双精度VFP寄存器命名 给一个单精度VFP寄存器命名 给一个特定的浮点寄存器命名
ARM汇编程序设计
表4-1 内置变量(续) 内置变量(
{CODESIZE} 如 果 汇 编 器 汇 编 ARM 代 码 , 则 值 为 32 ; 如 果 汇 编 器 汇 编 Thumb代码,则值为16,与{CONFIG}同义 选定的CPU名,缺省时为ARM7TDMI 选定的FPU名,缺省时为SoftVFP 选定的ARM体系结构的值;3,3M,4,4T和4TxM {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET}