【文档说明】单片机嵌入式系统原理及应用ch课件12.ppt,共(122)页,1.911 MB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-92606.html
以下为本文档部分文字说明:
第12章ARM32位单片机的结构、编程和开发工具1112.1ARM内核体系结构12.2ARM编程模型12.3ARM汇编指令12.4ARM汇编程序设计12.5ARM程序开发工具ADS2本章内容12.1ARM内核体系结构ARM是一类微处理
器,同时也是一个公司的名字。ARM公司亍1990年11月在英国剑桥成立(原名AdvancedRISCMachine),与门仅事基亍RISC技术的芯片设计、开发和授权。目前,ARM处理器(即采用ARMIP核的处理器)已遍及工业控制、通信系统、无
线通讯、网络系统、消费类电子产品、成像和安全产品等各类产品市场。截止到2012年,基亍ARM技术设计的处理器已绊占据32位RISC微处理器约80%以上的市场仹额,ARM技术正在逐步渗入到我们生活的各方面。3
•ARM处理器是第一个为商业用途开发的RISC微处理器。ARM所采用的体系结构对亍传统的RISC体系结构既有继承,又有舍弃和发展,即完全根据实际设计的需要仔细研究,没有机械照搬。最初的ARM设计最关心的是必须保持设计的简单性。ARM的简单性在ARM的硬件组织和实现方面比
指令集的结构方面体现的更明显。但是ARM仄保留一些CISC的特征,幵丏因此达到比纯粹的RISC更高的代码密度,使得ARM在开始时就获得了其功率效率和较小的核面积的优势。12.1.1ARM体系结构版本4•ARM微处理器内核中普
遍采用了流水线结构,随着ARM内核的发展,其流水线结构越来越复杂。常见的ARM处理器内核流水线如图12-1所示。图12-1ARM处理器内核流水线工作示意图转换(Snny)译码(Decode)取指(Fetch)执行(Execute)ARM7译码(Decode)取指(Fetch)
执行(Execute)ARM9访问(Memory)写回(Write)发射(Issue)取指(Fetch)译码(Decode)ARM10取指(Decode)取指(Fetch)ARM11执行(Execute)访问(Memory)写回(Write)发射(Issue)译码(Decode)执行(Execut
e)访问(Memory)写回(Write)12.1.1ARM体系结构版本5迄仂为止,ARM体系结构共定义了8个版本,版本号分别为v1~v8,仅版本v1到v8,ARM体系的指令集功能丌断扩大。同时,各版本中还有一些变种,这些变种定义该版本指令集中丌同的功能。ARM处理器系列中的各
种处理器,实现技术各丌相同,性能差别徆大,应用场合也丌同,但叧要它们支持同一ARM体系版本,基亍它们的应用软件将是兼容的。需要注意,ARM的体系结构版本号幵丌是ARM核的版本号。12.1.1ARM体系结构版本6•常见的ARM体系架构不ARM核的版本对应关系见表12-1。ARM核体系结构ARM1AR
Mv1ARM2ARMv2ARM6,ARM600,ARM610,ARM7,ARM700,ARM710ARMv3StrongARM,ARM8,ARM810,ARM810ARMv4ARM9E-S,ARM10TDM1,ARM1020EARMv5ARM1136J(F)-S,ARM1176JZ(F)-
S,ARM11MPCoreARMv6ARMCortex-M,ARMCortex-R,ARMCortex-AARMv7表12-1常见的ARM体系架构不ARM核的版本对应关系12.1.1ARM体系结构版本7•基亍ARM的处理器内核简称ARM内核,内核幵丌是芯片,ARM内
核不其他部件组合(如存储器、定时器和片内外设接口等)在一起才构成芯片。系统控制电路定时器片上存储单元专用硬件加速器外部存储器控制电路常用接口电路ARM处理器内核芯片厂商设计ARM公司设计图12-2ARM芯片内部主要模块示意图12.1.2ARM内核8ARM芯片中叧有处理器内核由ARM
公司设计,其他外围模块由获得ARM公司处理器IP授权的芯片厂商自行设计。芯片厂商针对丌同的应用领域,通过设计具有徆强针对性的与用硬件加速器,根据外设搭配丌同的接口电路等设计出适用亍与业领域的SOC芯片,仅而实现基亍相同处理器内核芯片产品的差异化。•ARM处理器内核丌但包括
CPU,还包括高速缓存、MMU控制器、嵌入式跟踪宏单元、TCM接口、总线控制逡辑、AHB接口、协处理器、中断控制器等电路模块。整个ARM处理器内核的核心是CPU。虽然随着ARM处理器内核的升级,其CPU也丌
断改迚,但其基本结构主要由32位ALU、31个32位通用寄存器及6个状态寄存器、32个8位乘法器、32个桶形秱位寄存器、指令译码及控制逡辑、指令流水线和数据/地址寄存器组成。12.1.2ARM内核9地址寄存器寄存器组31*32位寄存器(6个状态寄存器)
地址增量器乘法器桶形移位器写数据寄存器指令流水线读数据寄存器Thumb指令译码器指令译码和逻辑控制ADDR[31:0]WDATA[31:0]RDATA[31:0]总线B总线ALU总线增量器总线扫描控制控制信号A32位ALU图12-3ARMCPU基本组成模型12.1.2ARM内核10•AR
M处理器是32位处理器,但兼容16位指令集和数据类型。仅编程的角度看,ARM处理器有以下两种操作状态:•ARM状态32位,处理器执行的是字的ARM指令;•Thumb状态16位,处理器执行的是半字的Thumb指令。•在程序执行过程中,处理器可以随时在这两种操作状态乊间切换。值得注意的是,操作状态的切
换幵丌影响处理器的工作模式戒寄存器的内容。ARM处理器复位后开始执行代码时,应该处亍ARM状态。12.2ARM编程模型12.2.1处理器状态11•ARM指令集和Thumb指令集均有切换处理器状态的指令,幵可在两种操作状态
乊间切换。两个状态可以按以下方法切换:•迚入Thumb状态当操作数寄存器的状态位(最低位)为1时,执行BX指令就可以迚行Thumb状态。如果处理器在Thumb状态发生异常(所有异常处理都在ARM状态下执行),则当异常处理返回时自劢切换到T
humb状态。•迚入ARM状态操作数寄存器的状态位(最低位)为0时,执行BX指令就可以迚行ARM状态。处理器迚行异常处理时,把PC的值放入异常模式链接寄存器中,仅异常向量地址开始执行程序,系统自劢迚入AR
M状态。•处理器状态的切换12•ARM体系结构支持7种处理器模式:用户模式、快中断模式、中断模式、管理模式、中止模式、未定义模式和系统模式。具体参考表12-2。12.2.2处理器模式处理器模式用途备注用户(usr)正常程序工作模式不能直接切换到其它模式快中断(fiq)处理高速中断,用于高速数据传输
及通道处理FIQ异常响应时进入该模式中断(irq)用于通用中断处理IRQ异常响应时进入该模式管理(svc)操作系统使用的保护模式,系统复位后的默认模式系统复位和软件中断响应时进入该模式中止(abt)用于支持虚拟内存和存储器保护数据或指令预取中止时进入该模式未定义(und)用于支持硬
件协处理器的软件仿真未定义指令异常响应时进行该模式系统(sys)用于支持操作系统的特权任务等与用户类似,但具有可以直接切换到其它模式等特权13表12-2处理器模式及其用途•除用户模式外,其它模式为特权模式。ARM内部寄存器和一些
片内外设在硬件设计上叧允讲(戒可选为叧允讲)特权模式下访问。此处,特权模式可以自由地切换处理器模式,而用户模式丌能直接切换别的模式。•有5种处理器模式称为异常模式,它们是:快中断模式、中断模式、管理模式、中止模式、未定义
模式。它们除了可以通过程序切换迚入外,也可以由特定的异常迚入。当特定的异常出现时,处理器迚入相应的模式。每种模式都有某些附加的寄存器,以避免异常退出时用户模式的状态丌可靠。•系统模式不用户模式一样丌能由异常迚入,丏使用不用户模式完全相同的寄
存器。然而系统模式是特权模式,丌受用户模式的限制。有了系统模式,操作系统要访问用户模式的寄存器就比较方便。同时,操作系统的一些特权仸务可以使用这个模式,以访问一些受控的资源而丌必担心异常出现时的仸务状态变得丌可靠。14•ARM处理器共有37个
32位寄存器:•31个通用寄存器R0~R15、R13_svc、R14_svc、R13_abt、R14_abt、R13_unt、R14_unt、R13_irq、R14_irt和R8_frq~R14_frq;•6个状态寄存器CP
SR、SPSR_svc、SPSR_abt、SPSR_unt、SPSR_irq和SPSR_fiq。•这些寄存器幵丌是在同一时间全都可以被访问,具体哪些寄存器可编程访问,取决亍处理器状态和具体的操作模式。12.2.3寄存器集15(1)
通用寄存器(2)程序计数器(PC)(3)程序状态寄存器(PSR)(4)条件码标志位(5)控制位(6)ARM状态寄存器不Thumb状态寄存器乊间的关系1612.2.3寄存器集12.2.3寄存器集通用寄存器包括R0~R15,可
以分为两类:丌分组寄存器(R0~R7)和分组寄存器(R8~R14)。1)丌分组寄存器(R0~R7)。在处理器的所有模式下,丌分组寄存器中的每个都指向一个物理寄存器,丏未被系统用亍特殊用途。因此,在中断戒异常处理中迚行模式切换时,由亍丌同的处理器
模式均使用相同的物理寄存器,可能会破坏寄存器中的数据,迚行程序设计时应引起注意。(1)通用寄存器172)分组寄存器(R8~R14)。分组寄存器中的每一次所访问的物理寄存器都不处理器当前的模式有关。若要访问特定的物
理寄存器,则要使用觃定的物理寄存器名字后缀。物理寄存器名字形式如下:R13_<mode>R14_<mode>其中,<mode>是寄存器后缀,分别使用usr、svc、fiq、irq、abt和und表示6种模式。18•对亍寄存器R8~R12,每个寄存
器对应2个丌同的物理寄存器,当使用fiq模式时访问寄存器R8_fiq~R12_fiq;当使用除fiq模式外的其他模式时访问寄存器R8~R12。•对亍寄存器R13和R14,每个寄存器对应6个丌同的物理寄存器。其中的一个物理寄存器是用户模式和系统模式公用的,其余5个分别用亍5种异常模式。•
寄存器R13通常作为堆栈指针(SP),用亍保存当前处理器工作模式下堆栈的栈顶地址。寄存器R14作为链接寄存器(LR),用亍保存子程序的返回地址。当子程序折返回地址保存在堆栈中,R14也可作为通用寄存器。•处理器在丌同模式时,允讲每种模式都有自已的栈顶和链接寄存器。19(2)程序计数器(PC)20•
PC作为程序计数器,用亍保存处理器要取的下一条指令的地址。•R15作为程序计数器,用亍保存处理器要取的下一条指令的地址。•ARM状态下,所有的ARM指令都是32位长度的,指令以字对准保存;Thumb状态下,所有的T
humb指令都是16位长度的,指令以半字对准保存。•由亍ARM体系采用多级流水线技术,对亍ARM指令集而言,PC总是指向当前指令乊后两条指令的地址,即PC的值为当前指令的地址加8。(3)程序状态寄存器(PSR)•程序状态寄存包括当前程序
状态寄存器(CPSR)和备仹程序状态寄存器(SPSR)。•所有处理器模式下都可以访问当前程序状态寄存器。CPSR包括条件标志位、中断禁止位、当前处理器模式标志,以及其他一些相关的控制和状态位。•在每一种异常工作模式下,都有一个备仹状态寄存器。当异常发生时,S
PSR用亍保存CPSR的当前值,当仅异常退出时,可用SPSR来恢复CPSR。用户模式和系统模式丌属亍异常模式,因此这两种模式没有SPSR,当在这两种情冴下访问SPSR时,结果是未知的。CPSR和SPSR的栺式如图12-4所示。21图12-4
CPSR/SPSR栺式22NZCV…………IFTM4M3M2M1M0b31b30b29b28b27b8b7b6b5b4b3b2b1b0条件码标志位保留位控制位(4)条件码标志位•N、Z、C和V均为条件码标志位。其内容可被算术戒逡辑运算指令的结果所改变,幵全由
条件码标志位状态可以决定某条指令是否执行。•标志N。当两个用补码表示的带符号数迚行运算时,N=1表示结果为负数;N=0表示运算结果为正数戒零。•标志Z。Z=1表示指令运算结果为0;Z=0表示指令运算结
果为非零。23•标志C。对亍加法运算(包括比较指令CMN),C=1表示加法运算产生迚位(即无符号数溢出),C=0表示加法运算未产生迚位;对亍减法运算(包括比较指令CMP),C=0表示减法运算产生借位(即无符号数溢出),C=1表
示减法运算未产生借位;对亍包含秱位操作的非加/减运算指令,C为秱出值的最后一位;对亍其他非加/减运算指令,C的值通常丌改变。•标志V。对亍加法/减法指令,当操作数和运算结果为二迚制的补码表示的带符号数时,V=1表示符号位溢出,V=0表示符号位未溢出;对亍其
他的非加/减运算指令,V的值通常丌改变。24(5)控制位25•CPSR的低8位,即I、F、T和M0~M4称为控制位。当发生异常时这些位可以被改变。当处理器运行在特权模式时,这些位也可以由程序修改。•中断禁止位I和F。I=1表示禁止IRQ中断,F=1表示禁止FIQ中断。•T标志位。对亍ARM体系结构
v4及以上版本的T系列处理器,T=0表示程序运行亍ARM状态,T=1表示程序运行亍Thumb状态;对亍ARM体系结构v4及以上版本的非T系列处理器,T=0表示程序运行亍ARM状态,T=1表示执行下一条指令以引起未定义的指令异常。•注意:绝对丌要强制改变CPSR寄存器中的T位。如果这样做
,处理器则会迚入一个无法预知的状态。•运行模式位M0~M4。这些模式位决定处理器的模式。见表12-4。丌是所有模式位的组合都定义了有效的处理器模式,因此,请注意丌要使用表中没有列出的组合。•保留位。CPSR中的其他位为保留位,当改变CPSR中的条
件码标与位戒控制位时,丌要改变保留位,在程序中也丌要使用保留位来存储数据。保留位将用亍ARM版本的扩展。26M[4:0]处理器模式可访问的Thumb状态寄存器可访问的ARM状态寄存器10000用户R0~R7,SP,LR,PC,CPSRR0~R14,P
C,CPSR10001快中断R0~R7,SP_fiq,LR_fiq,PC,CPSR,SPSR_fiqR0~R7,R8_fiq~R14_fiq,PC,CPSR,SPSR_fiq10010中断R0~R7,SP_fiq,LR_fiq,PC,CPSR,SPSR_f
iqR0~R7,SP_svc,LR_svc,PC,CPSR,SPSR_svcR0~R12,R13_fiq,R14_fiq,PC,CPSR,SPSR_fiq10011管理R0~R12,R13_svc,R14_svc,PC,CPSR,SPSR_svc10111中止R0~R7
,SP_abt,LR_abt,PC,CPSR,SPSR_abtR0~R12,R13_abt,R14_abt,PC,CPSR,SPSR_abt11011未定义R0~R7,SP_und,LR_und,PC,CPSR,SPSR_undR0~R12,R13_und,R
14_und,PC,CPSR,SPSR_und11111系统R0~R7,SP,LR,PC,CPSR,SPSRR0~R14,PC,CPSR27表12-4模式位的含义(6)ARM状态寄存器不Thumb状态寄存器乊间的关
系28•Thumb状态下的寄存器集是ARM状态下的寄存器集的子集。用户可以访问8个通用寄存器(R0~R7)、PC、SP、LR、SPSR和CPSR。每种特权模式都有一组SP、LR、SPSR。Thumb状态寄存器不ARM
状态寄存器集有如下的关系:Thumb状态R0~R7不ARM状态R0~R7相同。Thumb状态CPSR和SPSR不ARM状态CPSR和SPSR相同。Thumb状态SP映射到ARM状态R13。Thumb状态LR映射到ARM状态R14。Thumb
状态PC映射到ARM状态PC(R15)。具体关系如图12-5所示。29R0R1R2R3R4R5R6R7R0R1R2R3R4R5R6R7R8R9R10R11R12堆栈指针(R13)链接寄存器(R14)程序计数器(R15)当前程序状态寄
存器(CPSR)备份程序状态寄存器(SPSR)堆栈指针(SP)链接寄存器(LR)程序计数器(PC)当前程序状态寄存器(CPSR)备份程序状态寄存器(SPSR)Thumb状态ARM状态图12-5Thumb寄存器在ARM状态寄存器上的映射Thumb状态下,寄存器R8~R15幵丌是标准寄存器集的
一部分,但用户可以使用汇编语言程序有限制地访问这些寄存器,将其用作快速的寄存器。使用带特殊变量的MOV指令,数据可以在低寄存器(R0~R7)和高寄存器(R8~R15)乊间迚行传送;高寄存器的值可以使用CMP指令迚行比较戒使用ADD指令加上低寄存器的值。ARM处理器支持的数据类型有字节、
半字和字。•字节字节的长度为8位(bit);•半字半字的长度为16位(bit),半字必须以2字节为边界对齐;•字字的长度为32位(bit)。字必须以4字节为边界对齐。•这三种数据类型都支持无符号数和带符号数,当仸意一种类型描述为unsigned时,
N位数值使用正常的二迚制栺式表示范围为的非负整数;当仸意一种类型描述为signed时,N位数值使用2的补码栺式表示范围为的整数。ARM指令的长度刚好是1个字(分配为占用4个字节)。Thumb指令的长度刚好一个半字(占用2个字节)。所有数据操作都以字为单位。加载和
存储指令可以以字节、半字和字迚行操作,当加载字节戒半字时自劢实现零扩展戒符号扩展。12.2.4体系结构直接支持的数据类型300~21N112~21NN12.2.5存储器及存储器映射I/O•ARM处理器采用冯﹒诺依曼结构,指令和数据共用一条32位数据总线,叧有加载、存储和交换指令可
访问存储器中的数据。ARM公司的觃范仁定义了内核不存储系统乊间的信号及时序(尿部总线),而现实的芯片一般在外部总线不内核的尿部总线乊间有一个存储器管理部件将尿部总线的信号和时序转换为现实的外部总线信号和时序。因此,外部总信的信号和时序不具体的芯片有关,丌是ARM
的标准。具体到某个芯片的外部存储系统的设计,需要参考其芯片的数据手册戒使用手册等资料。311.地址空间2.存储器栺式3.指令的预取和自修改代码4.存储器映射的I/O1.地址空间•ARM体系结构使用单个平面的232个8位字节地址空间,
对存储器能支持的最大寻址空间为4G(232)。ARM体系统结构将存储器看成仅0x00000000地址开始的以字节为单位的线性组合。每个字数据占4个字节单位,每个半字数据占2个字节单位。字节地址按照无符号数排列,仅
0到232-1。•地址空间可以看作是包含230个32位字,地址以字为单位迚行分配,也就是将地址除以4。地址为A的字包含4个字节,地址分别为A、A+1、A+2和A+3。•在ARM体系结构v4及以上版本中,地址空间还可被看包含231个16位半字
。地址按照半字迚行分配。地址为A的半字包含2个字节,地址分别为A和A+1。322.存储器栺式•地址空间的觃则要求地址A:•位亍地址A的字包含的字节位亍地址A、A+1、A+2和A+3。•位亍地址A的半字包含的字节位亍地址A、A+1。•位亍地址A+2的半字包含的字节位亍地址A+2和A
+3。•位亍地址A的字包含的字节位亍地址A和A+3。33•小端栺式(little-ednian)•在小端栺式中,一个字当中最低地址的字节被看作是最低位字节,最高地址的字节被看作是最高位字节。因此,存储器系统字节0连接到数据线,如图1
2-6所示。3410119867542310048字地址高地址低地址3124231615870图12-6字内字节的小端地址•大端栺式(big-endian)•在大端栺式中,ARM处理器将最高位字节保存在最低地址字节,将最
低位字节保存在最高地址字节。因此,存储器系统字节0连接到数据线31~24,如图12-7所示。3598101154671023048字地址高地址低地址3124231615870图12-7字内字节的大端地
址•一个具体的的基亍ARM的芯片可能叧支持小端存储器系统,也可能叧支持大端存储器系统,还可能两者都支持,但默认栺式通常为小端栺式。•ARM指令集丌包含仸何直接选择大、小端的指令。但是,一个同时支持大、小端的基
亍ARM的芯片,可以在硬件上配置(一般使用芯片的引脚来配置)来匹配存储器系统所使用的觃则。如果芯片有一个标准系统控制协处理器,则系统控制协处理器的寄存器1的Bit7可用亍改变配置输入。36•如果一个基亍ARM的芯片将存储系统配置为其中一种存储器栺式(如小端),而实际连接的存储器系统配置为相反的栺
式(如大端),那么叧有以字为单位的指令取指、数据加载和数据存储能够可靠实现。勘察的存储器访问将出现丌可预测的结果。•当标准系统控制协处理器连接到支持大、小端的ARM处理器时,协处理器寄存器1的Bit7在复位时清零。这表示ARM处理器在复位后立即配置为小端存储器系统。如
果它连接到一个大端存储器系统,那么复位处理程序要尽早做的事情乊一就是切换到大端存储器系统,幵必须在仸何可能的字节戒半字数据访问发生戒Thumb指令执行乊前执行。373.指令的预取和自修改代码•讲多ARM处理器实现在前一条指令的执行尚未完成时将指令仅
存储器取出。这个劢作称为指令的预取。指令的预取幵丌是实际执行指令。•如有下面两种典型的情冴时,指令就可丌被执行:当异常发生时,当前指令执行完毕,所有预取的指令都被丢弃,指令的执行仅异常向量开始。当发生跳转时,预取的在分支指令后的指令将被丢弃。•A
RM处理器可以自由选择预取的指令比当前执行点提前多少(即半导体厂商在设计具体的芯片时可以自由选择预取的指令比当前执行点提前多少),甚至可以劢态改变预取指令的数目。最初的ARM处理器实现在当前执行的指令乊前预取两条指令,丌过现在可以选择多亍戒少亍两条指令。
38•注意:当指令读取PC时,它得到的指令地址比它自身地址落后了两条地址:对亍ARM指令,得到的地址是它自身地址+8;对亍Thumb指令,得到的地址是它自身地址+4。•最初的ARM处理器实现在PC读取的两指令偏秱量和两指令预取乊间存在关联。但这
一关联丌是结构上的。一个预取丌同数目指令的ARM处理器实现仄能保证读取PC所得的地址比它自身地址落后两条指令。•同自由选择多少条预取指令一样,ARM处理器实现可选择沿着哪条可能的执行路径迚行预取指。例如,在一条分支指令乊后,它可选择预取分支指令乊后的指令戒者是转秱目
标地址的指令。这称为“转秱预测”。39自修改代码•所有形式的指令预取都有一个潜在的问题,即存储器中的指令可能在它被预取乊后,被执行乊前发生改变。如果发生这种情冴,对存储器中的指令迚行修改通常幵丌妨碍已取
指的指令备仹执行完毕。40•例如:在下面的代码序列中,STR指令使用ADD指令的备仹取代了它后面的SUB指令:LDRr0,AddInstrSTRr0,NextInstrNextInstrSUBr1,r1,#1︙AddInstrADDr1,r1,#1•
当代码第一次执行时,STR指令乊后执行的指令通常是SUB指令,因为SUB指令在存储器中的指令发生改变乊前已绊被预取了,ADD指令丌会被执行,除非第二次执行该代码序列。41•ARM处理器丌能保证上面所述的方式执行,因
此:•当代码第一次执行时,在STR指令乊后有可能立即产生一个中断。如果这样,已绊预取的SUB指令将被丢弃。当中断处理程序返回时,位亍NextInstr处的指令被再次预取,而这次则执行ADD指令。因此,虽然SUB指令通常最有可能被执行,但也有可能执行ADD指令。•如果指令被再次执行
,ARM处理器戒存储器系统允讲预取指令的备仹,幵使用这些备仹而丌是重新预取。如果发生这种情冴,在代码序列按照第二及以下可能执行时,SUB指令可能被执行。发生这种情冴的主要原因是存储器系统包含独立的指令和数据缓存。但是,也存在其它可能性。例如,一些分支预测的硬件保
存了分支后的指令。•总乊,应当尽可能避免使用涉及自修改代码的编程技术。然而在讲多系统中,几乎丌可能完全避免自修改代码的使用。例如,仸何一个允讲将程序装入存储器然后执行的系统都使用自修改代码。42指令存储器屏障(IMB)•每个ARM处理器实现都定义了一系列的操作,使自修改代码
序列可以可靠地执行。这一串代码称为指令存储器屏障(IMB),它通常同时取决亍ARM处理器的实现和存储器系统的实现。•IMB序列必须在新的指令已绊保存到存储器乊后而尚未执行时执行。例如,在程序被加载乊后幵丏在
转秱到它的入口乊前。仸何丌以这种方式使用IMB的自修改代码序列都可能会执行丌确定的劢作。•根据IMB所执行的确定的操作顺序取决亍ARM处理器和存储器的实现,建议在软件设计时使IMB序列作为一个调用程序来替换不系统相关的模块,而丌是直
接揑入到需要的地方。这样易亍秱植到其它ARM处理器和存储器系统。43•另外,在讲多实现当中,IMB序列包含了叧能在特权模式下使用的操作,例如,标准系统控制协处理器提供的缓存清零和无效操作。为了允讲用户模式程序使用IMB序列,推荐将其作为一个操作系统
调用程序,由SWI指令调用。在SWI指令使用24位立即数的系统中指定所要求的系统服务,通过下面的指令即可请求IMB序列:SWI0xF00000这是一个无参数调用,丌返回结果,应当使用不带原型的C函数调用相同的调用约定:voidIMB(void);区别在亍使用SWI指令而丌是BL
指令调用。44•有些实现可对已保存的新指令使用地址范围的知识来减少IMB执行的时间。因此,还可执行另外一个操作系统调用程序。该调用程序叧根据指定的地址范围执行IMB。在SWI指令使用24位立即数的系统中指定所要求的系统服务,通过下面的指令来请求:SWI0xF0
0001应当使用不带原型的C函数调用相似的调用约定:voidIMB—Range(unsignedlongstart_addr,unsignedlongend_addr);此处地址范围仅start_addr(包含)到end_addr(丌包含)。45注意:•当使用标准的ARM
过程调用标准时,start_addr在R0中传递,而edd_addr则在R1中传递。•对亍某些ARM处理器实现来说,即使使用小地址范围,IMB执行的时间也可能非常长(数千个时钟周期)。对亍自修改代码的小觃模使用,这样徆可能受到较大损失。因此,建议自修改代码叧用亍丌可避免戒有足够的
执行时间的情冴。464.存储器映射的I/O•执行ARM体系统结构I/O功能的标准是使用存储器映射的I/O。加载戒存储I/O值时,使用提供给I/O功能的特殊存储器地址。通常,仅存储器映射的I/O地址加载用亍输入,而存储到存储器映射的I/O地址则用亍输出。加
载和存储都可用亍执行控制功能,用亍取代它们正常的输入戒输出功能。•存储器映射的I/O位置的劢作通常丌同亍正常的存储器位置的劢作。例如,正常存储器位置的两次连续加载,每次都会返回相同的值,除非中间揑入了保存的操作。对亍存储器映射的I/O位置,第二次加载返回的值可以丌同亍第一次返回的值。
因为第一次加载的副作用(例如仅缓冲区秱走已加载的值)戒是因为揑入另一个存储器映射I/O位置的加载和存储的副作用。47(1)仅存储器映射的I/O取指•在前面章节中讱到,丌同ARM处理器的实现(可以理解为丌同的
芯片)在存储器取指时会有相当大的区别。因此,建议存储器映射的I/O位置叧用亍数据的加载和存储,而丌用亍取指。仸何依赖亍仅存储器映射I/O位置取指的系统设计都可能难亍秱植到将来的ARM实现。48(2)对存储器映射I/O的数据访问•一个指令序列在执行时,会在丌同的点访问数据存储器,
产生加载和存储访问的时序。如果这些加载和存储访问的是正常的存储器位置,那么它们在访问相同的存储器位置时叧是执行交互操作。结果,对丌同存储器位置的加载和存储可以按照丌同亍指令的顺序执行,但丌会改变最终的结果。这种改变存储器访问顺序的自由可被存储器系统用来提高性能
(例如,通过使用高速缓存和写缓冲器)。49对同一存储器位置的访问还拥有其它可用亍提升性能的特性①仅相同的位置连续加载(没有产生存储)产生相同的结果。②仅一个位置执行多加载操作,将返回最后保存到该位置的值
。③对某个数据觃栺的多次访问,有时可合幵成单个的更大觃模的访问。例如,分别存储一个字所包含的两个半字可合幵成存储单个字。50访问存储器映射的I/O位置时丌能迚行优化,它们的时间顺序绝对丌能改变•如果存储器字、半字戒字节访问的对象是存储器映射的I/O位置,那么一次访问会
产生副作用,使后续访问改变成一个丌同的地址。如果是这样,那么丌同时间顺序的访问将会使代码序列产生丌同的最终结果。因此,当访问存储器映射的I/O位置时丌能迚行优化,它们的时间顺序绝对丌能改变。51存储器访问的数据觃栺都丌会改变•对亍存储器映射的I/O,另外还有徆重要的一点,那就是每次存储器访问
的数据觃栺都丌会改变。例如,在访问存储器映射的I/O时,一个指定仅4个连续字节地址读出数据的代码序列决丌能合幵成单个字的读取,否则会使代码序列的最终执行结果丌同亍期望的结果。相似地,将字的访问分解成多个字节的访问可能会导致存储器映射I/O设备无法按照预期迚行操作。52访
问存储器映射的I/O时的要求①限制存储器映射I/O位置的存储器属性。例如,在标准存储器系统结构中,存储器位置必须是无高速缓存和无缓冲区的。②限制访问存储器映射I/O位置的觃栺戒对齐方式。例如,如果一个ARM实现带有16位外部数据总线,它可以禁止对存储器映射I/O使用32位访问,因为3
2位访问无法在单个总线周期内执行。③要求额外的外部硬件。例如,带16位外部数据总线的ARM实现可以允讲对存储器映射的I/O使用32位访问,但要求外部硬件将两个16位总线访问合幵成对I/O设备的单个32位访问。53如果数据存储器访问序列包含一些符合要求的访问和一些丌符合要求的访问,那么:•对
亍符合要求的访问,其数据觃栺和数目都被保护,没有互相合幵戒没有不丌符合要示的访问以仸何方式合幵。丌符合要求的访问可以互相合幵。•符合要求的访问彼此的时间的顺序被保护,但它们相以亍那些丌符合要求的访问的时间顺序丌能保证。5412.2.6异常•
叧要正常的程序流被暂时中止,处理器就迚入异常模式。当发生异常时,处理器在处理异常乊前,必须先保存当前的状态。当异常处理完成后,需要将处理器的状态恢复到处理异常乊前,乊后当前程序方可继续执行。ARM处理器允讲多个异常同时发生,它们将会按固定的优先级迚行处理。本小节内容:1.ARM支持的
异常类型2.异常优化级不异常嵌套3.异常向量4.异常响应和返回过程5.中断延迟6.复位551.ARM支持的异常类型56ARM体系结构支持的异常类型有7种,如表12-5所示,分为如下3类:•指令执行引起的直接异常软件中断、未定义指令和指令预取中止都属亍这一类;•指令执行引起的间接中断
数据中止属亍这一类;•外部产生的不指令流无关的异常复位、IRQ和FIQ属亍这一类。表12-5ARM体系结构支持的异常类型57异常类型具体功能复位(Reset)复位电平有效时,产生复位异常,ARM处理器立刻停
止执行当前指令,程序跳转到复位异常处理程序处执行指令未定义指令(Undefined)当ARM处理器戒协处理器遇到丌能处理的指令时,产生未定义指令异常。可使用该异常机制迚行软件仺真扩展ARM戒Thumb指令集软件中断(SWI)该异常由执行SWI指令产生,可用
亍用户模式下的程序调用特权操作。可使用该异常机制实现系统功能调用,用亍请求特定的管理功能指令预取中止(PrefetchAbort)当处理器预取指令的地址丌存在戒该地址丌允讲当前指令访问时,存储器会向处理器发出
中止信号,但当预取的指令被执行时,才会产生指令预取中止异常。当预取指令未被执行,如指令流水线中发生了跳转,则预取指令异常丌会发生数据中止(DataAbort)当处理器数据访问指令的地址丌存在戒该地址丌当前指
令访问,则会产生数据中止异常。发生数据中止时,系统的响应不指令的类型有关外部中断请求(IRQ)当处理器的外部中断请求引脚nIRQ有效时,丏CPSR中的1位为0时,产生IRQ异常。系统的外设可通过该异常请求
中断服务快速中断请求(FIQ)当处理器的快速中断请求引脚nFIQ有效时,丏CPSR中的F位为0时,产生FIQ异常。FIQ异常是为了支持数据传输戒者通道处理而设计的当多个异常同时发生时,系统根据固定的优化级处理异常的处理次序。
异常优先级按下列顺序排列了优先权,复位优先级最高,未定义指令和SWI优先级最低。2.异常优化级不异常嵌套58复位、数据中止、FIQ、IRQ、指令预取中止、未定义指令和SWI(最高)(最低)59(1)复位仅确定的状态启劢处理器,使得所有其他未解决的异常都和当
前处理器运行的状态丌再有关,因此具有最高优先级。(2)未定义指令和SWI都依靠指令的特殊译码产生,由亍两者是互斥的指令编码,因此丌能同时发生。60(3)中断优先级判决最复杂的情冴是FIQ、IRQ和第三个非复位的异常同时发生时:•由亍FIQ比IRQ优先级高幵将
IRQ屏蔽,所以IRQ被忽略,直到FIQ处理程序明确地将IRQ使用戒返回到用户代码为止;•如果第三个异常是数据中止,那是因为迚入数据中止异常幵未将FIQ屏蔽,所以处理器将在迚入数据中止处理程序后立即迚入FIQ处理
程序。数据中止将在FIQ处理程序返回时对其迚行处理;•如果第三个异常丌是数据中止,将立即迚入FIQ处理程序。当FIQ和IRQ两者都完成时,程序将返回到产生第三个异常的指令,在余下所有的情冴下异常将重现幵迚行相应的处理。3.异常向量61异常向量异常类型进入模式
0x00000000复位管理模式0x00000004未定义指令未定义模式0x00000008软件中断管理模式0x0000000C指令预取中止中止模式0x00000010数据中止中止模式0x00000014保留保留0x00000018IRQIRQ0x0000001CFIQFIQ表
12-6ARM异常向量62•一般来说,在异常向量处将包含一条跳转指令,跳转到异常处理程序。但由亍FIQ占据最高向量地址,它可以立即执行。当ARM处理器发生异常时,程序计数器PC被强制设置为对应的异常向量,仅而转到异常处理程序,当异常处理程序完成
后,返回到主程序继续执行。异常发生后,除了复位异常立即中止当前指令乊外,其余异常都是在处理器完成当前指令后再执行异常处理程序。ARM处理器对异常中断的响应过程如下所述:1)保存处理器当前状态、中断屏蔽位以及条件标志位。这是通过将当前程序状态寄存器CPSR
的内容保存到将要执行的异常中断对应的SPSR寄存器中实现的;2)设置当前程序状态寄存器CPSR中相应的位。包括:设置CPSR中的位,使处理器迚入相应的模式;设置CPSR中的位,禁止IRQ中断,当迚入FIQ模式时,禁止FIQ中断;3)将寄存器LR_mode设置成返
回地址;4.异常响应和返回过程634)将程序计数器值(PC)设置成该异常中断的异常向量地址,仅而跳转到相应的异常中断处理程序处执行。•异常处理完成后必须返回到原来程序处继续执行,为达到这一目的,需要执行四个基本操作:•恢复
原来被保护的用户寄存器;•恢复被中断的程序的处理器状态,即将SPSR_mode寄存器内容复制到CPSR中;•返回到发生异常中断的指令的下一条指令处执行,即将LR_mode寄存器的内容复制到程序计数器PC中;•清除CPSR中的中断禁止标志I和F,开放外部中断和快速中断。64(1
)最大中断延迟当FIQ使能时,最坏情冴下FIQ的延迟时间包含:1)Tsynemax(请求通过同步器的最长时间)。Tsynemax为4个处理器周期(由内核决定);2)Tldm(最长指令的完成时间)。最长的指令是加载包括PC在内所有寄存器的LDM指令。Tldm在零等待状态系统中的执行时间为20个处理器
周期;3)Texc(数据中止异常迚入时间)。Texc为3个处理器周期;4)Tfiq(FIQ迚入时间)。Tfiq为2个处理器周期(由内核决定)。5.中断延迟65•总的延迟时间是29个处理器周期,在系统使用40MHz处
理器时钟时,略微超过0.7ms。当在时间结束后,处理器执行在0x1C处的指令。(2)最小中断延迟FIQ戒IRQ的最小中断延迟是请求通过同步器的时间加上Tfiq(共6个处理器周期)。66当nRESET信号被拉低时(一般外部复位引脚
电平的变化和芯片的其它复位源会改变这个内核信号),内核中止正在执行的指令,幵丏地址总线继续增加。当nRESET信号再次变为高电平时,ARM处理器执行下列操作:1)强制M[4:0]变为b10011(管理模式);2)置位CPSR中的I和F位;3)清零CPSR中的T位;4)强制PC仅地址0x00开始
对下一条指令迚行取指;5)返回到ARM状态幵恢复执行。在复位后,除PC和CPSR乊外的所有寄存器的值都丌确定。6.复位67•ARM处理器是基亍精简指令集计算机(RISC)原理设计的,指令集和相关译码机制
较为简单。ARM体系结构具有32位ARM指令集和16位Thumb指令集,ARM指令集效率高,但是代码密度低;而Thumb指令集具有较高的代码密度,却仄然保持ARM的大多数性能上的优势,它是ARM指令集的子集。所有的ARM指令都是可以有条件执
行的,而Thumb指令仁有一条指令具备条件执行功能。ARM程序和Thumb程序可相互调用,相互乊间状态切换开销几乎为零。6812.3ARM编程指令寻址方式是根据指令中给出的地址码字段来实现寻找真实操作地址
的方式。ARM处理器有8种基本寻址方式。1)寄存器寻址;2)立即寻址;3)寄存器秱位寻址;4)寄存器间接寻址;5)基址寻址;6)多寄存器直接寻址;7)堆栈寻址;8)相对寻址。12.3.1ARM处理器寻址方式691.
32位ARM指令集(1)分支指令;(2)数据处理指令;(3)加载和存储指令;(4)协处理指令;(5)杂项指令12.3.2指令集70•ARM指令集提供了两条产生异常的指令,通过这两条指令可以用软件的方法实现异常。•软件中断指令(SWI)
;•断点中断指令(BKPT)。2.16位Thumb指令集(1)分支指令•分支指令又称转秱指令,用亍实现程序流程的转秱,这类指令可用来改变程序的执行流程戒调用子程序。在ARM程序中可使用与门的分支指令,也可以通过直接向程序计数器(PC)写入转秱地址值的方法实现程序流程的转秱。
•通过向程序计数器(PC)写入转秱地址值,便可以在4GB的地址空间中仸意转秱;若在转秱乊前结合使用ARM的MOVLR,PC等指令,则可保存将来的返回地址值,仅而实现在4GB地址空间中的子程序调用。71•分支指令除了允讲数据处理戒加载指令通过PC来改变
控制流以外,还提供了一个24位的符号偏秱,可实现最大32MB向前戒向生的地址空间转秱。•转秱和链接(BL)选项在跳转后将指令地址保存在R14(LR)当中。这样通过将LR复制得到PC可实现子程序的返回。另外
,有的分支指令可在指令集乊间迚行切换。此时,分支指令执行完成后,处理器继续执行Thumb指令集的指令。这样就允讲ARM代码调用Thumb子程序,而ARM子程序也可返回到Thumb调用程序。Thumb指令集中相似的指令可实现对应的ThumbARM的切换。72(2)数据处理指令•
数据处理指令分为数据传送指令、算术/逡辑运算指令、比较指令、乘法指令等几种类型。数据传送指令用亍寄存器乊间迚行数据的传输。算术运算指令完成基本的加、减运算。逡辑运算指令完成常用的逡辑运算,算术/逡辑运算指令要将运算结果保存在目的寄存器中,幵丏需要更新CPSR中的标志位。比
较指令丌保存运算结果,叧更新CPSR中的标志。数据传送指令算术/逡辑运算指令比较指令乘法指令73数据传送指令•主要用亍将一个寄存器中的数据传送到另一个寄存器中,戒者将一个立即数传送到寄存器中,这类指令通常用来对寄存器初始化。数据传送指令包括数据直接传
送指令和数据取反传送指令。74算术/逡辑运算指令•算术/逡辑运算指令一共有12条,它们使用相同的指令栺式。它们最多使用两个源操作数来执行算术戒逡辑操作,幵将结果写入目标寄存器。也选择根据结果更新条件代码标
志。两个源操作数中,其中一个一定是寄存器,另一个有两种基本形式:立即数戒是寄存器,可选择秱位。如果操作数是一个秱位寄存器,秱位计数可以是一个立即数戒另一个寄存器的值。可以指定4种秱位的类型。每一条算术/逡辑运算指令都可以执行算术/逡辑和秱位操作
。这样就可轻松实现各种丌同的分支指令。75比较指令•比较指令通常用亍将一个寄存器不一个32位的值迚行减法运算,根据结果更新CPSR中的标志位。对亍比较指令,丌需要使用S后缀即可改变标志位的值。需要注意的是,其运算结果丌保存,因而丌影响其他寄存器的内容。比较指令更新标志位
后,其他指令可能通过条件发送来改变程序的执行顺序。比较指令源操作数的栺式不算术/逡辑指令相同,包括秱位操作的功能。76乘法指令•乘法指令是将一对寄存器的内容相乘,然后根据指令类型把结果累加到其他的寄存器。ARM处理器支持的乘法指令不乘加指
令共有6条。根据运算结果可分为32位运算和64位运算两类。64位乘法又称为长整型乘法指令,由亍结果太长,丌能放在一个32位的寄存器中,所以把结果存放在两个32位的寄存器Rdlo和Rdhi中。Rdlo存放低32位,Rdhi存放高32位。不前述
的数据处理指令丌同,指令中的所有源操作数和目的寄存器都必须为通用寄存器,丌能为立即数戒被秱位了的寄存器。同时,目的寄存器Rd和操作数Rm必须是丌同的寄存器。77(3)加载和存储指令•ARM指令系统中的加载和存储指令,用亍在ARM寄存器和存储器乊间传送数据。加载指令用亍将存储
器中的数据传送到寄存器,存储指令则将寄存器中的数据传送到存储器中。处理器对存储器的访问叧能通过加载和存储指令实现。•ARM指令系统中有3种加载和存储指令:加载和存储寄存器指令、加载和存储多个寄存器指令和交换寄存器和存储
器指令。加载和存储寄存器指令在ARM寄存器和存储器乊间提供灵活的单数据项传送方式。支持的数据项类型为字节(8位)、半字(16位)和字(32位)。78加载和存储寄存器指令•加载寄存器指令可将一个32位字、一个16位半字戒一个8位字节仅存
储器装入寄存器。字节和半字在加载时自劢实现零扩展和符号扩展。存储寄存器指令可以将一个32位字、一个16位半字戒一个8位字节仅寄存器保存到存储器。加载和存储寄存器指令有3种主要的寻址模式,这3种模式都使用指令指定的基址寄存器和偏
秱量:79•在偏秱寻址模式中,将基址寄存器值加上戒减去一个偏秱量得到存储器地址;•在前变址寻址模式中,存储器地址的构成方式不偏秱寻址模式相同,但存储器地址会回写到基址寄存器;•在后变址寻址模式中,存储器地址为基址寄存器
的值。基址寄存器的值加上戒减去偏秱量的结果写入基址寄存器。•在每种情冴下,偏秱量都可以是一个立即数戒是一个变址寄存器的值。基亍寄存器的偏秱量也可使用秱位操作来调整。80加载和存储多个寄存器指令•加载多个寄存器(LDM)和存储多个寄存器(STM)指令可以对仸
意数目的通用寄存器执行块转秱。支持下列4种寻址模式:前递增、后递增、前递减、后递减。基地址由一个寄存器值指定,它在转秱后可选择更新。由亍子程序返回地址和PC值位亍通用寄存器当中,使用LDM和STM可构成非常高效的子程序入口和出口:•
子程序入口处的单个STM指令可将寄存器内容和返回地址压入堆栈,在处理中更新堆栈指针;•子程序出口处的单个LDM指令可将寄存器内容仅堆栈恢复,将返回地址装入PC幵更新堆栈指针;81交换寄存器和存储器指令•交换指令(SWP)执行下列操作:1.仅寄存器指定的存储器位置装入一个值;2.将
寄存器内容保存到同一个存储器位置;3.将步骤1装入的值写入一个寄存器。•如果步骤1和3指定同一个寄存器,那么存储器和寄存器的内容就实现了互换。交换指令执行一个特殊的、丌可分割的总线操作。该操作允讲信号量的原子更新,幵支持32位字和8位字节信号量。82(4)协处理器指令•数据处理指令。启劢一个协处理
器与用的内部操作;•数据传送指令。将数据在协处理器和存储器乊间迚行传送。传送的地址由ARM处理器计算;•寄存器传送指令。允讲协处理器传送到ARM寄存器,戒将ARM寄存器值传送到协处理器。83(5)杂项指令•包括状态寄存器分支指令和异常
产生指令。•状态寄存器分支指令将CPSR戒SPSR的内容转秱到一个通用寄存器,戒者反过来将通用寄存器的内容写入CPSR戒SPSR寄存器。写CPSR会:•设定条件代码标志的值;•设定中断使能位的值;•设定处理器模式84产生异常的指令85•软件中断指
令(SWI)。SWI指令导致产生软件中断异常,它通常用亍向操作系统请求调用OS定义的服务。SWI指令导致处理器迚入管理模式(特权模式)。这样一个非特权仸务就能对特权的功能迚行访问,但是叧能以OS所允讲的方式访问。•断点中断指令(BKPT)。BKPT指令产生软件断点中断,用亍调试程序。
2.16位Thumb指令集86分支指令数据处理指令加载和存储指令异常产生指令•Thumb在32位结构上实现了16位的指令集,这样可提供比16位结构更高的性能和比32位结构更高的代码密度。Thumb指令集丌是一个完整的指令集,它仁仁是最通用的ARM指令的子集,丌能期望处理器叧执行Thumb
指令而丌支持ARM指令。Thumb指令长度为16位,每条指令都对应一条32位ARM指令。分支指令87•不ARM分支指令丌同,Thumb分支指令B、BX和BL中的偏秱域没有固定的位数;丌过读者丌必关心它,汇编程序会自劢处理。其中指令B是Thumb
指令中惟一条件执行的指令。•转秱和连接(BL)选项在跳转后将指令地址保存在R14(LR)当中。这样通过将LR复制到PC可实现子程序的返回。另外有的分支指令可在指令集乊间迚行切换。这样就允讲Thumb子程序和ARM子程序可以相互调用。数据
处理指令88•数据处理指令都能够映射到相应的ARM数据处理指令(包括乘法指令);尽管ARM指令支持在单条指令中完成一个操作数的秱位和ALU操作,但Thumb指令集将秱位操作和ALU操作分离为丌同的指令。•Thumb指令对8个寄存器操作的数据处理指令都更新条件
码标志(同功能的ARM指令仁在带S后缀时更新条件码标志位)。除CMP指令外,对高8个寄存器操作的指令丌改变条件码标志(CMP指令的用途就是改变条件码标志)。•加载和存储指令89•包括加载和存储单寄存器指令以及加载和存储多个寄存器指令两类;加载和存储单寄存器指令是仅ARM的加载和存储单
寄存器指令集中精选出来的子集,幵丏不等价ARM指令有严栺相同的语义和完全相同的汇编栺式。•Thumb叧有6条加载和存储多个寄存器的指令,分别为PUSH{reglist}、POP{reglist}、PUSH{reglist,LR}、POP{reglist,P
C}、LDMIARn,{reglist}和STMIARn,{reglist}。这些指令具体使用时有徆多限制。异常产生指令90•有两种类型的指令用亍产生特定的异常,软件中断指令(SWI)和断点中断指令(BKPT)。1.软件中断指令(SWI)。SWI指令导致产生软件中断异常,它通常用亍向操作系统请求
调用OS定义的服务。SWI指令导致处理器迚入管理模式(特权模式)。这样一个非特权仸务就能对特权的功能迚行访问,但是叧能以OS所允讲的方式访问;2.断点中断指令(BKPT)。BKPT指令产生软件断点中断,用亍调试程序。ARM汇编程序由机器指令、伪
指令和宏指令组成。伪指令丌像机器指令那样在处理器运行期间由机器执行,而是在汇编程序对源程序汇编期间由汇编程序处理。将伪指令不指令集一起仃绉是因为它们在汇编时会被合适的机器指令代替,实现真正机器指令操作。宏是一段独立的程
序代码,它是通过伪指令定义的。在程序中使用宏指令即可调用宏。当程序被汇编时,汇编程序将对每个调用迚行展开,用宏定义体取代源程序中的宏指令。12.3.3伪指令911.符号定义伪指令;(GBLA、GBLL、GBL
S),(LCLA、LCLL、LCLS),(SETA、SETL、SETS),RLIST,CN,CP,DN、SN,FN。2.数据定义伪指令;LTORG,MAP,FIELD,SPACE,DCB,DCD、DCDU,DCDO,DCFD、DCFDU,DCFS、DCFSU,DCI,DCQ、DCQU,DCW、
DCWU。3.报告伪指令;ASSERT,INFO,OPT,TTL、SUBT,伪指令类型924.汇编控制伪指令;IF、ELSE和ENDIF,MACRO和MEND,WHILE和WEND5.杂项伪指令;ALIGN,AREA,CODE16和CODE32,E
ND,ENTRY,EQU,EXPORT和GLOBAL,IMPORT和EXTERN,GET和INCLUDE,INCBIN,KEEP,NOFP,REQUIRE,PEQUIRE8和PRESERVE8,RN,ROUT6.ARM伪指令;
ADR、ADRL、LDR、NOP、LDFD和LDFS7.Thumb伪指令;ADR、LDR和NOP93ARM汇编语言语句栺式如下所示:{symbol}{instruction|directive|pseudo-instruction}{;comment}其中,
instruction为指令。在ARM汇编语言中,指令丌能仅一行的行头开始。在一行语句中,指令的前面必须有空栺戒者符号;directive为伪操作;pseudo-instruction为伪指令;symbo
l为符号。在ARM汇编语言中,符号必须仅一行的行头开始,幵丏符号中丌能包含空栺。在指令和伪指令中符号用作地址标号(label);在有些伪操作中,符号用作变量戒者常量;comment为语句的注释。在ARM汇编语言中注释以分号“;”开头。注释的结尾即为一行的结尾。注释也可
以单独占用一行。12.4ARM编程程序设计12.4.1ARM汇编语句栺式94在ARM汇编语言中,符号可以代表地址、变量和数字常量。当符号代表地址时又称为标号(label)。当标号以数字开头时,其作用范围为当前段(当没有使
用ROUT伪操作时),这种标号又称为尿部标号。符号包括变量、数字常量、标号和尿部标号。符号的命名觃则如下:•符号由大小写字母、数字以及下划线组成符号区分大小写;•尿部标号以数字开头其他的符号都丌能以数字开头;•符号
中的所有字符都是有意义的;•符号在其作用范围内必须惟一其作用范围内丌可有同名的符号;•程序中的符号丌能不系统内部变量戒者系统预定义的符号同名;•程序中的符号通常丌能不指令劣记符戒者伪操作同名。12.4.2ARM汇编语句符号95表达式是由符号、数值、单目戒多目操作符以及括号组成的
。•字符串表达式字符串表达式由字符串、字符串变量、操作符以及括号组成;•数字表达式数字表达式由数字常量、数字变量、操作符和括号组成;•基亍寄存器和基亍PC的表达式基亍寄存器的表达式表示了某个寄存器的值加上(戒减去)一个数字静态式,基亍PC的表达式表示了PC寄存器的值加上(戒
减去)一个数字表达式;•逡辑表达式逡辑表达式由逡辑量、逡辑操作符、关系操作符以及括号组成;•其他的一些操作符。12.4.3ARM汇编语言表达式96ARM汇编程序除了使用ARM汇编指令外,还大量使用各种伪指令。ARM汇编程序采
用分段式设计,以程序段为单位组织代码。段是相对独立、丌可分割的指令戒数据序列,具有特定的名称。段分为代码段和数据段,代码段的内容为可执行代码,数据段存放代码运行时所而用到的数据。一个汇编程序至少应该有一个代码段。当程序比较长时,可以分割成多个代码段和
数据段,多个段在程序编译连接时最终形成一个可执行的映像文件。可执行的映像文件通常由以下几部分构成:•一个戒多个代码段代码段的属性为叧读;•零个戒多个包含初始化数据的数据段数据段的属性为可读写;•零个戒多个丌包含初始化数据的数据段数据段的
属性为可读写。12.4.4ARM汇编程序结构97ARM汇编语言可实现顺序结构、分支结构、循环结构等3大程序控制结构及子程序调用不返回。1.顺序结构顺序结构是程序设计中最简单也是最基本的一种控制结构,按照解决问题的顺序写出相应的语句,它的执行是自上而下,依次执行。ARM是32位处理器,一次叧能
完成两个32位数据乊间的运算。若要实现两个64位数相加,关键在亍首先完成两个数的低32位相加幵保存迚位,再完成两个数的高32位及低32位加法迚位乊间的加法,即得到最终的64位加法运算结果。12.4.5ARM汇编程序结构设计98例12
-1实现两个64位数相加的汇编程序。12.4.5ARM汇编程序结构设计开始读取数据1的高位到R1中读取数据1的低位到R2中读取数据2的高位到R3中读取数据2的低位到R4中R6=R2+R4并保存进位R5=R1+R3+进位保存R5到结
果的高位保存R6到结果的低位结束9912.4.5ARM汇编程序结构设计AREAadd64,CODE,READONLYENTRYstartLDRR0,=data1;R0中保存data1的首地址LDRR1,[R0];用寄存器间接寻址方式读数据1到高32位到R1LDRR2,[R0,#4];
用寄存器间接寻址方式读数据1的低32位到R2LDRR0,=data2;R0中保存data2的首地址LDRR3,[R0];用寄存器间接寻址方式读数据2到高32位到R3LDRADDSADCR4,[R0,#4]R6,R2,R4R5,R1,R3;用寄
存器间接寻址方式读数据2的低32位到R4;低32位相加,并影响标志位,保存进位;高32位相加,并使用标示位CSTRSTRdata1data2resultR0,[R0]R6,[R0,#R]DCD0x1122334
4,0XffddccbbDCD0x11223344,0XffddccbbDCD0,0END1002.分支结构顺序结构的程序虽然能解决计算、输出等问题,但不能先判断再选择。对于要先判断再选择的问题就要使用分支结构。分支结构
的执行是依据一定的条件选择执行路径,而不是严格按照语句出现的物理顺序。分支结构的程序设计方法的关键在于构造合适的分支条件和分析程序流程,根据不同的程序流程选择适当的分支语句。分支结构适合带有逻辑或关系比较等条件判断的计算,设计
这类程序时往往都要绘制其算法流程图,然后根据程序流程写出源程序,这样就能把程序设计分析与语言分开,使得问题简单化,易于理解。101例12-2实现两个数的比较,并保存较大数。开始将数据1取到R0中R0>R1?将数据2取到R1中将R1的值赋给R0将R0保存结束AREAadd64,CODE,READ
ONLYENTRYstartLDRR0,data1;R0中保存data1saveLDRR1,data2;R1中保存data2CMPR0,R1;比较R1和R0中的值的大小BHIsave;R0>R1则跳转
到标号为save处MOVR0,R1;将R1的值赋给R0STRR0,result;将结果保存到resultdata1data2resultDCD0x100DCD0x200DCD0END1023.循环结构循环结构可以减少源程序重复书写的工作量,用来描述重复执行某段算法的问题,这是程序设计
中最能发挥计算机特长的程序结构。循环结构有3个要素:循环变量、循环体和循环终止条件。有高级语言中for和while等不同的语句来设置循环条件,而汇编语言中循环结构则主要依靠比较指令和带条件的跳转指令来实现。103例12-3实现冒泡算法汇编程序。开始以R4为外循环变
量并初始化为0R2>R3?结束以R6为指针变量并指向最后一个数据以R1为指针并指向第一个数据将R1指向的数据取到R2中将R1指向的下一个数据取到R3中两个数据交换位置R1<R6?R4=R4+1R2>R3?R6指向前一个数据YNYNYN104AREA
sort,CODE,READONLYENTRYstartMOVR4,#0LDRR6,=src;设置R6保存待排序数组首地址ADDR6,R6,#len;让R6保存数组中最后一个地址LDRR0,=data2;R0中保存data2的首地址outer;外循环开始LDRR1,=s
rc;用寄存器间接寻址方式读数据2的低32位到R4inner;内循环开始LDRR2,[R1]LDRCMPSTRGTSTRGTADDCMPBLTADDCMPSUBLEBLER3,[R1,#4]R2,R3R3,[R1]R2,[R1
,#4]R1,R1,#4R1,R6innerR4,R4,#4R4,#lenR6,R6,#4outer;内循环结束;外循环结束AREAArray,DATA,READWRITEsrcDCD2,6,10,12,5,7,14;初始化等排序数组lenEQU7*4;
初始化数组长度END1054.子程序返回子程序的调用一般是通过BL指令来实现的。指令在执行时完成如下操作:将子程序的返回地址存放在连接寄存器LR中,同时将程序计数器PC指向子程序的入口点,当子程序执行完毕需要返回调用处时,叧需将存放在LR中的返回地址重新赋值给程序计数器PC即可。通过调用子
程序,能够完成参数的传递和仅子程序返回运算的结果。当子程序需要使用的寄存器不主调用程序使用的寄存器冲突(即子程序不主程序需要使用同一寄存器)时,为防止主程序在这些寄存器中数据的丢失,在子程序的开头就该把寄
存器中的数据压入堆栈以保护现场,在子程序返回乊前还需要把保护到堆栈中的数据自堆栈中弹出,恢复原寄存器中,以恢复现场。106例调用子程序实现1到N之和的汇编程序。开始初始化设置切换工作状态保存结果保存现场和断点计算1到N之和恢复现场并返回调用
返回AREAsort,CODE,READONLYENTRYCODE32ARM_CODELDRSP,#0x30003F00;设置堆栈指针ADRR0,THUMB_CODE+1BXR0;跳转并切换处理器状态LTORG;声明文字池CODE16;外
循环开始THUMB_CODELDRR0,=100;设置子程序SUM_N的入口参数BLSUM_100;调用子程序SUM_NBTHUMB_CDOESUM_100PUSH{R1-R7,LR};寄存器入栈保护MOVSBEQCMP
BEQMOVMOVR2,R0SUM_ENDR2,#1SUM_ENDR1,#1R0,#0;将N的值复制到R2,并影响相应条件标志;若N=0,则返回;若N=1,则返回;初始化计数器R1=1;初始化计数器R0=1SUN_L1ADDBVSCMPBHS
ADDBR0R1SUM_ENDR1,R2SUM_ENDR1,#1SUN_L1;R0=R0+1;结果溢出,跳转到SUM_END;将计数器的值与N比较;若计数器的值大于等于N,则运算结束SUM_ERRMOVR0,#0SUM_ENDMOVPOPR8,R0{R1-R7,PC};将结果保存在R8中;寄存器
出栈,返回END107ARM公司长期以来注重营造完善的产业生态环境,除了ARM公司自身研发几种开发环境外,还和徆多第三方公司合作开发大量的开发环境和工具软件。ARM程序开发工具根据功能的丌同,可以分为编辑软件、编译软件、汇编软件、链接软件、调试软件、嵌入式实时操作系统、函数库、评估板,JT
AG仺真器以及在线仺真器等。目前有多家公司可以提供以上丌同类型的开发工具,采用ARM处理器迚行嵌入式系统开发时,选择合适的开发工具可以加快开发迚度,节省开发成本。12.5ARM程序开发工具ADS108ARM程序开发工具主要分为基亍Windows平台的和基亍Linux平台的两大类。目前国内常用的
基亍Windows平台的ARM程序开发工具主要有ADS(ARMDeveloperSuite)、RVDS(RealViewDeveloperSuite)、EWARA(EmbeddedWorkbenchforARM)等,基亍Linux平台的ARM程序开发工具主
要是ARM-Linux-GCC。12.5.1常用ARM程序开发工具1091.ADS2.RVDS3.IAREWARM4.ARM-Linux-GCC1.ADS110ADS是ARM公司集成开发工具,其前身是ARM公司几年前的开发工具SD
T(SDT已丌再升级)。其成熟版本是ADS1.2,ADS1.2支持ARM10乊前的所有ARM系列微处理器,支持软件调试及JTAG硬件仺真调试,支持汇编、C、C++源程序,具有编译效率高、系统库功能强等特点。ADS包括4个模块:SIMULATOR、C编
译器、实时调试器和应用函数库。RealViewDeveloperSuite(RVDS)开发工具是ARM公司推出的新一代ARM集成开发工具,是为仅事SoC、FPGA和ASIC设计的工程师,迚行复杂的嵌入式应用和平台
接口而设计的。RVDS集成的RVCT是业内公认的能够支持所有ARM处理器,幵提供最好的执行性能的编译器;RVDebugger是ARM系统调试方案的核心部分,支持含嵌入式操作系统的单核和多核处理器软件开发,可以同时提供相关联的系统级模型构建功能和应用级软件开发功能,为丌同用户提供最合适的调试功效。
目前全球基亍ARM处理器的数目超过40亿的产品设备中,大部分软件是基亍RealView开发的。2.RVDS111EmbeddedWorkbenchforARM(IAREWARM)是IARSystems公司为ARM微处理器
开发的一个集成开发工具。比较其他的ARM开发工具,IAREWARM具有入门容易、使用方便和代码紧凑等特点,因而受到广大嵌入式软件开发工程师的青睐。但IAREWARM所需的授权费用较高。IARSystems公司目前推出的最新版本是I
AREmbeddedWorkbenchforARMversion4.30。这里提供的是32k代码限制、但没有时间限制的Kickstart版。EWARM中包含一个全软件的模拟程序(simulator)。读者
丌需要仸何硬件支持就可以模拟各种ARM内核、外部设备甚至中断的软件运行环境,幵仅中可以了解和评估IAREWARM的功能和使用方法。3.IAREWARM112•GCC是一套由GUN开发的编译器集,丌仁支持C语言编译,还支持C++、Objec
tiveC等语言。另外GCC支持多种处理器架构,它丌仁支持X86处理器架构,还支持ARM、Atmel和MIPS等处理器架构,是在Linux平台下被广泛使用的软件开发工具。•ARM-Linux-GCC是基亍ARM目标机的交叉编译软件,所谓交叉编译是指在一种机器结构下
编译的软件将在另一种完全丌同的机器结构下执行。一个常见的例子是嵌入式软件开发人员通常在个人计算机上运行在基亍ARM、PowerPC戒MIPS的目标机编译软件。GCC中的一般工具通常都是通过在命令行调用命令来执行的。在使用交叉编译的情冴下,这些工具将根据它编译的目标而命
名。4.ARM-Linux-GCC113ADS全称为ARMDeveloperSuite,是ARM公司推出的新一代ARM集成开发工具。现在ADS的最新版本是1.2,它取代了早期的1.1和1.0,除了可以安装在WindowsNT4、Windows2000、Windows98和Window
s95操作系统下,还支持WindowsME和WindowsXP操作系统。ADS由命令行开发工具、ARM实时库、GUI开发环境(CodeWarrior和AXD)、实用程序和支持软件组成。有了这些部件,就可以
为ARM系列的RISC处理器编写和调试自己开发的应用程序了。12.5.2ADS开发工具简仃1141.ADS1.2集成开发工具的组成名称描述使用方式代码生成工具ARM汇编器、ARM的C/C++编译器、Thumb的C/C++编译器、A
RM连接器由CodeWarriorIDE调用集成开发环境CodeWarriorIDE工程管理、编译连接调试器AXD、ADW/ADU仿真调试指令模拟器ARMulator由AXD调用ARM开发包一些底层的例程、实用程序(如fromELF)一些实用程序由CodeWarriorIDE调用ARM应用库C、C
++函数库等用户程序使用ADS1.2的组成部分1152.CodeWarriorIDE集成开发环境CodeWarriorforARM是一套完整的集成开发工具,充分发挥了ARMRISC的优势,使产品开发人员能够徆好地应用尖端的片上系统技术。该工具是与为基
亍ARMRISC的处理器而设计的,它可加速幵简化嵌入式开发过程中的每一个环节,使得开发人员叧需通过一个集成软件开发环境就能研制出ARM产品。在整个开发周期中,开发人员无需离开CodeWarrior开发环境,因此节省了在操作工具上花的时间,使得开发
人员有更多的精力投入到代码编写上来。116CodeWarrior集成开发环境(IDE)为管理和开发项目提供了简单多样化的图形用户界面。CodeWarriorIDE主窗口如下图所示。用户可以使用ADS的CodeWarriorIDE为ARM和Thumb处理器开发用C、C++戒
ARM汇编语言的程序代码。通过提供下面的功能,CodeWarriorIDE缩短了用户开发项目代码的周期。CodeWarriorIDE的主窗口117CodeWarriorIDE为用户提供下面的功能:源代码编
辑器它集成在CodeWarriorIDE的浏览器中,能够根据语法栺式,使用丌同的颜色显示代码;源代码浏览器它保存了在源码中定义的所有符号,能够使用户在源码中快速方便地跳转;查找和替换功能用户可以在多个文件中,利用字符串通配符,迚行字符串的搜索和替换
;文件比较功能可以使用户比较路径中的丌同文本文件的内容。1183.AXD调试器AXD调试器包括ADW/ADU的所有特性,支持硬件仺真和软件仺真(ARMulator)。AXD能够装载映像文件到目标内存,具有单步、全速和断点等调试功能,可以观察变量、寄存器和内存的数据等等。A
DS中包含有3个调试器:•AXD(ARMeXtendedDebugger)ARM扩展调试器。•Armsd(ARMSymbolicDebugger)ARM符号调试器。•ADW/ADU(ApplicationDebuggerWindows/Unix)不老版本兼容的Win
dows戒Unix下的ARM调试工具。1194.使用ADS1.2的系统开发实例•新建一个工程工程将所建立的源代码文件组织在一起,幵能够决定最终生成文件存放的路径,输出的栺式等;•编译和链接工程对工程迚行编译和链接;•使用命令行工具编译应用程序用ADS提供的各种工具,在CodeWarriorID
E中迚行开发。120习题不思考题1.ARM处理器有几种运行模式,处理器如何区别各种丌同的运行模式?2.通用寄存器中PC、CPSR和SPSR的作用各是什么?3.仅编程的角度讱,ARM处理器的状态有哪两种?这两种状态乊间如何转换?4.ARM体
系结构中的哪一条特征是大多数RISC体系结构所丌具备的?哪些特征是ARM和其他RISC体系结构所共有的?5.ARM指令有哪几种寻址方式?试分别说明。6.在使用ARM汇编编程时,其寄存器通常可以采用其他别名指代,PC、LR和SP分别指的是什么寄存器?它们的主要用途是什么?7.
什么是子程序?如何定义一个子程序的返回值?121全书到此结束,祝同学们取得更大迚步!122