第5-2章 ARM汇编程序设计
- 格式:pdf
- 大小:359.43 KB
- 文档页数:84
ARM汇编语言程序设计1.ARM汇编语言概述2.ARM寄存器3.ARM指令ARM指令包括数据处理指令、传输指令、分支指令和其他特殊指令。
(1)数据处理指令:包括算术运算、逻辑运算、移位和旋转、比较和测试等。
(2)传输指令:用于数据的加载和存储,包括复制、分配和堆栈操作等。
(3)分支指令:用于控制程序流,包括无条件跳转、条件跳转和中断处理等。
4.ARM程序设计(1)初始化:程序开始时需要进行系统和寄存器的初始化。
可以将堆栈指针初始化,设置另外的寄存器和内存变量等。
(2)输入输出:程序可能需要从外部设备读取数据或向外部设备写入数据。
可以使用传输指令实现数据的输入和输出。
(3)运算处理:根据程序的需求,进行各种运算处理。
可以使用数据处理指令实现数据的加减乘除、逻辑运算等。
(4)循环和条件控制:根据需要,使用分支指令控制程序的流程。
可以使用无条件跳转、条件跳转和循环指令实现程序的循环和条件控制。
(5)结束:在程序执行完毕后,可以进行清理工作,例如释放内存、关闭设备等。
5.ARM程序设计实例下面是一个简单的ARM汇编程序示例,实现从数组中找到最大值并输出:.global _start.section .dataarray: .word 1, 3, 5, 2, 4max: .word 0.section .text_start:loop:next:在上述示例中,程序首先将数组的地址和最大值的地址加载到寄存器中。
然后使用循环和条件控制指令依次比较数组元素,找到最大值并将其存储在max变量中。
最后将最大值输出,并结束程序。
ARM汇编语言编程详解作者:机器人小助手摘要:本文旨在为读者提供一份详细的ARM汇编语言编程指南。
在介绍ARM汇编语言的基础知识后,我们将深入讨论ARM指令集的不同类型、寻址方式、寄存器的使用以及常见的编程技巧。
通过本文的学习,读者将能够深入了解ARM汇编语言的编程思想,并能够编写高效的ARM汇编语言程序。
一、ARM汇编语言简介ARM汇编语言是一种低级的程序设计语言,用于编写针对ARM架构的机器码指令。
它是一种类似于其他汇编语言的文本格式,用于表达机器指令和操作数。
通过编写ARM汇编语言程序,我们可以直接控制计算机的硬件资源,实现高效的程序执行。
二、ARM指令集概述ARM指令集是一套针对ARM架构的机器指令集合,包含多条不同功能的指令。
根据指令的功能和操作对象的不同,ARM指令可以分为数据处理指令、分支跳转指令、访存指令以及其他特殊指令。
1. 数据处理指令数据处理指令用于对操作数进行算术运算、逻辑运算、移位操作等。
这些指令可以对寄存器中的数据进行操作,并将结果存储回寄存器。
常见的数据处理指令有加法、减法、乘法、比较以及逻辑运算等。
2. 分支跳转指令分支跳转指令用于控制程序的流程,可以根据条件进行无条件跳转或有条件跳转。
通过分支跳转指令,我们可以实现程序的循环、条件分支等逻辑。
3. 访存指令访存指令用于读取或写入内存中的数据。
ARM汇编语言提供了多种不同的寻址方式,可以根据操作对象的不同进行选择。
使用访存指令,我们可以实现数据的存储和加载操作。
三、ARM汇编语言编程基础在进行ARM汇编语言编程时,我们需要了解一些基本的编程知识和技巧。
1. 寄存器的使用ARM架构提供了多个通用寄存器,用于存储临时数据。
在编写ARM汇编语言程序时,我们需要灵活使用寄存器,将数据加载到寄存器中进行计算,然后将结果保存回寄存器或内存。
2. 标志位的使用ARM架构提供了一组标志位,用于记录程序执行的状态和结果。
通过检查标志位的值,我们可以进行条件分支和判断,实现程序的流程控制。
第5章ARM汇编程序设计ARM编译器,如ADS集成开发环境,一般都支持汇编语言的程序设计。
本章介绍ARM 程序设计的一些基本概念,如ARM汇编语言的伪指令、汇编语言的语句格式和汇编语言的程序结构等到,并在些基础上介绍一些常用的ARM汇编子程序的设计。
4.1 ARM伪指令ARM汇编程序由汇编指令、伪指令和宏指令组成,伪指令不介汇编指令那样在处理器的运行期间执行,而是在汇编器对汇编程序进行汇编时处理。
宏是一段独立的汇编程序代码,它是通过伪指令定义的,在程序中宏指令即调用宏指令。
当程序被汇编时,汇编程序对每个宏调用进行展开,用宏定义代汇编程序中的宏指令。
由于指令也发球汇编伪指令的一部分,因此本书将宏指令放在汇编伪一起介绍。
与单片机汇编程序设计一样,在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,它们没有相对应的操作友码,通常称这些特殊指令助记符为伪指令,它们所完成的操作称为伪操作。
伪指令在源程序中的作用是为完成汇编程序做各种准备工作,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成了。
在ARM的光荣称号程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令以及其他伪指令。
4.1.1 符号定义(Symbol Definition)伪指令符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等。
常见的符号定义伪指令有以下几种:●用于宝玉局变量的GBLA、GBLL和GBLS;●用于定义局部变量的LCLA、SETL、LCLS;●用于对变量赋值的SETA、SETL、SETS;●为通用寄存器列表定义名称的RLIST;●为一个协处理器的寄存器定义名称的伪指令CN;●为一个协处理器定义名称的伪指令CP;●为一个CFP寄存器定义名称的伪指令DN和SN;●为一个FPA浮点寄存器定义名称的伪指令FN。
1.GBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS) 全局变量名GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并半其初始化。
5.2ARM汇编程序设计ARM程序设计基础◆伪操作(derective)◆伪指令(Pseudo-instruction)◆ARM汇编语言语句格式◆ARM汇编语言的程序格式◆相关的程序示例伪操作◆符号定义伪操作◆数据定义伪操作◆汇编控制伪操作◆其他伪操作符号定义伪操作◆定义全局变量:GBLA、GBLL和GBLS ◆定义局部变量:LCLA、LCLL和LCLS ◆变量赋值:SETA、SETL、SETS ◆通用寄存器列表定义名称:RLISTGBLA、GBLL和GBLSGBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS)全局变量名GBLA objectsize ;全局的数字变量objectsize ,为0 Objectsize SETA 0xff;将该变量赋值为0xffSPACE objectsize ;引用该变量GBLL statusB;全局的逻辑变量statusB ,为{False} statusB SETL {TRUE};将该变量赋值为真全局:作用范围为包含该变量的源程序LCLA、LCLL和LCLSLCLA、LCLL和LCLS语法格式:LCLA(LCLL或LCLS)局部变量名MACRO;声明一个宏$label message $a ;宏的原型LCLS err ;声明一个局部变量err,为空串err SETS “error no: ” ;向该变量赋值$label;代码INFO 0,err:CC::STR:$a ;使用该串变量MEND;宏定义结束局部:作用范围为包含该局部变量的宏代码的一个实例SETA、SETL、SETSSETA、SETL和SETS语法格式:变量名SETA(SETL或SETS)表达式在向变量赋值前,必须先声明该变量RLISTRLIST语法格式:名称RLIST{寄存器列表}Context RLIST {r0-r6,r8,r10-r12,r15};将寄存器列表名称定义为Context ,可在ARM指令LDM/STM中通过该名称访问寄存器列表。
排列顺序无关数据定义伪操作◆DCB◆DCW(DCWU)◆DCD(DCDU)◆DCFD(DCFDU)◆DCFS(DCFSU)◆SPACE◆MAP◆FIELDDCB语法格式:{标号}DCB表达式表达式取值范围:-128~255的数字或字符串。
DCB:“=”Nullstring DCB“Null string”,0;构造一个以0结尾的字符串DCW(或DCWU)语法格式:{标号}DCW(或DCWU)表达式DCW:半字对齐DCWU:不严格半字对齐。
表达式取值范围:-32768~65535data1DCW-128,num1+8;num1必须是已经定义过的DCD(或DCDU)语法格式:{标号}DCD(或DCDU)表达式DCD:“& ”DCD:字对齐DCDU:不严格字对齐。
data1DCD1,5,20;其值为1,5,20data2DCD memaddr+4;分配一个字单元,其值为程序中标号memaddr加4个字节语法格式:{标号}DCFD(或DCFDU)表达式每个双精度的浮点数占据两个字单元。
DCFD:字对齐DCFDU:不严格字对齐DCFD1E308,-4E-100 DCFDU100000,-.1,3.1E26语法格式:{标号} DCFS(或DCFSU)表达式每个单精度的浮点数占据一个字单元。
DCFS:字对齐DCFSU:不严格字对齐DCFS1E3,-4E-9DCFSU 1.0,-.1,3.1E6SPACE语法格式:{标号}SPACE表达式分配一片连续的存储区域并初始化为0。
其中,表达式为要分配的字节数。
SPACE:“%”Datastruc SPACE 280;分配连续280字节的存储单元并初始化为0MAP语法格式:MAP 表达式{,基址寄存器}用于定义一个结构化的内存表的首地址。
MAP:“^”通常与FIELD伪指令配合使用来定义结构化的内存表。
MAP0x80,R9;定义结构化内存表首地址的值为0x80+R9FILED语法格式:{标号} FIELD 表达式定义一个结构化内存表中的数据域。
FILED也可用“#”代替。
MAP0;定义结构化内存表首地址为0consta FIELD4;consta的长度为4字节,相对位置为0 constb FIELD4;constb的长度为4字节,相对位置为4 x FIELD8;x的长度为8字节,相对位置为0x8y FIELD8;y的长度为8字节,相对位置为0x10 string FIELD256;y的长度为256字节,相对位置为0x18MOV R9,#4096LDR R5,[R9,constb];将内存表中数据域constb读取到R5中汇编控制伪操作汇编控制(Assembly Control)伪操作用于控制汇编程序的执行流程,常用的汇编控制伪操作包括以下几条:◆IF、ELSE、ENDIF◆WHILE、WEND◆MACRO、MEND◆MEXITIF、ELSE、ENDIF语法格式:IF逻辑表达式指令序列1ELSE指令序列2ENDIF示例:IF Version=“1.0”;指令;伪指令ELSE;指令;伪指令ENDIFWHILE、WEND语法格式:WHILE逻辑表达式指令序列WEND示例:count SETA1WHILE count<=4 count SETA count+1;codeWEND语法格式:MACRO$标号宏名$参数1,$参数2,……指令序列MEND示例:在ARM中完成测试-跳转操作需要两条指令,定义一条宏指令完成测试-跳转操作MACRO$label TestAndBranch$dest, $reg, $cc$label CMP$reg,#0B$cc$destMEND;在程序中调用该宏test TestAndBranch NonZero, r0, NE ……NonZero;程序被汇编后,宏展开的结果test CMP r0, #0BNE NonZero……NonZeroMEXIT语法格式:MEXITMEXIT用于从宏定义中跳转出去。
其他常用的伪操作◆AREA◆CODE16、CODE32◆ENTRY◆END◆EQU◆IMPORT◆GET(或INCLUDE)AREA语法格式:AREA段名属性1,属性2,……定义一个代码段或数据段。
常用的属性如下:CODE:用于定义代码段,默认为READONLY。
DATA:用于定义数据段,默认为READWRITE。
READONLY:指定本段为只读,代码段默认为READONLY。
READWRITE:指定本段为可读可写,数据段的默认属性为READWRITE。
示例:AREA Example,CODE,READONLY;codeCODE16、CODE32语法格式:CODE16(或CODE32)CODE16:其后的指令序列为16位的Thumb指令。
CODE32:其后的指令序列为32位的ARM指令。
示例:AREA ChangeState,CODE,READONLYCODE32;指示下面的指令为ARM指令LDR r0,=start+1BX r0;切换到Thumb状态,并跳转到start处执行CODE16;指示下面的指令为Thumb指令start MOV r1,#10ENTRY语法格式:ENTRYENTRY伪操作用于指定汇编程序的入口点。
在一个源文件里最多只能有一个ENTRY(可以没有)。
在一个完整的汇编程序中至少要有一个ENTRY(当有多个ENTRY时,程序的真正入口点由链接器指定)。
示例:AREA example,CODE,READONLYENTRY;应用程序的入口点END语法格式:ENDEND伪指令用于通知编译器已经到了源程序的结尾。
示例:AREA example,CODE,READONLY……ENDEQU语法格式:名称EQU表达式{,类型} EQU:“* ”示例:abcd EQU 2 ;定义abcd符号的值为2abcd EQU label1+16 ;定义abcd符号的值(label1+16)IMPORT语法格式:IMPORT标号{[WEAK]}用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用。
示例:AREA Init,CODE,READONLYIMPORT Main;通知编译器当前文件要引用标号Main,但Main在其他源文件中定义……ENDGET(或INCLUDE)语法格式:GET文件名用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。
可以使用INCLUDE代替GET。
使用方法与C语言中的“include”相似。
示例:AREA example,CODE,READONLYGET file1.s;包含源文件file1.s GET C:\project\file2.s ;包含源文件file2.s GET C:\Program files\file3.s ;包含源文件file3.s伪指令◆ADR◆ADRL◆LDR◆NOPADR-小范围的地址读取伪指令◆语法格式ADR{cond} register, exprcond:可选的指令执行条件register:目标寄存器expr:基于PC或寄存器的地址表达式,取值范围:●地址非字对齐,-255~255●地址字对齐,-1020~1020将基于PC或寄存器的地址值读取到寄存器中。
ADR伪指令被替换成一条合适的指令(ADD指令或SUB指令)。
如果不能用一条来实现ADR伪指令的功能,编译器将报告错误。
ADR-小范围的地址读取伪指令示例:start MOV r0,#10 ;PC值为当前指令地址值加8字节ADR r4,start;本ADR伪指令将被编译器替换成; SUB r4,pc,#0xcADRL-中等范围的地址读取伪指令◆语法格式ADRL{cond} register, exprcond:可选的指令执行条件register:目标寄存器expr:基于PC或寄存器的地址表达式,取值范围:●地址非字对齐,-64KB~64KB●地址字对齐,-256KB~256KB将基于PC或寄存器的地址值读取到寄存器中。
ADRL伪指令被替换成两条合适的指令。
如果不能用两条来实现ADRL伪指令的功能,编译器将报告错误。
ADRL-中等范围的地址读取伪指令示例:start MOV r0,#10 ;PC值为当前指令地址值加8字节ADR r4,start+60000;本ADRL伪指令将被编译器替换成下面两条指令;ADD r4,pc,#0xe800;ADD r4,r4,#0x254;60000=0xEA60LDR-大范围的地址读取伪指令◆语法格式LDR{cond} register, =[expr|label-expr]cond:可选的指令执行条件register:目标寄存器expr:32位常数●当expr没有超过MOV或MVN指令中的地址取值范围时,编译器用合适的MOV或MVN指令代替该LDR伪指令●反之,编译器将该常数放在数据缓冲池中,同时用一条基于PC的LDR指令读取该常数。