1.1 ARM简介 1.1.1 ARM公司简介 ARM是Advanced RISC Machines的缩写,它是一家微处理器行业的知名企业,该企业设计了大量高性能、廉价、耗能低的RISC (精简指令集)处理器。公司的特点是只设计芯片,而不生产。它将技术授权给世界上许多著名的半导体、软件和OEM厂商,并提供服务。
ARM(Advanced RISC Machines)有3种含义: 【1】一个公司的名称 【2】一类微处理器的通称 【3】一种技术的名称
1.1.2 ARM微处理器的特点 【1】体积小、低功耗、低成本、高性能; 【2】支持Thumb(16位)/ARM(32位)双指令集,能很好的兼容8位/16位器件; 【3】大量使用寄存器,指令执行速度更快; 【4】大多数数据操作都在寄存器中完成; 【5】寻址方式灵活简单,执行效率高; 【6】指令长度固定。
1.1.3 ARM微处理器系列 ARM处理器的产品系列非常广,包括ARM7、ARM9、ARM9E、ARM10E、ARM11和Cortex等。以及其它厂商基于ARM体系结构的处理器,除了具有ARM体系结构的共同特点以外,每一系列提供一套特定的性能来满足设计者对功耗、性能、体积的需求。 表 1 ARM 系列 基于ARMv7版本的ARM Cortex系列产品由A、R、M三个系列组成,具体分类延续了一直以来ARM面向具体应用设计CPU的思路。 其中: A应用处理器(Application Processor )系列 R实时控制处理(Real Time Control )系列 M微控制器(Micro Controller )系列 CortexTM-R4处理器简介 该处理器是首款基于ARMv7架构的高级嵌入式处理器,其主要目标为产量巨大的高级嵌入式应用系统,如硬盘,喷墨式打印机,以及汽车安全系统等等。 CortexTM-R4F处理器简介 该处理器在CortexTM-R4处理器的基础上加入了代码错误校正(ECC)技术,浮点运算单元(FPU)以及DMA综合配置的能力,增强了处理器在存储器保护单元、缓存、紧密耦合存储器、DMA访问以及调试方面的能力。 CortexTM-A8处理器简介 该处理器是ARM公司所开发的基于ARMv7架构的首款应用级处理器,其特色是运用了可增加代码密度和加强性能的技术、可支持多媒体以及信号处理能力的NEONTM技术、以及能够支持Java和其他文字代码语言的提前即时编译的Jazelle@RTC技术。众多先进的技术使其适用于家电以及电子行业等各种高端的应用领域。 CortexTM-M3处理器简介 Cortex-M3处理器是一个低功耗的处理器,具有门数少,中断延迟小,调试容易等特点。它是为功耗和价格敏感的应用领域而专门设计的、具有较高性能的处理器,应用范围可从低端微控制器到复杂SoC。
1.1.4 RISC设计思想与CISC比较: a:设计重点不同,RISC重点在于通过软件的灵活降低硬件执行指令的复杂度,即使得编译器更高的复杂性; b:指令集,RISC减少了指令种类,操作也简单,基本是一个周期执行一条指令,每一条指令长度是固定,而CISC指令长度不固定,执行也需要多个周期; c:寄存器,RISC拥有更多寄存器,都可以存放数据或地址,而CISC都是用于特定目的的专用寄存器; d:load-store结构,即处理器只处理寄存器中的数据,独立的load-store指令完成数据在寄存器和外部存储器之间的传送,即数据处理与存储器访问分开,而CISC能够直接处理存取器中的数据; 注:ARM指令集属于RISC指令集,但与单纯的RISC有以下几方面不同 大部分ARM指令是单周期完成的,但也有不是的,如多寄存器的load-store指令的执行周期是不确定的,具体由被传送的寄存器个数决定; 内嵌桶型移位寄存器; Thumb 16位指令集; 条件执行; 增强指令,如添加了强大的数字信号处理器(DSP)指令,以支持16×16位乘法操作及饱和操作;
1.2数据类型 1.2.1 ARM 的基本数据类型 ARM采用的是32位地址线/数据线,支持如下数据类型: 字节(byte) 8bits 半字(Half word) 16bits,半字必须对齐2字节边界 字(Word) 32bits,字必须对齐4字节边界 双字(Doubleword)64bits,字必须对齐8字节边界。
1.2.2大小端 ARM处理器可以将存储器中的字以下列格式存储: 大端格式(Big-endian):字数据的高字节存储在低地址中,而低字节存储在高地址中; 小端格式(Little-endian):与小端对齐相反,字数据的高字节存储在高地址中,低字节存储在低地址中。
1.3 Cortex-A8内核的工作模式 ARM有8个工作模式: 表2 处理器模式
1.4 寄存器组织 1.4.1综述 ARM Cortex-A8处理器内部有40个32位长度的寄存器: 32个通用寄存器; 7个状态寄存器:1个CPSR ,6个SPSR; 1个PC程序计数器。 在不同的工作模式和处理器状态下,程序员可以访问的寄存器也不尽相同。 表3 R0 — R12:通用寄存器。当C和汇编互相调用时,R0 — R3用来传递函数参数; R13:用于各种模式下的堆栈寄存器(SP) R14:用来保存程序返回地址的链接寄存器(LR) R15:程序计数器(PC) 除了User和System模式外,各种模式都有自己独立的R13和R14
1.4.2程序状态寄存器
图2程序状态寄存器1.标志位
N、Z、C、V均为条件码标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。 表4
2.Q标志位 在ARMv5以前的版本Q标志位没有意义,属于带扩展的位。在ARMv5以后的版本Q位用于判断是否发生了溢出。
3.控制位 CPSR的低8位统称为控制位。当发生异常时,这些位也发生了相应的变化。另外,在特权模式下,也可以通过软件编程的方式来改变这些位的值。 中断禁止位。 I=1,IQR被禁止, F=1,FIQ被禁止。 状态控制位。 T=0是ARM状态, T=1是Thumb状态。 模式控制位 M[4:0]为模式控制位, 表5 模式控制位
1.4.3 程序计数器(PC) 冯 ·诺伊曼计算机体系结构的主要内容之一就是“程序预存储,计算机自动执行”!处理器要执行的程序(指令序列)都是以二进制代码序列方式预存储在计算机的存储器中,处理器将这些代码逐条地取到处理器中再译码、执行,以完成整个程序的执行。为了保证程序能够连续地执行下去,CPU必须具有某些手段来确定下一条取指指令的地址。程序计数器(PC )正是起到这种作用,所以通常又称之为‘指令计数器’。CPU总是按照PC的指向对指令序列进行取指、译码和执行,也就是说,最终是PC 决定了程序运行流向。故而,程序计数器(PC )属于特别功能寄存器范畴,不能自由地用于存储其他运算数据。 在程序开始执行前,将程序指令序列的起始地址,即程序的第一条指令所在的内存单元地址送入PC,CPU 按照 PC的指示从内存读取第一条指令(取指)。当执行指令时,CPU自动地修改PC 的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数(指令字节数),使 PC总是指向下一条将要取指的指令地址。由于大多数指令都是按顺序来执行的,所以修改PC 的过程通常只是简单的对PC 加“指令字节数”。 当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的目 标地址。处理器总是按照PC 指向取指、译码、执行,以此实现了程序转移。 ARM 处理器中使用R15 作为PC,它总是指向取指单元,并且ARM 处理器中只有一个PC 寄存器,被各模式共用。R15 有32 位宽度(下述标记为R15[31:0],表示R15 的‘第31位’到‘第0位’),ARM 处理器可以直接寻址4GB 的地址空间(2^32 = 4G )。 (解释什么是字对齐什么是半字对齐)存储器是计算机中用于记忆数据信息的电子装置,它通过记忆“高/低”电平记忆“1/0”能记忆 1 位“1/0”数据的电子单元,称之为存储元,计算机中的存储器通常将每8 个这样的存储元组成一个单元,称之为字节,字节是处理器访问存储器的最小单位。ARM 处理器对存储器空间的访问分辨率以字节为最小单位;ARM 处理器还支持 16bit 数据(2 字节)的存储器访问和 32bit数据(4 子节)的存储器访问。在ARM 中将32 位的数据称之为‘字’,将 16 位的数据称之为‘半字’。 ARM 处理器在对于“字”/ “半字”数据进行访问时,对数据的存储格式是有要求的。要求被访问的“半字”必须存放在存储器紧邻的两个字节单元,并且首字节地址必须能被2整除,这样存储的 16bit 数据称为 ‘半字对齐’存储数据,16bit 数据这样的存储方式称为 ‘半字对齐’存储。类似的,ARM 处理器在进“字”数据访问时,要求被访问的“字”必须 存放在存储器紧邻的4 个字节单元,并且首字节地址必须能被4 整除,这样存储的32bit 数 据称为‘字对齐’存储数据,32bit 数据这样的存储方式称为‘字对齐’存储。 能被2 整除数据的二进制表示,其最低位一定是‘0’;能被4 整除数据的二进制表示,其最低两位一定是‘00’。ARM 体系要求32 位长的ARM 指令在存储器中必须字对齐存储,16 位长的 Thumb 指令必须半字对齐存储。因此,在ARM 状态下,R15 的值总是能被4 整除,也就是R15 寄存器的最低2 位总是 0;Thumb 状态下,R15 的值总是能被2 整除,也就是R15 寄存器的最低位总是0。
1.5 流水线 三级流水线 取指:将指令从存储器中取出,放入指令Cache中。 译码:由译码逻辑单元完成,是将在上一步指令Cache中的指令进行解释,告诉CPU将如何操作。 执行:这阶段包括移位操作、读通用寄存器内容、输出结果、写通用寄存器等。 三级流水线的执行步骤: 图3三级流水线 五级流水线 . 取指:从指令Cache中读取指令。 译码:对指令进行译码,识别出是对哪个寄存器进行操作并从通用寄存器中读取操作数。 执行:进行ALU运算和移位操作,如果是对存储器操作的指令,则在ALU中计算出要访问的存储器地址。 存储器访问:如果是对存储器访问的指令,用来实现数据缓冲功能(通过数据Cache)。 寄存器回写:将指令运算或操作结果写回到目标寄存器中。 五级流水线的执行步骤:
图4五级流实线六级流实线
六级流水线的执行过程:
图5六级流水线
1.6 ARM处理器工作模式 1.6.1 ARM体系的CPU有以下7种工作模式 【1】用户模式(usr):正常的程序执行状态 【2】快速中断模式(fiq):用于支持高速数据传输或通道处理 【3】中断模式(irq):用于普通中断处理 【4】管理模式(svc):操作系统使用的保护模式 【5】系统模式(sys):运行具有特权的操作系统任务 【6】数据访问终止模式(abt):数据或指令预取终止时进入该模式 【7】未定义指令终止模式(und):未定义的指令执行时进入该模式 表6
1.6.2 CPU模式 CPU的模式可以简单的理解为当前CPU的工作状态,比如:当前操作系统正在执行用户程序,那么当前CPU工作在用户模式,这时网卡上有数据到达,产生中断信号,CPU自动切换到一般中断模式下处理网卡数据(普通应用程序没有权限直接访问硬件),处理完网卡数据,返回到用户模式下继续执行用户程序。 1、用户模式 VS 特权模式 7种模式中除用户模式外其它的6种处理器模式称为Privileged Modes(特权模式)。 用户模式:大多数用户程序运行在用户模式,此模式下程序不能够访问一些受操作系统保护的系统资源,应用程序也不能直接进行处理器模式的切换。 特权模式:程序可以访问所有的系统资源,也可以任意地进行处理器模式的切换。只有在特权模式下才允许对当前的程序状态寄存器的反有控制位直接进行读写访问。 2、异常模式 VS 系统模式 6种特权模式中除系统模式外,其他5种特权模式又称之为异常模式。 异常模式:当应用程序发生异常中断时,处理器进入相应的异常模式。每一种异常模式都有一组寄存器,供相应的异常处理程序使用,这样可保证进入异常模式时,用户模式下的寄存器(保存了程序运行状态)不被破坏。 系统模式:系统模式不是通过异常过程进入的,它和用户模式具有完全一样的寄存器。但是系统模式属于特权模式,可以访问所有的系统资源,也可以直接进行处理器模式的切换。它主要供操作系统任务使用。 附:何时近入到异常模式 1)-- 复位进入管理模式,操作系统内核通常处于此种模式 2)-- 访问失败则进入中止模式 3)-- 遇到不支持的指令时,进入未定义 4)-- 中断模式与快速中断模式分别对ARM外理器2种不同等级别的中断
1.6.3模式切换 处理器的模式可以通过软件控制进行切换,也可以通过外部中断或是异常处理过程进行切换。 1、当异常发生,CPU进入相应的异常模式时,以下工作是由CPU自动完成的: 1)-- 在异常模式的R14中保存前一工作模式的下一条即将执行的指令地址; 2)-- 将CPSR的值复制到异常模式的SPSR中; 3)-- 将CPSR的工作模式设为该异常模式对应的工作模式; 4)-- 令PC值等于这个异常模式在异常向量表中的地址,即跳转去执行异常向量表中的相应指令; 2、从异常工作模式退回到之前的工作模式时,需要由软件来完成以下工作: 1)-- 将异常模式的R14减去一个适当的值(4或8)后赋给PC寄存器; 2)-- 将异常模式SPSR的值赋给CPSR;
1.6.4 ARM体系的CPU有两种工作状态 1、ARM 2、THumb CPU上电处于ARM状态
1.6.5寄存器 ARM有31个通用的32位寄存器,6个程序状态寄存器,共分为7组,有些寄存器是所有工作模式共用的,还有一些寄存器专属于每一种工作模式; R13——栈指针寄存器,用于保存堆栈指针; R14——程序连接寄存器,当执行BL子程序调用指令时,R14中得到R15的备份,而当发生中断或异常时,R14保存R15的返回值; R15——程序计数器;快速中断模式有7个备份寄存器R8—R14,这使得进入快速中断模式执行很大部分程序时,甚至不需要保存任何寄存器; 快速中断模式有7个备份寄存器R8—R14,这使得进入快速中断模式执行很大部分程序时,甚至不需要保存任何寄存器; 其它特权模式都含有两个独立的寄存器副本R13、R14,这样可以令每个模式都拥有自己的堆栈指针和连接寄存器;
1.6.6当前程序状态寄存器(CPSR) CPSR中各位意义如下: T位:1——CPU处于Thumb状态, 0——CPU处于ARM状态; I、F(中断禁止位): 1——禁止中断, 0——中断使能; 工作模式位:可以改变这些位,进行模式切换;
1.6.7程序状态保存寄存器(SPSR) 当切换进入某一个特权模式时,SPSR保存前一个工作模式的CPSR值,这样,当返回前一个工作模式时,可以将SPSR的值恢复到CPSR中;
1.7编写简单的ARM汇编程序 首先,我们先看一个简单的汇编程序: area ff,code,readonly ;声明代码段 code32 ;声明为32位ARM指令 entry ;声明程序入口 start ;b指令 ;1.b 跳转范围+_ 32M b + 标号 ;b start ;b stop ;2.bl 子函数调用 ;会把预取指令的地址保存在lr(r14) ;3.bx 子函数返回 mov r0,#9 mov r1,#15 mov r5,#9 bl func ;int func(int a,int b) stop b stop func mov r5,#1 loop cmp r0,r1 beq stop1 subgt r0,r0,r1 sublt r1,r1,r0 b loop stop1 bx lr end 可以看出,ARM汇编程序用“;”号进行注释。
1.7.1汇编语言程序格式 一个完整的ARM汇编由两部分组成:声明,实际代码段两部分组成。 1、声明 在一个程序之前先要进行声明: 1)声明代码段: 用AREA指令定义一个段,说明所定义段的相关属性。(说明段的名字,段的属性) 2) 声明ARM指令: 用CODE32或CODE16来声明程序为32位ARM指令或是16位Thumb指令。 3) 声明程序入口: 用ENTRY指令标识程序的入口点。 注: 这3个声明缺一不可。 在程序完成后要用END 指令声明程序结束。每一个汇编程序段都必须有一条END指令,指示代码段的结束。 2、段 1)在ARM汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。 2)段的分类 代码段:代码段的内容为执行代码 数据段:数据段存放代码运行时需要用到的数据。 注:一个汇编程序至少有一个代码段。如果程序较长时,可以分割为多个代码段和数据段。多个段在程序编译连接时最终形成一个可执行的映像文件。 3)段具有以下的属性 Ø READONLY Ø READWRITE
1.7.2汇编语言的语句格式 [LABEL] OPERATION [OPERAND] [;COMMENT] 标号域 操作助记符域 操作数域 注释域 1. 标号域(LABLE) 1>标号域用来表示指令的地址、变量、过程名、数据的地址和常量。 2>标号是可以自己起名的标识符,语句标号可以是大小写字母混合,通常以字母开头,由字母、数字、下划线等组成。 3> 语句标号不能与寄存器名、指令助记符、伪指令(操作)助记符、变量名同名。 4> 语句标号必须在一行的开头书写,不能留空格。 2. 操作助记符域(OPERATION) 1>操作助记符域可以为指令、伪操作、宏指令或伪指令的助记符。 2> ARM汇编器对大小写敏感,在汇编语言程序设计中,每一条指令的助记符可以全部用大写、或全部用小写,但不允许在一条指令中大、小写混用。 3> 所有的指令都不能在行的开头书写,必须在指令的前面有空格,然后再书写指令。 4> 指令助记符和后面的操作数或操作寄存器之间必须有空格,不可以在这之间使用逗号。 3. 操作数域(OPERAND) 操作数域表示操作的对象,操作数可以是常量、变量、标号、寄存器名或表达式,不同对象之间必须用逗号“,”分开。
1.7.3 ARM指令集格式 opcode {< cond>}{S} < Rd>,< Rn> {,< operand2>} 1、其中<>中的项是必须的,{}中的项是可选的。 2、opcode 表示指令助记符。 cond:表示执行条件。 S:表示是否影响CPSR寄存器的值。 Rd:表示目标寄存器。 Rn:表示第一个操作数的寄存器。 operand2:表示第2个操作数。 3、“operand2”具有如下的形式: 1>#immed_8r:常数表达式 eg: MOV R0,#1 ADD R0,R1,#0X0F 2>Rm:寄存器形式。 即在寄存器方式下,操作数即为寄存器的数值。 eg: MOV PC,R0 ADD R1,R1,R2 3>Rm,shift:寄存器移位方式。 将寄存器的移位结果作为操作数,当Rm值保持不变。 Ø ASR #n:表示算术右移n位。 Ø LSR #n:表示逻辑右移n位。 Ø ROR #n:表示循环右移n位。 Ø RRX #n:带扩展的循环右移n位。 Ø LSL #n:逻辑左移n位。 4> 使用条件码“cond”可以实现高效的逻辑操作,提高代码的效率。 Ø 所有的ARM指令都可以条件执行。 Ø Thumb指令只有B(跳转)指令具有条件执行功能。 注:如果执行中不表明条件码,默认为无条件(AL)执行。
1.7.4汇编程序中常用的符号 在汇编语言程序设计中,经常使用各种符号表示变量、常量和地址 Ø 符号由大小写字母、数字以及下划线组成。 Ø 符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。 Ø 符号在其作用范围内必须唯一,即在其作用范围内不可有同名的符号。 Ø 自定义的符号名不能与系统的保留字相同。 符号名不应与指令或伪指令同名。 1. 程序中的变量: 1>ARM汇编程序所支持的变量有数字变量,逻辑变量和字符串变量 2>在ARM汇编程序设计中,可使用GBLA,GBLL,GBLS伪定义声明全局变量,使用LCLA,LCLL,LCLS声明局部变量,并可使用SETA,SETL和SETS对其经行初始化。 2. 程序中的常量 1>ARM汇编程序所支持常量有数字常量,逻辑常量和字符串常量。 3. 程序中的变量代换 1>程序中的变量可通过代换操作取的一个常量。代换操作符为”$” 2>使用示例: LCLS S1 LCLS S2 ;定义局部字符串变量S1和S2 S1 SETS “Test!” S2 SETS “This is a $ S1”;S2的值为“This is a Test
原作者:Bruceoxl
|