ARM体系结构和汇编指令

第一节 可编程器件的编程原理

1. 可编程器件的特色

  • 1 . CPU在固定频率的时钟控制下节奏运行
  • 2 . CPU能够经过总线读取外部存储设备中的二进制指令集,而后解码执行
  • 3 . 这些能够被CPU解码执行的二进制指令集是CPU设计的时候肯定的,是CPU的设计者(ARM公司)定义的,本质上是一串由1和0组成的数字。这就是CPU的汇编指令集

2. 从源代码到cpu执行过程

第二节 指令集对cpu的意义

1. 汇编语言与C等高级语言的差别

  • 汇编无移植性,c语言有必定可移植性,jave等更高级的语言移植性更强
  • 汇编语言效率最高,C次之,jave等更高级语言效率更低
  • 汇编不适合完成大型复杂的项目,更高级语言更适合完成更大,更复杂的项目

2. 汇编语言的本质

  • 汇编的实质是机器指令(机器码)的助记符,是一种低级符号语言
  • 机器指令集是一款CPU的编程特征,是这款CPU的设计者制定的。CPU的内部电路设计就是为了实现这些指令集的功能。机器指令集就好像CPU的API接口同样
  • 汇编器的工做是把助记符(如MOV相似人的姓名)翻译成(101001相似身份证号码)

3. 汇编语言的发展过程

  • 纯机器码编码
  • 汇编语言编程
  • c语言编程
  • c++语言编程
  • jave,c#等语言编程
  • 脚本语言编程

4. 总结

  • 汇编语言就是CPU的机器指令集的助记符,是一款CPU的本质特征
  • 不一样CPU的机器指令集设计不一样,所以汇编程序不能在不一样CPU之间相互移植
  • 使用汇编编程能够充分发挥CPU的设计特色,因此汇编编程效率最高,所以在操做系统内核中效率极其重要处都须要用汇编处理

第三节 RISC和CISC的区别

1. CISC

  • complex instruction set computer复杂指令集CPUlinux

  • CISC体系的设计理念是用最少的指令来完成任务(譬如计算乘法只须要一条MUL指令便可),所以CISC的CPU自己设计复杂,工艺复杂,但好处是编译器好设计。CISC出现较早,至今Intel还一直采用CISC设计android

2. RISC

  • Reduced Instruction Set computer精简指令集CPUnginx

  • RISC的设计理念是让软件来完成具体的任务,CPU自己仅提供基本功能指令集。所以RISC CPU的指令集中只有不多的指令,这种设计相对于CISC,CPU的设计和工艺简单了,可是编译器的设计变难了c++

3.CPU设计方式发展

  • 早期简单CPU,指令和功能都颇有限程序员

  • CISC时代--CPU功能扩展依赖于指令集的扩展,实质是CPU内部组合逻辑电路的扩展docker

  • RISC年代--CPU仅提供基础功能指令(譬如内存与寄存器通讯指令,基本运算与判断指令等),功能扩展由使用CPU的人利用基础构架来灵活实现编程

4.RISC与CISC指令数对比

通常典型CISC CPU指令在300条左右
ARM CPU经常使用指令30条左右swift

5.发展趋势

没有纯粹的RISC或CISC,发展方向是RISC和CISC结合,造成一种介于2者之间的CPU类型c#


第四节 统一编址&独立编址&哈佛结构&冯诺伊曼结构

1. 统一编址&独立编址

什么是IO?什么是内存?

  • 内存就是程序的运行场所,内存和CPU之间经过总线链接,CPU经过必定的地址来访问具体内存单元安全

  • IO(input and output)是输入输出接口,是CPU和其余外部设备(如串口,LCD,触摸屏,LED等)之间通讯的道路。通常的,IO就是只CPU的各类内部和外部外设

内存的访问方式

  • 内存经过CPU的数据总线来寻址定位,而后经过CPU数据总线来读写

  • CPU的地址总线的位数是CPU设计时肯定的,所以一款CPU所能寻址的范围是必定的,而内存是须要占用CPU的寻址空间

  • 内存与CPU的这种总线式链接方式是一种直接链接,优势是效率高访问块,缺点是资源有限,扩展性差

IO的访问方式(经过访问寄存器来操做IO)

  • IO指的是与CPU链接的各类外设

  • CPU访问各类外设有2种方式,一种是相似于访问内存的方式,即把外设的寄存器当作一个内存地址来读写,从而以访问内存相同的方式来操做外设,叫IO与内存统一编址方式(RISC,如ARM);另外一种是使用专用的CPU指令来访问某种特定外设,叫IO与内存独立编址(CISC)

内存与IO访问方式的对比

  • 因为内存访问频率高,所以采用总线式链接,直接地址访问,效率最高

  • IO与内存统一编址方式,优点是IO当作内存来访问,编程简单;缺点是IO也须要占用必定的CPU地址空间,而CPU的地址空间是有限资源

  • IO与内存独立编址方式,优点是不占用CPU地址空间;缺点是CPU设计变复杂了

2. 冯诺伊曼结构与哈佛结构

程序和数据

  • 程序运行是两大核心元素:程序代码+数据

  • 程序是咱们写好的源代码通过编译,汇编以后获得的机器码,这些机器码能够拿给CPU去解码执行,CPU不会去修改程序,因此程序是只读的

  • 数据是程序运行过程当中定义和产生的变量的值,是能够读写的,程序运行实际就是为了改写数据的值

什么是冯诺伊曼结构?什么是哈佛结构?

  • 程序和数据都放在内存中,且不彼此分离的结构称为冯诺伊曼结构,譬如Intel的CPU均采用冯诺伊曼结构

  • 程序和内存分开独立放在不一样的内存块中,彼此彻底分离的结构称为哈佛结构。譬如大部分单片机(MCS51,ARM9等)均采用哈佛结构

冯诺伊曼结构与哈佛结构对比

  • 冯诺伊曼结构中程序和数据不区分的放在一块儿,所以安全域稳定性(病毒)是个问题,好处是处理器来简单

  • 哈佛结构中程序(通常放在ROM,flash中)和数据(通常放在RAM中)独立分开存放,所以好处是安全和稳定性高,缺点是软件处理复杂一些(须要统一规划连接地址等)

第五节 软件编程控制硬件的关键---寄存器

1. 什么是寄存器

  • 寄存器属于CPU外设的硬件组成部分
  • CPU能够像访问内存同样访问寄存器
  • 寄存器是CPU的硬件设计者制定的,目的是留做外设被编程的"活动开关"
  • 正如汇编指令集是CPU的编程接口API同样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器
  • 编程操做寄存器相似于访问内存
  • 寄存器总每一个bit位都有特定含义,所以编程操做须要位操做
  • 单个寄存器的位宽通常和CPU的位宽同样,以实现最佳访问效率

2. 两类寄存器

  • SoC中有2类寄存器:通用寄存器(和CPU绑定)和SFR(功能已经在设计CPU时就已经肯定好了,不能再改变,已经事先和某个外设绑定好了)
  • 通用寄存器(ARM中有37个)是CPU的组成部分,CPU的不少活动都须要通用寄存器的支持和参与
  • SFR(special function register特殊功能寄存器)不在CPU中,而存在于CPU的外设中,咱们经过访问外设的SFR来编程操控这个外设,这就是硬件编程控控制的方法

第六节 ARM体系结构总结

1. ARM是RISC架构

  • [ ] 经常使用的ARM汇编指令只有二三十条

  • [ ] ARM是低功耗CPU

  • [ ] ARM的架构很是适合单片机,嵌入式,尤为是物联网领域;而服务器等高校性能领域目前主导仍是Intel

2. ARM是统一编址的(IO与内存)

  • [ ] 大部分ARM(M3 M4 M7 M0 ARM9 ARM11 A8 A9等)都是32位架构

  • [ ] 32位ARM CPU支持的内存少于4G,经过CPU地址总线来访问

  • [ ] SoC中的各类内部外设经过各自的SFR编程访问,这些SFR的访问方式相似于访问普通内存,这叫IO与内存统一编址

3. ARM是哈佛结构的

  1. 常见的ARM(ARM7除外(已淘汰))都是哈佛结构的

  2. 哈佛结构保证了ARM CPU运行的稳定性和安全性,所以ARM适用于嵌入式领域

  3. 哈佛结构也决定了ARM裸机程序(使用实地址即物理地址的地址叫裸机程序)的连接比较麻烦,必须使用复杂的连接脚本告知连接器如何组织程序;对于OS之上的应用(工做在虚拟地址之中)则不需考虑这么多


第七节 S5PV210的地址映射详解

1. 什么是地址映射(通常叫内存映射)

  • S5PV210属于ARM Cortex-A8架构,32位CPU,CPU设计时就有32根地址线&32根数据线

  • 32根地址线决定了CPU的地址空间为4G,那么这4G空间如何分配使用?这个问题就是地址映射问题(硬编码,不能修改)

2. 一些专用术语

  • ROM:read only memory 只读存储器(不能直接经过地址总线和数据总线写)
  • RAM:ramdom access memory 随机访问存储器
  • IROM:internal rom 内部ROM,指的是集成到SoC内部的ROM(内存条有两个IROM&IRAM,目的是映射和转换。底下是上面的映射,很灵活)
  • IRAM:internal ram 内部RAM,指的是集成到SoC内部的RAM
  • DRAM:dynamic ram 动态RAM(外部接的内存就是平时咱们插入的内存条)
  • SRAM:static ram 静态RAM,容量小,价格高,优势是不须要软件初始化直接上电就能用
  • SROM:接网卡

第八节 CPU和外部存储器的接口

1.内存与外存的区别

  • 内存就是内部存储器,是用来运行程序的,即RAMDRAM,SRAM,DDR),经过地址总线访问

  • 外存就是外部存储器,是用来存储东西的,即ROM(硬盘,flash(Nand,iNand...U盘,SSD),光盘)

  • CPU链接内存和外存的链接方式不一样。内存须要直接地址访问,因此是经过地址总线和数据总线的总线式访问方式链接到(好处是直接访问,随机访问;坏处是占用CPU的地址空间,大小受限);外存是经过CPU的外存接口来链接到(好处是不占用CPU的地址空间,坏处是访问速度没有总线式快,访问时序较复杂)

2. SoC经常使用外部存储器

Flash类(电子式)

  • NorFlash(总线式访问,接到SROMC Bank,优势是能够直接总线访问,通常用来启动,太贵,已不多使用,但很可靠)
  • NandFlash(分为SLC和MLC,已渐渐淘汰)
  • eMMC/iNand/moviNand(iNand是SanDisk公司出厂的eMMC,moviNand是三星出厂的eMMC)
  • oneNAND(oneNand是三星出的一种Nand,只有三星使用)
  • eSSD(e即embeded嵌入式)
  • SD卡/TF卡/MMC卡

硬盘类

SATA硬盘(机械式访问,磁存储原理,SATA是接口)

3. X210开发板支持的外部存储器

  • X210有2个版本,Nand版和iNand版,分别使用NandFlash和iNand位外部存储器。咱们使用的是iNand版本,板载4GBiNand

  • S5PV210共支持4个SD/MMC通道,其中通道0和2依次用做启动。X210开发板中SD/MMC0通道用于链接板载MMC,所以外部启动时SD/MMC2通道(注意通道3不能启动)

第九节 S5PV210的启动过程详解

1. S5PV210 的启动过程

第一步:CPU上电后先从内部iROM中读取预先设置的代码,执行。这一段iROM代码作了一些基本的初始化(CPU时钟,关看门狗...)(这一段iROM代码是三星出厂前设置的,三星不知道咱们板子上未来接的是什么样的DRAM,所以这一段iROM是不能负责初始化外接的DRAM,所以这一段代码只能初始化SoC内部的东西);而后这一段代码会判断咱们选择的启动模式(咱们经过硬件跳线能够更改板子的启动模式),而后从相应的外部存储器去读取第一部分启动代码(BL1,大小为16KB)到内部SRAM

第二步:从SRAM去运行上一步读取来的BL1(16KB),而后执行。BL1负责初始化NandFlash,而后将BL2读取到iRAM(80KB).

第三步:从iRAM运行BL2,BL2初始化DRAM,而后将OS读取到DRAM中,而后启动OS,启动过程结束

思路:由于启动代码的大小是不定的,因此两步启动不合适
三星的解决方案是:把启动代码分为2半(BL1和BL2),这两部分协同工做来完成启动

2. BL0(iROM)作了什么

  • 关看门狗
  • 初始化指令cache
  • 初始化栈
  • 初始化堆
  • 初始化块设备复制函数device copy function
  • 设置SoC时钟系统
  • 复制BL1到内部的iRAM(16KB)
  • 检查BL1的校验和
  • 跳转到BL1去执行

3. S5PV210的全部启动

  • 先1st,经过OMpin选择启动介质
  • 再2nd启动,从SD2
  • 再Uart启动
  • 再USB启动

4. 其余

  1. 内存:

    SRAM:静态内存,特色是容量小,价格高,优势是不须要软件初始化直接上电就能用
     DRAM:动态内存,特色是容量大,价格低,缺点是上电后不能直接使用,须要软件初始化后才可使用

单片机中:内存需求量小,并且但愿开发尽可能简单,适合所有用SRAM
嵌入式系统:内存需求量大,并且没有NorFlash等可启动介质
PC机中:内存需求量大,并且软件复杂,不在意DRAM的初始化开销,适合所有用DRAM

2 . 外存:

NorFlash:特色是容量小,价格低,优势是能够和CPU直接总线式相连,CPU上电后能够直接读取,因此通常用启动介质 NandFlash(跟硬盘同样):特色是容量大,价格低,缺点是不能总线式访问,也就是说不能上电CPU直接读取,须要CPU先运行一些初始化软件,而后经过时序接口读写

因此通常PC机都是:不多容量的BIOS(NorFlash) + 很大容量的硬盘(相似NandFlash) + 大容量的DRAM
通常的单片机:不多容量的NorFlash + 不多容量的SRAM
嵌入式系统:由于NorFlash很贵,如今不少嵌入式系统倾向于不一样NorFlash,直接用:外接的大容量Nand + 外接大容量DRAM + SoC内置SRAM

3 . S5PV210启动方式是:外接的大容量Nand + 外接大容量DRAM + SoC内置SRAM
实际上,210内置了一块96KB的SRAM(叫iRAM),同时还有一块内置的64KB大小的NorFlash

第十节 如何在开发板上选择不一样的启动方式

  1. 体验从SD0的eMMC启动
    开发板默认从eMMC启动,内部预先烧录了Android

  2. 从SD2启动
    可使用外置SD卡从SD2通道启动,但这须要先破坏板载的eMMC中的android镜像。破坏方法见《X210V3开发板当即教程》2.5.2节

  3. USB调试模式

第十一节 ARM的编程模式和7种工做模式

1. ARM的基本设定

  1. ARM采用的是32位架构
  2. ARM约定:

    Byte: 8 bits Halfword:16 bits (2 byte) Word: 32 bits (4 byte)
  3. 大部分ARM core提供

    ARM指令集(32 bit) Thumb指令集(16 bit) Thumb2指令集(16 & 32 bit)

4.Jazelle cores 支持 jave bytecode

2. ARM处理器工做模式

  1. ARM处理器共有7种基本工做模式

    用户模式
     User:非特权模式,大部分任务执行在这种模式 异常模式 FIQ:当一个高优先级(fast)中断产生时将会进入这种模式 IRQ:当一个低优先级(normal)中断产生是将会进入这种模式 Supervisor(管理模式):当复位或软中断指令执行时将会进入这种模式 Abort:当存取异常时将会进入这种模式 Undef:当执行未定义指令时将会进入这种模式 系统模式 System:使用和User模式相同寄存器集的特权模式

注意:

  1. 除User(用户模式)是Normal(普通模式)外,其余6种都是Privilege(特权模式)
  2. Privilege中除sys模式外,其他5种为异常模式
  3. 各类模式的切换,能够是程序员经过代码主动切换(经过写CPSP寄存器);也能够是CPU在某些状况下自动切换
  4. 各类模式下权限和能够访问的寄存器不一样

2. CPU为何设计这些模式

  1. CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件须要,便于实现软件特性
  2. 操做系统有安全级别要求,所以CPU设计多种模式是为了方便操做系统的多种角色安全等级须要

第十二节 ARM的37个寄存器(不是SFG)详解

1. 概述

ARM总共有37个寄存器,可是每种模式下最多只能看到18个寄存器,其余寄存器虽然名字相同可是在当前模式下不可见。

37个寄存器中30个为"通用”型,1个固定用做PC,一个固定用做CPSR,5个固定用做5中异常模式下的SPSR

对r14这个名字来讲,在ARM中共有6个名叫r14(又叫sp)的寄存器,可是在每种特定处理器模式下,只有一个r14是当前可见的,其余的r14必须切换到它的对应模式下才能看到。这种设计叫影子寄存器(banked register)

2. CPSR程序状态寄存器

  1. Mode位(0 - 4)

    处理器模式位
  2. T Bit(5)

    仅ARM xT架构支持
     T = 0:处理器处于ARM状态 T = 1:处理器处于Thumb状态
  3. 中断禁止位(6 - 7)

    I = 1:禁止IRQ F = 1:禁止FIQ
  4. J位(24)

    仅ARM 5TE/J架构支持
     J = 1:处理器处于Jazelle状态
  5. Q位(27)

    仅ARM 5TE/J架构支持
     指示饱和状态
  6. 条件位(28 - 31)

    N = Negative result from ALU Z = Zero result from ALU C = ALU operation Carried out V = ALU operation overflowed

3. PC(r15)程序控制寄存器

  1. PC(Program control register)为程序指针,PC指向哪里,CPU就会执行哪条指令(因此程序跳转是就是把目标地址代码放到PC中)
  2. 整个CPU中只有一个PC(CPSR也只有一个,但SPSR有5个)

第十二节 ARM的异常处理方式简单介绍

1. 什么是异常

  1. 正常工做以外的流程都叫异常

  2. 异常会打断正在执行的工做,而且通常我慢但愿异常处理完成后继续回来执行原来的工做

  3. 中断是异常的一种

2. 异常向量表

  1. 全部的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的

  2. 当异常发生时,CPU会自动动做(PC跳转到宜昌向量到处理异常,有时伴有一些辅助动做)

  3. 异常向量表是应将想软件提供的处理异常的支持

3. ARM的异常处理机制

  1. 当异常产生时

    拷贝CPSR到SPSR_<mode> 设置适当的CPSR位: 改变处理器状态进入ARM态 改变处理器模式进入相应的异常模式 设置中断禁止位禁止相应中断 保存返回地址到LR_<mode> 设置PC为相应的异常向量
  2. 返回时,异常处理须要

    从SPSR_<mode>恢复CPSR 从LR_<mode>恢复PC Note:这些操做只能在ARM态执行

第十三节 ARM的汇编指令集

1. 指令与伪指令的概念

  1. (汇编)指令是CPU机器指令的助记符,通过编译后会获得一串10组成的机器码,能够由CPU读取执行

  2. (汇编)伪指令本质上不是指令(只是和指令一块儿写在代码中),他是编译器环境提供的,目的是用来指导编译过程,通过编译后伪指令最终不会生成机器码

2. 两种不一样风格的ARM指令

  1. ARM官方的ARM汇编风格:指令通常用大写,Windows中IDE开发环境(如ADS,MDK等)经常使用。如:LDR R0,[R1]

  2. GNU风格的ARM汇编:指令通常用小写字母,linux中经常使用。如ldr r0,[r1]

3. ARM汇编的特色

LDR/STR架构

  1. ARM采用RISC架构,CPU自己不能直接读取内存,而须要先讲内存中的内容加载入CPU中通用寄存器中才能被CPU处理

  2. ldr(load register)指令将内存内容加载入通用寄存器

  3. str(store register)指令将寄存器内容存入内存空间中

  4. ldr/str组合用来实现ARM CPU和内存数据交换

8种寻址方式

> * 寄存器寻址 mov r1,r2 > * 当即寻址 mov r0,#0xFF00 > * 寄存器移位寻址 mov r0,r1,lsl #3 > * 寄存器间接寻址 ldr r1,[r2] > * 基址变址寻址 ldr r1,[r2,#4] > * 多寄存器寻址 ldmia r1!,{r2-r7,r12} > * 堆栈寻址 stmfd sp!,{r2-r7,lr} > * 相对寻址 beq flag 

指令后缀

同一指令常常附带不一样后缀,变成不一样的指令。常用的后缀有

> * B(Byte) 功能不变,操做长度变为8位 > * H(Half word) 功能不变,长度变为16位 > * S(Signed) 功能不变,操做数变为有符号 > * 如ldr ldrb ldrh ldrsb ldrsh > * S(S标志) 功能不变,影响CPSR标志位 > * 如mov movs 

条件执行后缀

条件后缀是否成立,不是取决于本句代码,而是取决于这句代码以前的代码运行后的结果
条件后缀决定了本句代码是否被执行,而不会影响上一句和下一句代码是否被执行

moveq r0,r1  @相似于c语言中的if (eq) {r0= r1;}
操做码 条件码助记符 标志 含义
0000 EQ Z = 1 相等
0001 NE Z = 0 不相等
0010 CS/HS C = 1 无符号数大于或等于
0011 CC/LO C = 0 无符号数小于
0100 MI N = 1 负数
0101 Pl N = 0 正数或零
0110 VS V = 1 溢出
0111 VC V = 0 没有溢出
1000 HI C = 1,Z = 0 无符号数大于
1001 LS C = 0,Z = 1 无符号数小于或等于
1010 GE N = V 有符号数大于或等于
1011 LT N != V 有符号数小于
1100 GT Z = 0,N = V 有符号数大于
1101 LE Z = 1,N != V 有符号数小于或等于
1110 AL 任意 无条件执行(指令默认条件)
1111 NV 任意 从不执行(不要使用)

多级指令流水线

为了增长处理器指令流的速度,ARM使用多级流水线, S5PV210使用13级流水线,ARM11为8级

容许多个操做同时处理,而非顺序执行

PC指向正被取值的指令,而非正在指向的指令

4. 经常使用的ARM指令

数据处理指令

数据传输指令 mov mvn
算术指令 add sub rsb adc sbc rsc 逻辑指令 and orr eor bic 比较指令 cmp cmn tst teq 乘法指令 mvl mla umull umlal smull smlal 前导零计数 clz

注意
1 . mvn和mov用法同样,区别是mov是原封不动的传递,而mvn是按位取反后传递

mov r1,r2 @两个寄存器之间数据传递 mov r1,#0 @将当即数传给寄存器

2 . and orr(逻辑或) eor(逻辑异或) bic(位清除指令)

bic r0,r0,#0x1f @将r0中的数的bit0到bit4清零后赋值给r0 0x1f = 0x0000 001f = 0x0000 ```` 11111

3 . 比较指令用来不叫2个寄存器中的数

cmp r0,r1 @比较r0,r1的数是否相等 cmn r0,r1 @让r0和r1中的数相加 tst r0,#0xf @测试r0的bit0-bit3是否相等

注意:比较指令不用后加s后缀就能够影响spcr中的标志位

4 . sub r2,r0,r1 (r2 = r0 -r1)

cpsr访问指令

CPSR寄存器比较特殊,须要专门的指令访问,这就是mrs和msr

mrs & msr(更强)

mrs用来读psr,msr用来写psr

注意cpsr和spsr的区别和联系:
cpsr是程序状态寄存器,整个SoC中只有1个;而spsr有5个,分别在5中异常模式下,做用是当从普通模式进入一场模式时,用来保存以前普通模式下的cpsr,以在返回普通模式时恢复原来的cpsr

跳转(分支)指令

b & bl & bx

b 直接跳转
bl branch and link,跳转前把返回地址放入lr中,以便返回,以便于函数调用
bx 跳转同时切换到ARM模式,通常用于异常处理的跳转(如今已经不用)

访存指令

ldr/str & ldm/stm &swp

单个字/半字/字节访问ldr/str
多字批量访问 ldm/stm
swp r1,r2,[r0] @内存与寄存器交换内容
swp r1,r1,[r0]

软中断指令

swi(software interrupt) 

软中断指令用来实现操做系统中系统调用

5. ARM汇编中的当即数(标志符号#)

  1. 合法当即数和非法当即数

  2. ARM指令都是32位,除了指令标记和操做标记外,自己只能附带不多位数的当即数。所以当即数有合法与非法之分

  3. 合法当即数:通过任意位数的移位后非零部分能够用8位表示的几位合法当即数

    合法:0xf000 000f,0x00ff 0000

6. ARM的协处理器指令

什么是协处理器

  • SoC内部另外一处理核心,协助主CPU实现某些功能,被主CPU调用执行必定任务

  • ARM设计上支持多达16个协处理器,可是通常SoC只实现其中的CP15(coprocessor)

  • 协处理器和MMU,cache,TLB等处理有关,功能上和操做系统1的虚拟地址映射,cache管理等有关

协处理器cp15操做指令

mcr & mrc 

mrc用于读取cp15中的寄存器
mcr用于写入cp15中的寄存器

MRC & MCR的使用方法

  • [ ] mcr{
  • [ ] opcode_1:对于cp15永远为0
  • [ ] Rd:ARM的普通寄存器
  • [ ] Crn:cp15的寄存器,合法值是c0-c15
  • [ ] Crm:cp15的寄存器,通常均设为c0
  • [ ] opcode_2:通常省略或为0

7.ARM的ldm/stm与栈处理

为何须要多寄存器访问指令

  • ldr/str每周期只能访问4字节内存,若是须要批量读取,写入内存时太慢,解决方案是ldm/stm
  • ldm/stm:load register multiple/store register multiple
  • 举例(uboot的start.S 537行)

    stmia sp,{r0-r12} @将r0存入sp指向的内存处(假设为0x3000 1000);而后地址+4(即指向0x3000 1004),将r1存入该地址;而后地址再+4(指向0x3000 1008),将r2存入该地址.....直到r12内容放入(0x300 1030),指令完成 一个存访周期同时完成13个寄存器的读写 (r0-r12寄存器,sp寄存器里放了一个内存)

8种后缀

  • ia(increase after)先传输,再地址+4
  • ib(increase brfore)先地址+4,再传输
  • da(decrease after)先传输,再地址-4
  • db
  • fd(full decrease)满递减堆栈
  • ed(empty decrease)空递减堆栈
  • fa 满递增堆栈
  • ea 空递增堆栈

4种栈

  • 空栈:栈指针指向空位,每次存入时能够直接存入而后栈指针移动一格;而取出时须要先移动一格才能取出
  • 满栈:栈指针指向栈中最后一个数据,每次存入时须要先移动栈指针一格再存入
  • 增栈:栈指针移动时向地址增长的方向移动的栈
  • 减栈:栈指针移动时向地址减小的方向移动的栈

!的做用

ldmia r0,{r2 - r3} ldmia r0 !,{r2 - r3}

!做用是r0的值在ldm过程当中发生的增长或者减小最后写回r0的值

^的做用

ldmfd sp!,{r0 - r6,pc} ldmfd sp!,{r0 - r6,pc}^ 

^的做用:在目标寄存器中有PC时,会同时将spsr写入到cpsr,通常用于从异常模式返回

8. 总结

操做栈时使用相同的后缀就不会出错
批量读取或写入内存时要用ldm/stm指令
经常使用stmfd和stmia

第十四节 ARM汇编伪指令

1. 伪指令的意义

  • 伪指令不是指令,伪指令和指令的根本区别是通过编译后会不会生成机器码
  • 伪指令的意义在于指导编译过程
  • 伪指令是和具体的编译器相关的,咱们使用gnu工具链,所以学习gnu环境下的汇编伪指令

2. gnu汇编中的一些符号

  • [ ] @用来作注释。能够在行首也能够在代码后面同一行直接跟,和c语言中的//相似
  • [ ] # 作注释,通常放在行首,表示这一行都是注释而不是代码
  • [ ] :以冒号结尾的是标号
  • [ ] .点号在gnu汇编中表示当前指令的地址
  • [ ] #当即数前面要加#或$,表示这个数是当即数

3. 经常使用gnu伪指令

  • [x] .global_start @给_start外部连接属性
  • [x] .section.text @指定当前段为代码段
  • [x] .ascii.byte.short.long.word @定义变量(数据类型)
  • [x] .quad.float.string @定义数据(与上一致·不经常使用)
  • [x] .align 4 @以16字节对齐(2^4)
  • [x] .balignl 16 0xabcdefgh @16字节对齐填充(b表示位填充;align表示对齐;l表示long,以4字节为单位填充;16表示16字节对齐,0xabcdefgh是用来填充的原料)
  • [x] .equ @相似c语言中的宏定义

4. 偶尔会用到的gnu伪指令

  • [ ] .end @标志文件结束
  • [ ] .include @头文件包含
  • [ ] .arm/.code32 @声明如下为arm指令
  • [ ] .thumb/.code16 @声明如下为thubm指令

5. 最重要的几个伪指令

  • [x] ldr @大范围的地址加载指令
  • [x] adr @小范围的地址加载指令
  • [x] adrl @中等范围的地址加载指令
  • [x] nop @空操做

ARM中有一个ldr指令,还有一个ldr伪指令

ldr指令:ldr r0,#0xff ldr伪指令:ldr r0,=0xfff1 @涉及到合法/非法当即数,涉及到ARM文字池 

通常都使用ldr伪指令而不用ldr指令

adr和ldr的区别

  • adr编译时会被一条sub或add指令替代,而ldr编译时会被一条mov指令替代或者文字池的方式处理
  • adr老是以PC为基准来表示地址,所以指令自己和运行地址有关,能够用来检测程序当前的运行地址在哪里
  • ldr加载的地址和链接式给定的地址有关,由连接脚本决定

adr和ldr的差异:ldr加载的地址在链接时肯定,而adr加载的地址在运行是肯定;因此咱们能够经过adr和lar加载的地址比较来判断当前程序是否在连接时指定的地址运行(重定位)

注:参考朱老师物联网大讲堂

相关文章
相关标签/搜索