第9章 ARM汇编语言程序设计基础.

Slides:



Advertisements
Similar presentations
2017年3月5日 单片机原理与应用 背景知识调查.
Advertisements

Tool Command Language --11级ACM班 金天行.
第三章 数据类型和数据操作 对海量数据进行有效的处理、存储和管理 3.1 数据类型 数据源 数据量 数据结构
第六章 ADS集成开发环境的使用.
Oracle数据库 Oracle 子程序.
在PHP和MYSQL中实现完美的中文显示
Hadoop I/O By ShiChaojie.
嵌入式系统课程简介 宋健建 南京大学软件学院 2004/02/10.
第二讲 搭建Java Web开发环境 主讲人:孙娜
第八章 菜单设计 §8.1 Visual FoxPro 系统菜单 §8.2 为自己的程序添加菜单 §8.3 创建快捷菜单.
SVN服务器的搭建(Windows) 柳峰
第4章 汇编语言程序设计 汇编语言源程序格式 汇编语言上机过程 汇编语言与C语言混合编程技术.
走进编程 程序的顺序结构(二).
第六章 基于ARM的嵌入式程序设计.
DM81X 视频采集处理 ——简单采集显示例程讲解 广州创龙电子科技有限公司
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第十章 IDL访问数据库 10.1 数据库与数据库访问 1、数据库 数据库中数据的组织由低到高分为四级:字段、记录、表、数据库四种。
College of Computer Science & Technology
第二章 Java语言基础.
逆向工程-汇编语言
CPU结构和功能.
第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
(第2版).
Gzip编译及调试 曹益华
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
三:基于Eclipse的集成开发环境搭建与使用
第7章 在C/C++中使用汇编 罗文坚 中国科大 计算机学院
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言程序设计 主讲教师:陆幼利.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
学习目标 1、什么是字符集 2、字符集四个级别 3、如何选择字符集.
微机系统的组成.
ARM Developer Suite 介 绍.
第1章 c++概述 1.1 C++语言的简史及特点 1.2 简单的C++程序 1.3 C++语言的基本组成
Platform Builder使用介绍 WINCE系统应用开发流程说明 ACTION RDC 杨 涛 2005.Dec.3th
VB与Access数据库的连接.
姚金宇 MIT SCHEME 使用说明 姚金宇
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月13日.
实验七 安全FTP服务器实验 2019/4/28.
工业机器人知识要点解析 (ABB机器人) 主讲人:王老师
<编程达人入门课程> 本节内容 内存的使用 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群: ,
项目二:HTML语言基础.
本节内容 Win32 API中的宽字符 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第4章 Excel电子表格制作软件 4.4 函数(一).
JSP实用教程 清华大学出版社 第2章 JSP运行环境和开发环境 教学目标 教学重点 教学过程 2019年5月7日.
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
数据报分片.
LOGIX500软件入门 西安华光信息技术有限公司 2008年7月11日.
College of Computer Science & Technology
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
魏新宇 MATLAB/Simulink 与控制系统仿真 魏新宇
第二章ADS1.2开发环境创建与简介.
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Python 环境搭建 基于Anaconda和VSCode.
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第四章 UNIX文件系统.
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
<编程达人入门课程> 本节内容 有符号数与无符号数 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
学习目标 1、什么是列类型 2、列类型之数值类型.
Presentation transcript:

第9章 ARM汇编语言程序设计基础

ADS IDE(集成开发环境) ARM应用软件的开发工具根据功能的不同,可以分为编辑软件、编译软件、汇编软件、链接软件、调试软件、嵌入式实时操作系统、函数库、评估板,JTAG仿真器以及在线仿真器等。目前有多家公司可以提供以上不同类型的开发工具,用户采用ARM处理器进行嵌入式系统开发时,选择合适的开发工具可以加快开发进度,节省开发成本。

ADS工具包的组成 ADS是ARM公司推出的集成开发工具包,是专门用于ARM相关应用开发和调试的综合性软件。目前常用的版本是1.2,在功能和易用性上比早期的SDT都有提高,是一款功能强大又易于使用的开发工具。ARM ADS包含有编译器、链接器、CodeWarrior IDE、调试器、指令集模拟器、ARM开发包和应用库等部分,可以用ADS来开发、编译、调试采用包括C、C++和ARM汇编语言编写的程序。

ADS工具包的组成 1. 编译器 ADS提供多种编译器,以支持ARM和Thumb指令的编译。 2. 链接器 Armlink(ARM链接器)可以将编译得到的一个或多个目标文件和相关的一个或多个库文件进行链接,生成一个可执行文件,也可以将多个目标文件部分链接成一个目标文件,以供进一步的链接。

ADS工具包的组成 3. CodeWarrior IDE CodeWarrior IDE(集成开发环境)包括工程管理器、代码生成接口、语法敏感编辑器、源文件和类浏览器、源代码版本控制系统接口以及文本搜索引擎等。ADS仅在其PC机版本中集成了该IDE。 CodeWarrior IDE为管理和开发项目提供了简单多样化的图形用户界面,用户可以使用ADS的CodeWarrior IDE为ARM和Thumb处理器开发用C、C++或者ARM汇编语言编写的程序代码。

ADS工具包的组成 (1)调试器类型 ADS中包含有3个调试器,分别是ARM扩展调试器AXD(ARM eXtended Debugger. (2)调试方式 在ARM体系中,可以选择Multi-ICE(Multi-processor in-circuit emulator)ARMulator或Angel多种调试方式。

ADS工具包的组成 5. ARM开发包和函数库 ARM开发包由一些底层的例程和库组成,可以帮助用户快速开发基于ARM的应用程序和操作系统。 ADS的ARM应用库完善并增强了SDT中的函数库,同时还包括一些非常有用的源码例程。

ADS开发工具集 1.命令行开发工具 (1)armcc armcc是 ARM C 编译器。在命令控制台环境下,输入命令:C:> armcc –help可以查看 armcc 的语法格式以及最常用的一些操作选项。 (2)armcpp armcpp 是 ARM C++ 编译器。它将 ISO C++ 或 EC++ 编译成 32 位 ARM 指令代码。 (3) tcc tcc 是 Thumb C 编译器。该编译器通过了 Plum Hall C Validation Suite 为 ANSI 一致性的测试。tcc 将 ANSI C 源代码编译成 16 位的 Thumb 指令代码。

ADS开发工具集 (4) tcpp tcpp 是 Thumb C++ 编译器。 它将 ISO C++ 和 EC++ 源码编译成 16 位 Thumb 指令代码。 (5) armsm armsm 是 ARM 和 Thumb 的汇编器 . 它对用 ARM 汇编语言和 Thumb 汇编语言写的源代码进行汇编。 (6) armlink armlink是 ARM 连接器。 (7) armsd armsd是 ARM 和 Thumb 的符号调试器。

ADS开发工具集 2.GUI 开发环境 ADS GUI开发环境主要包含Code Warrior 和 AXD,其中Code Warrior是用于编译和链接的集成开发工具,而AXD则是支持单步执行、断点设置等功能的集成调试工具。 (1)Code Warrior Code Warrior for ARM是一套完整的集成开发工具,充分发挥了 ARM RISC指令系统的优势, 使产品开发人员能够很好的应用尖端的片上系统技术 . 该工具是专为基于 ARM RISC 的处理器而设计的 。

ADS开发工具集 (2)AXD AXD调试器本身是一个软件,用户通过这个软件可以对包含有调试信息的、正在运行的可执行代码进行变量的查看、断点的设置、单步执行等调试操作。在ARM体系中,它有Multi-ICE、ARMulator和Angel等几种方式。AXD可以在Windows和UNIX下进行程序的调试,它为用C、C++和汇编语言的源代码提供了一个全面的Windows和UNIX环境。

ADS开发工具集 3、 实用程序 ADS 提供以下的实用工具来配合前面介绍的命令行开发工具的使用。 fromELF是 ARM 映像文件转换工具。 armar是ARM库函数生成器。 Flash downloader用于把二进制映像文件下载到ARM嵌入式设备上的 Flash 存储器中。

ARM汇编伪指令 在 ARM 汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,也就是不会生成机器码,仅仅是在编译器软件中起着格式化的作用,通常称这些特殊指令助记符为伪指令。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。          在 ARM 的汇编程序中,有如下几种伪指令:数据常量定义伪指令、数据变量定义伪指令、内存分配伪指令及其他伪指令。

1 数据常量定义伪指令 数据常量定义伪指令EQU用于为程序中的常量、标号等定义一个等效的字符名称,类似于 C 语言中的#define 。    EQU语法格式 :  名称 EQU 表达式 { ,类型 } ;其中 EQU 可用 “ * ” 代替。          名称为 EQU 伪指令定义的字符名称,当表达式为 32 位的常量时,可以指定表达式的数据类型,可以有以下三种类型: CODE16 、 CODE32 和 DATA 。            

2 数据变量定义伪指令(Cont.) 数据变量定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的数据变量定义伪指令有如下几种:    (1)GBLA、GBLL 和GBLS     语法格式:GBLA ( GBLL 或 GBLS ) 全局变量名         GBLA 、 GBLL 和 GBLS 伪指令用于定义全局变量,并将其初始化。其中:     ① GBLA用于定义一个全局的数字变量,并初始化为 0 ; ② GBLL用于定义一个全局的逻辑变量,并初始化F(假); ③ GBLS用于定义一个全局的字符串变量,并初始化为空;

2 数据变量定义伪指令(Cont.) (2)LCLA、LCLL 和LCLS         语法格式: LCLA ( LCLL 或 LCLS ) 局部变量名         LCLA 、 LCLL 和 LCLS 伪指令用于定义一个 ARM 程序中的局部变量,并将其初始化。其中:   ① LCLA伪指令用于定义一个局部的数字变量,并初始化为 0 ;   ② LCLL伪指令用于定义一个局部的逻辑变量,并初始化为 F(假);   ③ LCLS 伪指令用于定义一个局部的字符串变量,并初始化为空;

2 数据变量定义伪指令(Cont.) (3)SETA、SETL 和SETS      语法格式:变量名 SETA ( SETL 或 SETS ) 表达式      伪指令 SETA 、 SETL 、 SETS 用于给一个已经定义的全局变量或局部变量赋值。    ① SETA 伪指令用于给一个数学变量赋值;    ② SETL 伪指令用于给一个逻辑变量赋值;    ③ SETS 伪指令用于给一个字符串变量赋值;

2 数据变量定义伪指令(Cont.) (4)RLIST         语法格式:名称 RLIST { 寄存器列表 }      RLIST 伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在 ARM 指令 LDM/STM 中使用。在 LDM/STM 指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。    

3 内存分配伪指令 内存分配伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪指令有如下几种: 3 内存分配伪指令 内存分配伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪指令有如下几种:  (1)DCB        语法格式:  标号 DCB 表达式     (2) DCW(或DCWU)         语法格式:  标号 DCW (或 DCWU ) 表达式   

3 内存分配伪指令(Cont.) (3)DCD(或DCDU) 语法格式: 标号 DCD (或 DCDU ) 表达式 (4)DCFD(或DCFDU)         语法格式: 标号 DCFD (或 DCFDU ) 表达式     (5)DCFS(或DCFSU)         语法格式:  标号 DCFS (或 DCFSU ) 表达式

3 内存分配伪指令(Cont.) (6)DCQ(或DCQU) 语法格式: 标号 DCQ (或 DCQU ) 表达式 (7) SPACE         语法格式:    标号 SPACE 表达式  (8)MAP         语法格式:    MAP 表达式 { ,基址寄存器 }  (9)FILED      语法格式:标号 FIELD 表达式

4 汇编控制伪指令 汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条:    (1) IF、ELSE、ENDIF      语法格式:    IF 逻辑表达式       指令序列 1  ELSE         指令序列 2         ENDIF           

4 汇编控制伪指令(Cont.) (2) WHILE、WEND 语法格式: WHILE 逻辑表达式 指令序列 WEND   (3) MEXIT      语法格式: MEXIT         MEXIT 用于从宏定义中跳转出去。

4 汇编控制伪指令(Cont.) (4) MACRO、MEND      语法格式:     MACRO $ 标号 宏名 $ 参数 1 , $ 参数 2 ,……     指令序列         MEND         MACRO、MEND伪指令可以将一段代码定义为一个整体,然后就可以在程序中通过宏指令多次调用该段代码。  

5 其他常用的伪指令   还有一些其他的伪指令,在汇编程序中经常会被使用,主要包括AREA、ALIGN、CODE16、CODE32、ENTRY、END、EXPOR(或 GLOBAL)IMPORT、EXTERN、GET(或 INCLUDE )INCBIN、RN、ROUT等。

5 其他常用的伪指令(Cont.) (1)AREA         语法格式: AREA 段名 属性 1 ,属性 2 ,……     AREA 伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用 “ | ” 括起来,如 |1_test| 。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。

5 其他常用的伪指令(Cont.) (2) ALIGN 语法格式: ALIGN { 表达式 { , 偏移量 }} (3) CODE16、CODE32         语法格式:    CODE16 (或 CODE32 ) (4) ENTRY     语法格式: ENTRY       ……

5 其他常用的伪指令(Cont.) (5) END 语法格式: END (6) EXPORT(或GLOBAL)     语法格式: EXPORT 标号 {[WEAK]} (7) IMPORT     语法格式: IMPORT 标号 {[WEAK]}    

5 其他常用的伪指令(Cont.) (8) EXTERN 语法格式: EXTERN 标号 {[WEAK]} (9) GET(或INCLUDE)     语法格式:   GET 文件名  (10) INCBIN         语法格式:INCBIN 文件名  (11) RN         语法格式:    名称 RN 表达式  

ARM的汇编语言结构 在ARM(Thumb)汇编语言程序中,以相对独立的指令或数据序列的程序段为单位组织程序代码。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段,也可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映象文件。可执行映象文件通常由以下几部分构成:   ① 一个或多个代码段,代码段的属性为只读。   ② 零个或多个包含初始化数据的数据段,数据段的属性为可读写。   ③ 零个或多个不包含初始化数据的数据段,数据段的属性为可读写。

ARM汇编语言的语句格式 1. 基本语句格式 ARM(Thumb)汇编语言的语句格式为: {标号} {指令或伪指令} {;注释} 规则: {标号} {指令或伪指令} {;注释} 规则:   ① 如果一条语句太长,可将其分为若干行来书写,在行的末用续行符“\”来标识下一行与本行为同一条语句。   ② 每一条指令的助记符可以全部用大写、或全部用小写,但不能在一条指令中大、小写混用。

ARM汇编语言的语句格式(Cont.) 2. 汇编语言程序中常用的符号 在汇编语言程序设计中,可以使用各种符号代替地址、变量和常量等,以增加程序的可读性。以下为符号命名的约定:   ① 符号名不应与指令或伪指令同名   ② 符号在其作用范围内必须唯一。   ③ 符号区分大小写,同名的大、小写符号被视为两个不同的符号。   ④ 自定义的符号名不能与系统保留字相同。

ARM汇编语言的语句格式(Cont.) 3. 程序中的常量 3. 程序中的常量 程序中的常量是指其值在程序的运行过程中不能被改变的量。ARM(Thumb)汇编程序所支持的常量有逻辑常量、数字常量和字符串常量。   ① 数字常量一般为32位的整数,无符号常量取值范围为0~232-1,有符号常量取值范围为-231~231-1。   ② 逻辑常量只有两种取值:真或假。   ③ 字符串常量为一个固定的字符串,一般用来提示程序运行时的信息。

ARM汇编语言的语句格式(Cont.) 4. 汇编语言程序中的变量 程序中的变量是指其值在程序的运行过程中可以改变的量。   ① 逻辑变量用于在程序的运行中保存逻辑值(真/假)。   ② 数字变量用于在程序的运行中保存数字值,但数字值的大小不应超出数字变量所能表示的范围。   ③ 字符串变量用于在程序的运行中保存一个字符串,但字符串的长度不应超出字符串变量所能表示的范围。

ARM汇编语言的语句格式(Cont.) 5. 程序中的变量代换 程序中的变量可通过代换操作取得一个常量。代换操作符为“$”。如果“$”在数字变量前面,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量。

基于Windows下ADS的汇编语言程序结构 ADS环境下的ARM汇编语言程序结构与其它环境下的汇编语言程序结构大体相同,整个程序也是以段为单元来组织代码。其语法规则总结如下:   ① 所有标号必须在一行的顶格书写,其后不要添加“:”号;   ② 所有的指令均不能顶格写;   ③ 大小写敏感(可以全部大写或全部小写,但不能大小写混合使用);   ④ 注释使用分号“;” 。

基于Linux下GCC的汇编语言程序结构 Linux下GCC的汇编语言结构与其它环境下的汇编语言结构相似,整个程序都是以程序段为单位来组织代码,但是在语言规则上与ADS环境下的ARM汇编语言规则有明显的区别。现将Linux下GCC的汇编语言规则总结如下:   ① 所有标号必须在一行的顶格书写,并且其后必须添加“:”号;   ② 所有的指令均不能顶格写;   ③ 大小写敏感(可以全部大写或全部小写,但不能大小写混合使用);   ④ 注释使用分号“@” (注释的内容由“@” 号起到此行结束,注释可以在一行的顶格书写);

ARM汇编语言程序调试 无论进行嵌入式系统软件开发还是硬件电路设计,调试永远是不可缺少的、非常重要的一个环节。通常嵌入式系统的调试方法和类型有很多种,最为常见的包括软件模拟调试、硬件仿真器在线调试、Wiggler线缆调试和Linux环境下的gdb程序调试。

ADS软件模拟环境下的程序调试 ADS软件模拟调试是利用ARMUL.dll提供的一个软ARM内核,调试工具和待调试的嵌入式软件都在主机上运行,由主机提供一个模拟的目标运行环境,可以进行语法和逻辑上的调试。它的优点是简单方便,不需要嵌入式目标板,软件的调试功能较强;功能有限,不能进行实时联机调试。

ADS硬件仿真器环境下的程序调试 在ADS环境下利用JTAG硬件仿真器可以实现联机调试,即在线调试嵌入式设备的Flash中的程序或者SDRAM中的程序。由于仿真器自成体系,调试时既可以连接目标板,也可以不连接目标板,当然仿真器的价格也相对比较贵。一般在程序的前期开发,通常让程序只在SDRAM中调试运行,最后才下载到Flash中进行调试运行。

ADS硬件仿真器环境下的程序调试(Cont.) ARM仿真器是通过内部硬件实现PC并口协议到串行JTAG(Jiont Test Action Gruop)协议的转换。利用高速JTAG串行扫描链,通过调试通信通道(Debug Communications Channel,DCC)连接ARM核心内嵌的名为“Embedded-ICE”的调试逻辑,调试逻辑实时监测ARM核心的寄存器、数据总线和地址总线。

ADS硬件仿真器环境下的程序调试(Cont.) 1. Multi-ICE server 软件的安装

ADS硬件仿真器环境下的程序调试(Cont.) 2.运行Multi-ICE server 保证硬件正确连接后,即可运行Multi-ICE server,默认情况下,server 会用自动配置来连接目标器件。当然,可以在settings 菜单下选择配置的方式,一般选择Atuo-Configure即可。 如果正确连接到一个ARM内 核的嵌入式目标板,将显示 图。

ADS硬件仿真器环境下的程序调试(Cont.) 3. 配置ADS以支持JTAG仿真器 启动ADS的调试器AXD后,从菜单“Option”中选择“Configure Target”,在弹出的窗口中,选择Multi-ICE,如果没有此项,则需要将Multi-ICE驱动添加到对话框中。如图所示。

ADS Wiggler调试电缆环境下的程序调试 Wiggler调试电缆实际上可以看出就是一个简易的JTAG“仿真器”,它也支持ADS集成开发环境和在线联机调试,支持单步、全速及断点等调试功能。

ADS Wiggler调试电缆环境下的程序调试(Cont.) 1. Wiggler JTAG 调试电缆的驱动安装 要使用Wiggler JTAG 调试电缆来调试ARM 处理器,除了ADS1.2 集成开发环境外,还需要安装一个ARM 调试代理,一般使用H-JTAG 软件,H-JTAG 软件的特点如下: ① 支持ARM7/ARM9,支持自动检测和手动指定内核; ② 使用RDI 接口,支持SDT2.51、ADS1.2、REALVIEW 和IAR 集成开发环境; ③ 支持2 个硬件断点或数量不限的软件断点;

④ 支持ARM/Thumb 模式; ⑤ 支持Little Endian & BIG Endian 模式; ⑥ 支持Semihosting 调试; ⑦ 支持Wiggler、SDT JTAG 和自定义接口。 首先,用鼠标双击H-JTAG软件的安装文件H-JTAG V0.2.exe,启动H-JTAG 安装界面,按照提示操作完成安装。

ADS Wiggler调试电缆环境下的程序调试(Cont.) 2. 运行H-JATG软件 接着,将Wiggler JTAG 调试电缆一头通过并口延长线与PC机的并口连接,另一头接到嵌入式目标板的JTAG插座上。然后启动H-JTAG。H-JTAG会自动检测ARM 内核,如果JTAG 连接正确将会在H-JTAG主窗口中显示处理器的型号.

ADS Wiggler调试电缆环境下的程序调试(Cont.) 3. 配置ADS以支持JTAG仿真器 启动ADS的调试器AXD后,从菜单“Option”中选择“Configure Target”,在弹出的窗口中,添加或选择H-JTAG.dll(如图所示)。

Linux环境下的gdb程序调试 Linux下提供了一个叫 gdb的GNU调试程序,主要用来调试C、C++等应用程序。它可以提供: ① 监视程序中变量的值; ② 设置断点以使程序在指定的代码行上暂停执行; ③ 单步执行; 语法格式: gdb <fname>

gdb 基本命令

ARM汇编语言与C语言混合编程 ARM体系结构支持C/C++以及汇编语言的混合编程,在一个完整的程序设计中,除了初始化部分用汇编完成以外,其主要的编程任务一般都用C/C++完成。 汇编语言和C/C++的混合编程通常有以下几种方式: ① 汇编程序中调用C程序 ② C程序中调用汇编程序 ③ C程序中内嵌汇编语句 ④ 从汇编程序中访问C程序变量

基本的ATPCS 基本的ATPCS规定了在混合编程时子程序调用的一些基本规则,主要包括寄存器的使用、堆栈的使用、参数传递和子程序结果的返回等方面的规则。 1. 寄存器的使用规则 ① 程序通过寄存器R0~R3来传递参数,这时这些寄存器可以记作A0~A3,被调用的子程序在返回前无需恢复寄存器R0~R3的内容。

基本的ATPCS (Cont.) ② 在子程序中,使用R4~R11来保存局部变量,这时这些寄存器可以记作V1~V8。 ③ 寄存器R12用作子程序间scratch寄存器,记作IP,在子程序的连接代码段中经常会有这种使用规则。

基本的ATPCS (Cont.) ④ 寄存器R13用作数据栈指针,记做SP,在子程序中寄存器R13不能用做其他用途。 ⑤ 寄存器R14用作连接寄存器,记作LR,它用于保存子程序的返回地址。 ⑥ 寄存器R15是程序计数器,记作PC,它不能用作其他用途。 ⑦ ATPCS中的各寄存器在ARM编译器和汇编器中都是预定义的。

基本的ATPCS (Cont.) 2. 堆栈的使用规则      栈指针通常可以指向不同的位置,当栈指针指向栈顶元素时,称为FULL栈。当栈指针指向与栈顶元素相邻的一个元素时,称为Empty栈。 数据栈的增长方向也可以不同,当数据栈向内存减小的地址方向增长时,称为Descending栈;反之称为Ascending栈。

基本的ATPCS (Cont.) 3. 参数的传递规则 根据参数个数是否固定,可以将子程序分为参数个数固定的子程序和参数个数可变的子程序,这两种子程序的参数传递规则不同的。  ① 参数个数可变的子程序参数传递规则。 ② 参数个数固定的子程序参数传递规则。

基本的ATPCS (Cont.) 4. 子程序结果返回规则 ① 结果为一个32位的整数时,可通过寄存器R0返回。 ② 结果为一个64位整数时,可以通R0和R1返回,依此类推。 ③ 结果为一个浮点数时,可以通过浮点运算部件的寄存器f0,d0或者s0来返回。 ④ 结果为一个复合的浮点数时,可以通过寄存器f0-fN或者d0~dN来返回。 ⑤ 对于位数更多的结果,则需要通过调用内存来传递。

汇编程序中调用C程序 2. C语言文件 /*C file, called by asmfile */ int cFun(int a, int b, int c) { return a + b + c; } 这里的参数传递是利用寄存器r0~r2。需要指出的是当函数的参数个数大于4时就要借助堆栈。

C程序中调用汇编程序 在汇编程序中使用EXPORT伪指令声明程序,使得本程序可以被其他的程序调用;在C语言中使用EXTERN关键词声明该汇编程序,这样就可以在C中使用该函数了。从C的角度,并不知道该函数的实现是用C还是汇编。

C程序中内嵌汇编语句 在C中内嵌的汇编指令支持大部分的ARM和Thumb指令,不过其使用与汇编文件中的指令有些不同,存在一些限制,主要有下面几个方面: ① 不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令; ② 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突; ③ R12和R13可能被编译器用来存放中间编译结果; ④ 一般不要直接指定物理寄存器,而让编译器进行分配;

从汇编程序中访问C程序变量 在C程序中声明的全局变量可以被汇编程序通过地址间接访问,具体访问方法如下: ① 使用IMPORT伪指令声明该全局变量。 ② 使用LDR指令读取该全局变量的内存地址,通常该全局变量的内存地址值存放在程序的数据缓冲区中。 ③ 根据该数据的类型,使用相应的LDR指令读取该全局变量的值,使用相应的STR指令修改该全局变量的值。

从汇编程序中访问C程序变量(Cont.) 各数据类型及其对应的LDR/STR指令如下: ① 对于无符号的char类型的变量通过指令LDRB/STRB来读写。 ② 对于无符号的short类型的变量通过指令LDRH/STRH读写。 ③ 对于int类型的变量通过指令LDR/STR来读写。 ④ 对于有符号的char类型的变量通过指令LDRSB来读取。 ⑤ 对于有符号的char类型的变量通过指令STRB来写入。

⑥ 对于有符号的short类型的变量通过指令LDRH来读取。 ⑧ 对于小于8个字的结构型变量,可以通过一条LDM/STM指令来读/写整个变量。 ⑨ 对于结构型变量的数据成员,可以使用相应的LDR/STR指令来访问,这时必须知道该数据成员相对于结构型变量开始地址的偏移量。

从汇编程序中访问C程序变量(Cont.) 下面是一个在汇编程序中访问C程序全局变量的例子。 AREA global_exp, CODE, READONLY EXPORT asmsub IMPORT globv ;声明全局变量 asmsub LDR r1, = globv ;将内存地址读入到R1中 LDR r0, [r1] ;将数据读入到R0中 ADD r0, r0, #2 STR r0, [r1] ;修改 后再将值赋予变量 MOV pc, lr END

从汇编程序中访问C程序变量(Cont.) 程序中,变量globv1是在C程序中声明的全局变量,在汇编程序中首先使用IMPORT伪指令声明该变量,再将其内存地址读入到寄存器R1中,将其值读入到寄存器R0中,修改后再将寄存器R0的值赋予变量globv。