描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302459392丛书名: 21世纪高等学校嵌入式系统专业规划教材
本书重点介绍ARM9微处理器的结构、开发工具、Linux程序设计等,并包含嵌入式CDIO的丰富实训。本书配有PPT课件和编程实训的程序源代码。
本书共分5部分: 第1部分(第1章)为理论部分,着重介绍嵌入式系统的概念,包括嵌入式的特点、分类和应用; 第2部分(第2~6章)为基础部分,着重介绍ARM9体系结构、指令系统、寻址方式、指令集,伪指令、汇编语言程序设计基础及与C/C 的混合编程,S3C2440A 控制器的结构原理及外围电路的设计方法等; 第3部分(第7章)为开发工具部分,着重介绍ADS 1.2集成开发环境及嵌入式Linux的软件开发环境的使用; 第4部分(第8~11章)为操作系统部分,着重介绍Linux的程序设计; 第5部分为第2版新增部分(第12章),增加了嵌入式CDIO工程实训环节。
本书采用理论与实践相结合的方法,立足于应用,具有有针对性、实用性及综合性强等特点。
本书不仅适用于高等院校计算机、物联网、电子、自动化等相关专业的本科教学,也适合于从事嵌入式系统研究与开发的技术人员及普通读者参考。
目录
第1章嵌入式系统概述
1.1嵌入式系统定义
1.1.1嵌入式系统的概念
1.1.2嵌入式系统的特点
1.2嵌入式系统的组成
1.2.1嵌入式系统硬件
1.2.2嵌入式系统软件
1.2.3嵌入式系统的开发系统和开发工具
1.3嵌入式系统的应用
1.4本章小结
1.5习题1
第2章ARM微处理器概述与编程模型
2.1ARM微处理器概述
2.1.1ARM微处理器的特点
2.1.2ARM微处理器系列
2.2ARM微处理器结构
2.2.1RISC体系结构
2.2.2ARM微处理器的寄存器结构
2.2.3ARM微处理器的指令结构
2.3ARM微处理器的工作状态
2.4ARM体系结构的存储器格式
2.4.1指令长度及数据类型
2.4.2存储管理单元
2.5处理器模式
2.6寄存器组织
2.6.1ARM状态下的寄存器组织
2.6.2Thumb状态下的寄存器组织
2.6.3程序状态寄存器
2.7异常
2.7.1ARM体系结构所支持的异常类型
2.7.2异常优先级
2.7.3异常的响应及返回
2.7.4应用程序中的异常处理
2.8本章小结
2.9习题2
第3章ARM9指令系统
3.1ARM处理器的寻址方式
3.1.1寄存器寻址
3.1.2立即寻址
3.1.3寄存器间接寻址
3.1.4变址寻址
3.1.5寄存器移位寻址
3.1.6多寄存器寻址
3.1.7堆栈寻址
3.1.8相对寻址
3.2ARM指令集
3.2.1指令格式
3.2.2条件码
3.2.3ARM 存储器访问指令
3.2.4ARM 数据处理类指令
3.2.5ARM 分支指令
3.2.6ARM 协处理器指令
3.2.7ARM 软件中断指令
3.3Thumb指令集
3.4本章小结
3.5习题3
第4章嵌入式程序设计基础
4.1伪指令
4.1.1通用伪指令
4.1.2与ARM指令相关的伪指令
4.1.3与Thumb指令相关的伪指令
4.2汇编语言的语句格式
4.2.1书写格式
4.2.2汇编语言中表达式和运算符
4.3汇编程序应用
4.3.1汇编程序基本结构
4.3.2子程序调用
4.4汇编语言与C/C 的混合编程
4.4.1在C/C 程序中内嵌汇编指令的语法格式
4.4.2C/C 与汇编语言的混合编程应用
4.5本章小结
4.6习题4
第5章嵌入式内部可编程模块
5.1存储控制模块
5.1.1存储器控制器
5.1.2NAND Flash控制器
5.1.3存储器实例
5.2GPIO
5.2.1端口功能
5.2.2端口配置寄存器
5.2.3端口其他寄存器
5.2.4I/O应用实例
5.3中断系统
5.3.1中断优先级
5.3.2中断控制寄存器
5.3.3中断编程实例
5.4定时部件
5.4.1看门狗定时器原理及实例
5.4.2RTC部件
5.4.3Timer部件
5.4.4定时部件应用实例
5.5UART
5.5.1UART的操作
5.5.2UART接口寄存器
5.5.3UART实例
5.6ADC及触摸屏接口
5.6.1功能描述
5.6.2ADC及触摸屏接口特殊寄存器
5.6.3A/D转换实例
5.7本章小结
5.8习题5
第6章嵌入式接口技术应用
6.1LCD显示器接口
6.1.1LCD的控制器
6.1.2S3C2440A芯片的LCD专用寄存器
6.1.3S3C2440A芯片LCD寄存器的设置
6.2I2C总线
6.2.1S3C2440A的I2C接口
6.2.2I2C总线接口特殊寄存器
6.2.3I2C编程举例
6.3I2S总线
6.3.1发送接收模式
6.3.2音频串行接口格式
6.3.3I2S总线接口特殊寄存器
6.3.4I2S编程实例
6.4AC97控制器
6.4.1AC97控制器操作
6.4.2AC97控制器特殊寄存器
6.4.3AC97应用实例
6.5本章小结
6.6习题6
第7章软件开发环境
7.1ADS1.2集成开发环境
7.1.1使用ADS创建工程
7.1.2用AXD进行代码调试
7.2嵌入式Linux的交叉编译环境安装
7.3本章小结
7.4习题7
第8章嵌入式系统Boot Loader技术
8.1Boot Loader的基本概念
8.1.1Boot Loader的相关设备和机制
8.1.2Boot Loader的启动过程
8.1.3Boot Loader的操作模式
8.1.4Boot Loader的总体设计
8.2Boot Loader(vivi)的代码分析
8.3本章小结
8.4习题8
第9章嵌入式Linux操作系统移植
9.1嵌入式Linux基本概念
9.2嵌入式Linux内核移植
9.2.1内核修改
9.2.2内核配置
9.2.3内核编译
9.3建立Linux根文件系统
9.4下载目标文件
9.5本章小结
9.6习题 9
第10章嵌入式Linux设备驱动程序开发
10.1嵌入式Linux驱动程序开发基础
10.1.1嵌入式Linux设备驱动程序分类
10.1.2简单的内核模块
10.2嵌入式Linux设备驱动重要技术
10.2.1内存与I/O端口
10.2.2同步机制
10.2.3阻塞与非阻塞
10.2.4时间问题
10.2.5中断处理
10.3字符设备驱动程序
10.3.1字符设备驱动结构
10.3.2字符设备驱动实例——LED驱动
10.4网络设备驱动程序
10.4.1Linux 网络设备简介
10.4.2网络驱动核心数据结构
10.4.3网络驱动程序分析
10.5设备驱动实例
10.5.1ADC设备驱动实例
10.5.2PWM设备驱动实例
10.5.3触摸屏设备驱动实例
10.6本章小结
10.7习题10
第11章嵌入式Linux应用程序设计
11.1嵌入式Linux C语言应用程序开发基础
11.1.1编写源程序
11.1.2交叉编译程序
11.1.3调试程序
11.2文件I/O编程
11.2.1文件I/O操作例程
11.2.2文件I/O操作API
11.3网络编程
11.3.1网络通信基础及例程
11.3.2网络通信API
11.4应用实例
11.4.1ADC应用实例
11.4.2PWM蜂鸣器控制应用实例
11.4.3触摸屏应用实例
11.5本章小结
11.6习题11
第12章嵌入式CDIO实训项目
实训1ARM汇编基础训练1
实训2ARM汇编基础训练2
实训3GPIO输入输出实训
实训4GPIO定时器中断应用实训
实训5直流电机应用实训
实训6温度采集应用实训
实训7红外通信应用实训
实训8CAN总线应用实训
参考文献
第1版前言
“嵌入式无处不在”已成为现实。嵌入式系统应用的领域日益广阔,与网络通信、数字家庭、工业控制、国防军事、医疗系统、安防系统、能源系统、交通系统等行业融合正在加深,智能设备终端应用市场的快速发展对嵌入式系统提出了持续需求,使得嵌入式系统产业在前所未有的机遇下快速地发展。因此,系统地开设嵌入式系列课程是必要的,这样就需要合适的配套教材,鉴于这种情况,作者参考了大量国内外教材,结合应用型本科院校的特点,编写了《嵌入式系统原理及应用教程》一书。全书着眼于“应用”、立足于“工程开发”,具有以下特点。1. 综合性嵌入式系统是嵌入式硬件和嵌入式软件的综合体,硬件的设计服务于软件功能,软件的开发也必须考虑硬件资源的有限性。根据嵌入式系统的这一特点,本书采用“ARM9处理器 Linux操作平台 应用程序设计”的介绍方法。2. 基础性本书详细地讲解了ARM9处理器的体系结构和编程方法,尤其是举例讲解了指令系统中的指令集及汇编语言与C/C 混合编程的方法,以便读者掌握好底层嵌入式开发的技能。3. 实用性本书以S3C2440A芯片和Linux操作系统为例,举例介绍了开发环境的使用与调试方法,详细介绍了嵌入式软件的编程技术。例如介绍AC97音频控制器和触摸屏的设计实例。4. 针对性本书是编者几年嵌入式教学的总结。主要是针对应用型本科学生实践性强的特点,在介绍ARM9处理器的原理及结构的同时,注重了各功能模块的应用介绍。本书系统地介绍了嵌入式系统软硬件的组成、工作原理和设计方法。全书分为4部分,共11章,主要内容和篇章结构安排如下。第1部分为理论部分,由第1章组成。介绍嵌入式系统的基本概念,包括嵌入式系统的定义、组成、特点、分类和应用领域。第2部分为基本部分,由第2~6章组成。第2章重点讲解ARM9处理器的体系结构; 第3章详细讲解基于ARM的嵌入式处理器指令系统; 第4章讲解其嵌入式系统的程序设计基础,包括汇编语言程序设计及与C/C 语言的混合编程技术; 第5~6章详细讲解S3C2440A芯片内部结构、内部外设及工作原理和应用方法,并辅以实例讲解。第3部分为开发工具部分,由第7章组成。着重讲解ADS1.2集成开发环境及嵌入式Linux的软件开发环境的使用。第4部分为操作系统部分,由第8~11章组成。第8章详细分析嵌入式系统的Boot Loader; 第9~11章以实例的方式讲解基于“S3C2440A芯片 Linux操作平台”的设计方法。全书由孟祥莲主编并编写第3~6章,高洪志编写第1~2章,孙平编写第7~8章,朱国晗编写第9~11章。由于嵌入式技术发展迅速,加上作者水平有限,时间仓促,书中难免有疏漏和错误之处,无论如何,请读者不吝赐教,以便我们在改版或再版的时候及时纠正补充。
作者2010年8月
MOV R2,R3; R2←R3R3中的内容赋给R2
ADDR2,R3,R4; R2←R3+R4R3和R4中的内容相加,结果赋给R2
3.1.2立即寻址立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数没有存储在寄存器或存储器中,而是包含在指令的操作码中,只要取出指令也就取到了操作数。这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。例如以下指令:
ADDR1,R1,#1234; R1←R1+1234
ADDR1,R1,#0x7f; R1←R1+0x7f
在以上两条指令中,第二个源操作数即为立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在“#”后加上“0x”。3.1.3寄存器间接寻址寄存器间接寻址就是以寄存器中的内容作为操作数的地址,而操作数本身存放在存储器中。例如以下指令:
LDRR1,[R2]; R1←[R2]
STRR1,[R2]; [R2]←R1
条指令以R2中的内容为地址,将该地址中的数据传送到R1中。第二条指令将R1中的内容传送到以R2中的内容为地址的存储器中。3.1.4变址寻址变址寻址就是将寄存器(该寄存器一般称为基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。采用变址寻址方式的指令有以下几种常见形式,如下所示。
LDR R0,[R1,#8]; R0←[R1+8]
LDR R0,[R1,#8]!; R0←[R1+8],R1←R1+8
LDR R0,[R1],#2; R0←[R1],R1←R1+2
LDR R0,[R1,R2]; R0←[R1+R2]
在条指令中,将寄存器R1的内容加上8形成操作数的有效地址,从而取得操作数存入寄存器R0中。在第二条指令中,将寄存器R1的内容加上8形成操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增8个字节。在第三条指令中,以寄存器R1的内容作为操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增8个字节。在第四条指令中,将寄存器R1的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存入寄存器R0中。3.1.5寄存器移位寻址寄存器移位寻址是ARM指令集独有的寻址方式,操作数由寄存器的数值进行相应移位而得到; 移位的方式在指令中以助记符的形式给出,而移位的位数可用立即数或寄存器寻址方式表示。ARM微处理器内嵌的桶型移位器(barrel shifter),移位操作在ARM指令集中不作为单独的指令使用,它只能作为指令格式中的一个字段,在汇编语言中表示为指令中的选项。例如,数据处理指令的第2个操作数为寄存器时,就可以加入移位操作选项对它进行各种移位操作。移位操作包括如下6种类型,ASL和LSL是等价的,可以自由互换。1. LSL(或ASL)操作LSL(或ASL)操作的格式为:
通用寄存器,LSL(或ASL) 操作数
LSL(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操作,按操作数所指定的数量向左移位,低位用零来填充,后一个左移出的位放在状态寄存器的C位CPSR[29]中,如图31所示。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
图31逻辑(或算术)左移
操作示例:
MOVR0, R1, LSL#4; 将R1中的内容左移4位后传送到R0中
; 其中把后移出的位赋给程序状态寄存器的C位CPSR[29]
2. LSR操作LSR操作的格式为:
通用寄存器,LSR 操作数
LSR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端用零来填充,后一个右移出的位放在状态寄存器的C位CPSR[29]中,如图32所示。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
图32逻辑(或算术)右移
操作示例:
MOVR0, R1, LSR#4; 将R1中的内容右移4位后传送到R0中
; 其中把后移出的位赋给程序状态寄存器的C位CPSR[29]
3. ROR操作ROR操作的格式为:
通用寄存器,ROR 操作数
ROR可完成对通用寄存器中的内容进行循环右移的操作,按操作数所指定的数量向右循环移位,右端移出的位填充在左侧的空位处,后一个右移出的位同时也放在状态寄存器的C位CPSR[29]中,如图33所示。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
图33循环右移
操作示例:
MOVR0, R1, ROR#4; 将R1中的内容循环右移4位后传送到R0中
; 其中把后移出的位赋给程序状态寄存器的C位CPSR[29]
4. ASR操作ASR操作的格式为:
通用寄存器,ASR 操作数
ASR可完成对通用寄存器中的内容进行右移的操作,按操作数所指定的数量向右移位,左端的位保持不变,后一个右移出的位放在状态寄存器的C位CPSR[29]中,如图34所示。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
图34算术右移
这种移位对有符号数据使用时可以保持符号位不变。操作示例:
MOVR0, R1, ASR#4; 将R1中的内容右移4位后传送到R0中,符号位保持不变
; 后移出的位同时也送入状态位C中
5. RRX操作RRX操作的格式为:
通用寄存器,RRX
RRX可完成对通用寄存器中的内容进行带扩展的循环右移的操作,按操作数所指定的数量向右循环移位,左侧空位由状态寄存器C位来填充,右侧移出的位移进状态位C中,如图35所示。其中,操作数可以是通用寄存器,也可以是立即数(0~31)。
图35扩展的循环右移
操作示例:
MOVR0, R1, RRX; 将R1中的内容进行带扩展的循环右移1位后传送到R0中
3.1.6多寄存器寻址采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以一次对多个寄存器寻址,多个寄存器由小到大排列,多可传送16个寄存器。例如:
LDMIA R1,{R2R4,R5}; R2←[R1]
; R3←[R1+4]
; R4←[R1+8]
; R5←[R1+12]
该指令的后缀IA表示在每次执行完加载/存储操作后,R1按字长度增加,因此,指令可将连续存储单元的值传送到R2~R5。3.1.7堆栈寻址堆栈是一种数据结构,按先进后出(first in last out,FILO)的方式工作,使用一个称做堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。当堆栈指针指向后压入堆栈的数据时,称为满堆栈(full stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(empty stack)。同时,根据堆栈的生成方式,又可以分为递增堆栈(ascending stack)和递减堆栈(decending stack)。当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有4种类型的堆栈工作方式,ARM微处理器支持这4种类型的堆栈工作方式,即: 满递增方式(full ascending,FA),堆栈指针指向后入栈的数据位置,且由低地址向高地址生成。 满递减方式(full decending,FD),堆栈指针指向后入栈的数据位置,且由高地址向低地址生成。 空递增方式(empty ascending,EA),堆栈指针指向下一个入栈数据的空位置,且由低地址向高地址生成。 空递减方式(empty decending,ED),堆栈指针指向下一个入栈数据的空位置,且由高地址向低地址生成。3.1.8相对寻址 与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的调用和返回,跳转指令BL采用了相对寻址方式。
BLNEXT; 跳转到子程序NEXT处执行
…
NEXT
…
MOVPC,LR; 从子程序返回
3.2ARM指令集ARM微处理器的指令集是加载/存储型的,即指令集仅能处理寄存器中的数据,处理结果仍要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。3.2.1指令格式为了方便编写程序,ARM指令在汇编程序中用助记符表示。一般ARM指令的助记符格式如下:
{}{s} ,,
其中各项介绍如下。: 操作码,如ADD 表示算术加操作指令。{}: 决定指令执行的条件码。{s}: 决定指令执行是否影响CPSR寄存器的值。: 目的寄存器。: 个操作数,为寄存器。: 第二个操作数。注意: opcode、cond与s之间没有分隔符,s与Rd之间用空格隔开。3.2.2条件码当处理器工作在ARM状态时,几乎所有的指令均根据CPSR中条件码的状态和指令的条件域有条件地执行。当指令的执行条件满足时,指令被执行,否则指令被忽略。每一条ARM指令包含4位的条件码,位于指令的4位[31:28]。条件码共有16种,每种条件码可用两个字符表示,这两个字符可以添加在指令助记符的后面和指令同时使用。例如,跳转指令B可以加上后缀EQ变为BEQ表示“相等则跳转”,即当CPSR中的Z标志置位时发生跳转。在16种条件标志码中,只有15种可以使用,如表31所示,第16种(1111)为系统保留,暂时不能使用。
表31指令的条件码
条件码助记符后缀标志含义
0000EQZ置位相等0001NEZ清零不相等0010CSC置位无符号数大于或等于0011CCC清零无符号数小于0100MIN置位负数0101PLN清零正数或零0110VSV置位溢出0111VCV清零未溢出1000HIC置位Z清零无符号数大于1001LSC清零Z置位无符号数小于或等于1010GEN等于V带符号数大于或等于1011LTN不等于V带符号数小于1100GTZ清零且(N等于V)带符号数大于1101LEZ置位或(N不等于V)带符号数小于或等于1110AL忽略无条件执行
3.2.3ARM 存储器访问指令ARM微处理器内部没有RAM,而ARM除了寄存器(即R0~R15)外没有别的存储单元; 在以ARM为核的嵌入式系统中,所有的外围模块都和存储单元一样,是ARM微处理器的不同的地址单元。不管这些模块的功能如何(如输入输出、定时器、存储器等),也不管这些模块的位置如何(如片内或片外),ARM微处理器都把它们看作是外部存储器。其操作过程和对存储器的操作是相同的。因此,在ARM微处理器的数据传送中,数据的源和数据的目标只有两种: 一种是ARM的寄存器R0~R15; 另一种就是外部存储器(它们可能是外围模块的寄存器、外部数据存储器或可访问的程序存储器等)。因此,把数据从存储器到寄存器的传送叫加载,数据从寄存器到存储器的传送叫存储。具体的传送方式如图36所示。
图36ARM微处理器的数据传送方式
加载/存储指令可分为: 单一数据加载/存储指令、批量数据加载/存储指令以及数据交换指令3类。常用的加载/存储指令如下所示。1. 单一数据加载/存储指令(1) LDR指令LDR指令的格式为:
LDR{条件} 目的寄存器,
LDR指令是字加载指令,用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令通常用于从存储器中读取32位的字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。指令示例:
LDRR3,[R4]; 将存储器地址为R4的字数据读入寄存器R3
LDRR3,[R1,R2]; 将存储器地址为R1 R2的字数据读入寄存器R3
LDRR3,[R1,#8]; 将存储器地址为R1 8的字数据读入寄存器R3
LDRR3,[R1,R2]!; 将存储器地址为R1 R2的字数据读入寄存器R3,并将新地址; R1+R2写入R1
LDRR3,[R1,#8] !; 将存储器地址为R1 8的字数据读入寄存器R3,并将新地址; R1+8写入R1
LDRR3,[R1],R2; 将存储器地址为R1的字数据读入寄存器R3,并将新地址R1+R2; 写入R1
LDRR3,[R1,R2,LSL#3]!; 将存储器地址为R1+R2×8的字数据读入寄存器R3,并将新地; 址R1+R2×8写入R1
LDRR3,[R1],R2,LSL#3; 将存储器地址为R1的字数据读入寄存器R3,并将新地址R1+; R2×8写入R1
注: R15不可以作为偏移寄存器使用。(2) LDRB指令LDRB指令的格式为:
LDR{条件}B 目的寄存器,
LDRB指令是字节加载指令,用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。该指令通常用于从存储器中读取8位的字节数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。指令示例:
LDRBR3,[R1]; 将存储器地址为R1的字节数据读入寄存器R3,并将R3的高24位清零
LDRBR3,[R1,#8]; 将存储器地址为R1+8的字节数据读入寄存器R3,并将R3的高24位清零
(3) LDRH指令LDRH指令的格式为:
LDR{条件}H 目的寄存器,
LDRH指令是无符号半字加载指令,用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高16位清零。该指令通常用于从存储器中读取16位的半字数据到通用寄存器,然后对数据进行处理。当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转。指令示例:
LDRHR3,[R1]; 将存储器地址为R1的半字数据读入寄存器R3,并将R3的高16位清零
LDRHR3,[R1,#8]; 将存储器地址为R1+8的半字数据读入寄存器R3,并将R3的高16位清零
LDRHR3,[R1,R2]; 将存储器地址为R1+R2的半字数据读入寄存器R3,并将R3的高16位清零
(4) STR指令STR指令的格式为:
STR{条件} 源寄存器,
STR指令是字存储指令,用于从源寄存器中将一个32位的字数据传送到存储器中。该指令在程序设计中比较常用,且寻址方式灵活多样,使用方式可参考指令LDR。指令示例:
STRR3,[R1],#8; 将R3中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1
STRR3,[R1,#8]; 将R3中的字数据写入以R1+8为地址的存储器中
(5) STRB指令STRB指令的格式为:
STR{条件}B 源寄存器,
STRB指令是无符号字节存储指令,用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。指令示例:
STRBR3,[R1]; 将寄存器R3中的字节数据写入以R1为地址的存储器中
STRBR3,[R1,#8]; 将寄存器R3中的字节数据写入以R1+8为地址的存储器中
(6) STRH指令STRH指令的格式为:
STR{条件}H 源寄存器,
STRH指令是无符号半字存储指令,用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。指令示例:
STRHR3,[R1]; 将寄存器R3中的半字数据写入以R1为地址的存储器中
STRHR3,[R1,#8]; 将寄存器R3中的半字数据写入以R1+8为地址的存储器中
2. 批量数据加载/存储指令ARM微处理器所支持的批量数据加载/存储指令可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操作。常用的加载存储指令如下。
LDM(或STM)指令
LDM(或STM)指令的格式为:
LDM(或STM){条件}{类型} 基址寄存器{!},寄存器列表{∧}
LDM(或STM)指令用于在由基址寄存器所指示的一片连续存储器和寄存器列表所指示的多个寄存器之间传送数据,该指令的常见用途是将多个寄存器的内容入栈或出栈。其中,{类型}为以下几种情况。IA每次传送后地址加1,递增方式。 IB每次传送前地址加1,递增方式。 DA每次传送后地址减1,递减方式。 DB每次传送前地址减1,递减方式。 FD满递减堆栈。 ED空递减堆栈。 FA满递增堆栈。 EA空递增堆栈。 {!}为可选后缀,若选用该后缀,则当数据传送完毕之后,将后的地址写入基址寄存器,否则基址寄存器的内容不改变。基址寄存器不允许为R15。寄存器列表可以为R0~R15的任意组合,若使用连续的寄存器时,可以使用“”表示省略。{∧}为可选后缀,这是一个只是在数据块传送中使用的后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示: 除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。指令示例:
STMFDR13!,{R0,R4R12,LR}; 将寄存器列表中的寄存器(R0,R4~R12,LR)存入堆栈
LDMFDR13!,{R0,R4R12,PC}; 将堆栈内容恢复到寄存器(R0,R4~R12,LR)
在通用存储区,数据存储的方式和堆栈区相近。R1、R2和R3三个寄存器的4种后缀指令执行前后的存储情况如图37所示。
图37数据存储示意图
3. 交换指令(1) SWP指令SWP指令的格式为:
SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]
SWP指令是数据字交换指令,用于将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。指令示例:
SWPR1,R2,[R3]; 将R3所指向的存储器中的字数据传送到R1,同时将R2中的字数据传; 送到R3所指向的存储单元
SWPEQR1,R1,[R2]; Z=1时,完成将R2所指向的存储器中的字数据与R1中的字数据交换
(2) SWPB指令SWPB指令的格式为:
SWP{条件}B 目的寄存器,源寄存器1,[源寄存器2]
SWPB指令是字节交换指令,用于将源寄存器2所指向的存储器中的字节数据传送到目的寄存器中,目的寄存器的高24位清零,同时将源寄存器1中的字节数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容。指令示例:
SWPBR1,R2,[R3]; 将R3所指向的存储器中的字节数据传送到R1,R1的高24位; 清零,同时将R2中的低8位数据传送到R3所指向的存储单元
SWPBR1,R1,[R2]; 将R2所指向的存储器中的字节数据与R1中的低8位数据交换
3.2.4ARM 数据处理类指令数据处理指令只能对寄存器的内容进行操作,不允许对存储器中的数据进行操作,也不允许指令直接使用存储器的数据或在寄存器与存储器之间传送数据。数据处理指令可分为三大类: 数据传送指令、算术逻辑运算指令和比较指令。数据传送指令用于在寄存器和存储器之间进行数据的双向传输。算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件标志位。比较指令是对指定的两个寄存器(或一个寄存器,一个立即数)进行比较,不保存运算结果,只影响CPSR中相应的条件标志位。1. 数据传送指令MOV和MVN(1) MOV指令MOV指令的格式为:
MOV{条件}{S} 目的寄存器,源操作数
MOV指令可完成在寄存器之间或寄存器与第2操作数之间进行的数据传送。其中,S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。指令示例:
MOVR4,R5; 将寄存器R5的内容传送到寄存器R4
MOVPC,R14; 将寄存器R14的内容传送到PC,常用于子程序返回
MOVNE R4,R5,LSL#2; 当Z=0时,将寄存器R5的内容逻辑左移2位后传送到R4
(2) MVN指令MVN指令的格式为:
MVN{条件}{S} 目的寄存器,源操作数
MVN指令可完成在寄存器之间或寄存器与第2操作数之间进行的数据非传送。与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中,S决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。指令示例:
MVNR0,#0; 将立即数0取反传送到寄存器R0中,完成后R0=-1
2. 算术逻辑运算指令(1) ADD指令ADD指令的格式为:
ADD{条件}{S} 目的寄存器,操作数1,操作数2
ADD指令是加法指令,用于把两个操作数相加,并将结果存放到目的寄存器中。操作数1应是一个寄存器。操作数2可以是一个寄存器,被移位的寄存器或一个立即数。指令示例:
ADDSR0,R3,R4; R0 = R3 R4,设置标志位
ADDCR0,R3,#10; R0 = R3 10
ADDR0,R2,R3,LSL#2; R0 = R2 R3×4
(2) ADC指令ADC指令的格式为:
ADC{条件}{S} 目的寄存器,操作数1,操作数2
ADC指令是带进位加法指令,用于把两个操作数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。它使用一个进位标志位,这样就可以做比32位大的数的加法,注意不要忘记设置S后缀来更改进位标志。操作数1应是一个寄存器。操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。以下指令序列实现64位二进制数的加法: R2、R1=R2、R1 R4、R3
ADDSR1,R1,R3; R1= R1 R3
ADCR2,R2,R4; R2= R2 R4 C
(3) SUB指令SUB指令的格式为:
SUB{条件}{S} 目的寄存器,操作数1,操作数2
SUB指令是减法指令,用于把操作数1减去操作数2,并将结果存放到目的寄存器中。该指令可用于有符号数或无符号数的减法运算。操作数1应是一个寄存器。操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。指令示例:
SUBS R0,R3,R4; R0 = R3-R4,设置标志位
SUBR0,R1,#0x10; R0 = R1-0x10
SUBR0,R2,R3,LSL#1; R0 = R2-(R3 << 1)
评论
还没有评论。