【vfp精品源码栏目提醒】:网学会员--在 vfp精品源码编辑为广大网友搜集整理了:微处理器系统结构与嵌入式系统-第九章 - 科学技术绩等信息,祝愿广大网友取得需要的信息,参考学习。
微处理器系统结构与嵌 入式
系统设计 第九章 ARM程序设计9.1 ARM程序开发环境9.2 汇编语言伪指令9.3 ARM汇编语言程序
设计9.4 ARM汇编语言与C/C的混合编程 ARM常用开发环境 主要分为基于Windows平台的和基于Linux平台的两大类 基于Windows平台 – ADS ,目前已经基本被替代 – RealView Developer SuiteRVDS ,目前主流工具 Embedded Workbench for ARMEWARM ,IAR System公司,入门简单,授权费用高 – RealView Microcontroller Development KitMDK ,源自德国Keil公司,多用于低端ARM处理器开发 基于Linux平台 – ARM-Linux-GCC ,GNU开发的编译器集,依赖于不 同的目标机的平台,使用繁琐但不需要授权费用 RVDS开发环境简介 替代ADS的新一代开发环境 集程序的编辑、编译及调试于一体 支持软件仿真和硬件调试 持汇编、C和C等多种
源代码的编译 目前广泛的应用于ARM处理器开发 包括CodeWarrior IDE集成开发环境和 RVDebugger调试器两部分CodeWarrior IDE的主窗口RVD调试器主窗口 汇编语言程序设计特点 汇编语言源程序 汇编(汇编程序) 机器语言程序 高级语言源程序 编译或解释(编译程序) (目标代码)1. 汇编语言依赖于机器硬件,不同CPU提供的汇编指令可能有很 大的不同,因此汇编源程序几乎不具有移植性;但汇编语言程 序速度快、效率高,更能发挥机器硬件的长处;2. 汇编程序需要用户将汇编过程中需要的一些信息明确地写入源程 序,如:内存逻辑段的划分情况、数据在内存中的存放情况, 等等。
这些信息的说明由汇编程序指定相应的伪指令来完成, 并不由CPU定义;3. 伪指令 是在汇编过程中执行的,因而不会在机器语言程序中产生 目标代码;只有CPU定义的(助记符)指令才会生成目标代 码,并在程序运行过程中执行; 7/524. 源程序经汇编得到的目标代码实际上也是不能运行 的,还要经过系统的链接定位后才能生成真正的 可执行文件(.EXE文件)。
即一般用汇编语言开发 应用
软件时应依次 完成以下几个步骤:(1)编辑得到源程序(2)汇编得到目标代码(解决语法错误)(3)链接得到可执行文件(解决定位错误)(4)调试得到功能正确的应用软件(解决逻辑错误) (以上第2~4步任何一步有错都应返回到第1步重来) 8/52 符号定义伪指令 符号类型 指示符 功能 GBLA 声明和初始化一个全局算术变量,初始值为0 GBLL 声明和初始化一个全局逻辑变量,初始值为FALSE GBLS 声明和初始化一个全局字符串变量,初始值为空 声明和初始化一个 局部 算术变量,初始值为0。
局部算术变量只 LCLA 能在宏中进行声明。
LCLL 声明和初始化一个局部逻辑变量,初始值为FALSE。
局部逻辑变 量只能在宏中进行声明。
符号定义 LCLS 声明和初始化一个局部字符串变量,初始值为空。
局部字符串变量 只能在宏中进行声明。
伪指令 SETA 给一个局部或全局算术变量置值 SETL 给一个局部或全局逻辑变量置值 SETS 给一个局部或全局字符串变量置值 RLIST 给寄存器集命名 CN 给一个协处理器寄存器命名 CP 给一个特定协处理器命名,协处理器号为015 DN 给一个双精度
VFP寄存器命名 SN 给一个单精度
VFP寄存器命名 FN 给一个特定的浮点寄存器命名2012-12-13 9/52GBLA Test1 声明全局数字变量Test1,赋值为0xaa Test1 SETA 0xaaGBLL Test2 声明全局逻辑变量Test2,赋值为“真” Test2 SETL TRUEGBLS Test3 声明全局字符串变量为Test3,赋值为Testing“ Test3 SETS Testing“LCLA Test4 声明局部数字变量Test4,赋值为0xaa Test3 SETA 0xaaLCLL Test5 声明局部逻辑变量Test5 ,赋值为“真” Test4 SETL TRUELCLS Test6 声明局部字符串变量Test6 ,赋值为Testing“ Test6 SETS Testing“RegList RLIST R0-R5 R8 R10 声明寄存器列表RegList,LDM/STM指令可通过该名称访问寄存器
列表2012-12-13 10/52 数据定义伪指令 LTORG 指定一个文字池用以保存数据 或MAP 指定一个内存表的首址 或FIELD 指定内存表中的各数据域的长度(一般在MAP之后) 或SPACE 指定一块存储器的长度并将其中单元初始化为0 或DCB 分配一片连续的字节单元并初始化 或DCD 分配一片连续的字单元并初始化(字边界对齐) DCDU 分配一片连续的字单元并初始化(任意边界) 数据定义 DCDO 分配一片连续的字单元,并初始化为到静态基址寄存器R9的偏移量 (字边界对齐) 伪指 DCFD 分配一片连续的字单元给双精度浮点数并初始化(字边界对 齐) DCFDU 分配一片连续的字单元给双精度浮点数并初始化(任意边 界) DCFS 分配一片连续的字单元给单精度浮点数并初始化(字边界对 齐) DCFSU 分配一片连续的字单元给单精度浮点数并初始化(任意边 界) DCI 分配一片连续的字节单元并用于存放代码 DCQ 分 配 一 片 连 续 的8字节单元并初始化(字边界对 DCQU 齐) 分配一片连续的8字节单元并初始化(任意边界) DCW 分配一片连续的半字单元并初始化(半字边界对 DCWU 齐) 分配一片连续的半字单元并初始化(任意边界)2012-12-13 DATA 标识代码段中的数据标号,该符号后是DCB等Str DCB “This is a test” 分配一片连续的字节存储单元并初始化Test2Data DCW 1 2 3 分配一片连续的半字存储单元并初始化DataTest DCD 4 5 6 分配一片连续的字存储单元并初始化FdataTest DCFD 2E115 -5E7双精度 分配一片连续的字存储单元并初始化FdataTest DCFS 2E5 -5E-7 单精度 分配一片连续的字存储单元并初始化DataTest DCQ 100 分配一片连续的8字节存储单元并初始化DataSpace SPACE 100 分配连续100个字节存储单元并初始化为0 定义一个首址为40960x1000的内存表,该表中包含5个字段:A4Bytes、B4Bytes、X8Bytes、Y8Bytes、String256Bytes。
MAP 0x1000 基于绝对地 内存表首地址的值为0x1000A FIELD 4 址的内存表 定义A的长度为4字节,位置为0x1000B FIELD 4 定义B的长度为4字节,位置为0x1004X FIELD 8 定义X的长度为8字节,位置为0x1008Y FIELD 8 定义Y的长度为8字节,位置为0x1010String FIELD 256 仅可访问指令前/后4KB地址范围的数据字段 定义String为256字节,位置为0x1018定义一个内存表,其首址为固定地址与R9和,表中包含同样字段。
MAP 0 R9 内存表首地址为0与R9寄存器内容的和A FIELD 4 基于相对地 定义A的长度为4字节,相对位置为0B FIELD 4 址的内存表 定义B的长度为4字节,相对位置为4X FIELD 8 定义X的长度为8字节,相对位置为8Y FIELD 8 定义Y的长度为8字节,相对位置为16String FIELD 256 定义String为256字节,相对位置为24 ADR R9 DATASTART;伪指令ADR 初始化R9 可访问地址范围 LDR R5 B 相当于LDR R5 R9 4 超过4 KB的数据定义一个内存表,其首址为PC的值,表中包含同样字段。
Dstruc SPACE 280 分配280个字节单元 MAP Dstruc 内存表首地址为DstrucA FIELD 4 基于PC的 定义A的长度为4字节,相对位置为0B FIELD 4 内存表 定义B的长度为4字节,相对位置为4X FIELD 8 定义X的长度为8字节,相对位置为8Y FIELD 8 定义Y的长度为8字节,相对位置为16String FIELD 256 定义String为256字节,相对位置为24 可访问地址范围不 LDR R5 B 相当于LDR R5 PC 4 超过4 KB的数据 汇编控制伪指令 助 记 符 指令功能描述IF、ELSE和ENDIF 根据条件成立与否决定是否编译某个指令序列 WHILE和WEND 根据条件成立与否决定是否循环编译某个指令序列 将一段代码用一个标号替代,可在程序中多次调用该段 MACRO和MEND 代码 MEXIT 从宏定义中跳转出去 GBLA Counter 声明全局的数字变量Counter Counter SETA 3 由变量Counter控制循环次数 …… WHILE Counter 10 指令序列 修改Counter的值 WEND2012-12-13 14/52 宏和宏定义指令MACRO 标号 宏名 参数1,参数2,…… 宏体MEND MACRO和MEND伪指令可以嵌套使用。
宏的使用方式和功能与子程序有些相似。
子
程序可以提供模块化的程序设计、节省存储空间并提高运行速度,但在使用子程序结构时需要保护现场,从而增加了系统的开销。
因此,在代码较短且需要传递的参数较多时,可以使用宏指令代替子程序。
2012-12-13 15/52定义一条宏指令,使其可以完成测试-跳转操作。
MACRO 宏名 宏定义开始 宏参 lable TestAndBranch dest reg cc 用于构造宏义 体内的标号 lable CMP reg 0 测试寄存器 Bcc dest 目标地址 MEND 条件 宏定义结束 …… test TestAndBranch NonZero R0 NE 程序中的宏调用 …… NonZero …… test CMP R0 0 ;程序汇编时宏展开 BNE NonZero …… ;其它指令序列 NonZero2012-12-13 …… ;其它指令序列 16/52MACRO 宏定义开始lable xmac p1 p2 宏的名称为xmac,有两个参数p1和p2lable.loop1 lable.loop1为宏定义体的内部标号 …… BGE lable.loop1lable.loop2 指令 lable.loop2为宏定义体的内部标号 BL p1 参数p1为一个子程序的名称 BGT lable.loop2 …… ADR p2MEND 宏定义结束 abc xmac subr1 de 宏调用,其中宏标号为abc参数为subr1,de …… 宏展开 abc.loop1 …… BGE abc.loop1 abc.loop2 BL subr1 BGT abc.loop2 …… ADR de 17/52 其它
常用伪指令 AREA 指示汇编器汇编一段新的代码或数据部分 ENTRY 指向程序的入口,一个源文件中只能有一个ENTRY END 表示源程序的结束 CODE16 指示汇编器将随后的指令作为16位Thumb指令 CODE32 指示汇编器将随后的指令作为32位ARM指令 或EQU 对一个常量赋予一个符号名 EXPORT或GLOBAL 说明了由链接器在目标和库文件中使用的符号 其他常用 IMPORT或EXTERN 提供汇编器在当前汇编中未曾定义的符号名 的伪指令 GET或INCLUDE 包含一个文件,在GET处汇编包含的文件 ALIGN 从一个字边界开始 INCBIN 包含一个未被汇编过的文件 KEEP 指示汇编器保留符号表中的局部符号 NOFP 在汇编语言程序中禁止浮点指令 REQUIRE 指示两段之间的依赖关系 REQUIRE8 指示当前文件请求堆栈为8字节对准 PRESERVE8 指示当前文件保持堆栈为8字节对准 RN 给特定的寄存器命名 ROUT 标记局部标号使用范围的界面2012-12-13 18/52 AREA、ENTRY、END伪指令 一个汇编源程序至少包含一个段,程序太长时可分为多个段并用AREA标示;一个汇编源程序最多只能有一个 可以没有ENTRY标示程序入口;一个完整的汇编源程序中至少应有一个用ENTRY标示的入口,如有多个则程序的 真正入口点由连接器指定;一个汇编源程序用END标示源文件结束;AREA 段名 属性1,属性2,…… 定义代码段或数据段 1.段名若以数字开头,则该段名需用“”括起来,如1_test。
2.属性字段表示该代码或数据的相关属性,多个属性关键字以逗号分隔:CODE:用于定义代码段。
DATA:用于定义数据段。
READONLY:指定本段为只读属性,代码段默认为READONLY。
READWRITE:指定本段为可读写属性,数据段默认为READWRITE。
ALIGN 表达式:表达式取值为031。
ELF可执行连接文件的段默认按字对齐。
COMMON:定义一个通用段,各源文件中同名的COMMON段共享同一段存储单元。
AREA Init CODE READONLY 代码段Init属性为只读 ENTRY 指定应用程序的入口点 指令序列 END 通知编译器源程序结束 19/52 ALIGN伪指令 ALIGN 表达式,偏移量 ALIGN伪指令可通过添加填充字节的方式,使当前位置满 足一定的对其方式。
其中: 表达式可能的取值为2的幂(如1,2,4,8和16等)。
若未 指定表达式则将当前位置对齐到下一个字的位置。
若使用偏移量字段,则当前位置的对齐方式为:表达式偏移 量。
AREA Init CODE READONLY ALIEN 3 指定后面的指令 为8字节对齐 指令序列 END2012-12-13 20/52