朱老师ARM裸机-第二部分-ARM体系与汇编指令

1.可编程器件的编程原理
电子器件的发转方向:模拟器件->数字器件;ASIC->可编程器件。
可编程器件的特点:CPU在固定频率的时钟控制下节奏运行。
                  CPU可以通过总线读取外部设备中的二进制指令集,然后解码执行。
                  这些可以被CPU解码执行的二进制指令集是CPU设计的时候确定的,是CPU的设计者(ARM公司)定义的,本质上是一串由1和0组成的数字。这就是CPU的汇编指令集。
整个编程及运行过程:
                .c等高级语言  -(编译器)-.s汇编源代码-(汇编器)-Elf格式二进制可执行程序-(Objcopy工具)-Bin格式烧录文件-(总线)-CPU读入后先解码-(CPU内部指令流水线)-CPU执行指令。
2.指令集对CPU的意义
汇编语言与C等高级语言的差异
    汇编难写,C好写
    汇编无可移植性,C语言有一定可移植性,JAVA等更高级语言移植性更强。
    汇编语言效率最高,C语言次之,JAVA等高级语言效率更低
    汇编不适合完成大型复杂的项目,更高级语言更适合完成更大,更复杂的项目。
汇编语言的本质:机器指令集的助记符,是一种低级符号语言。
                机器指令集是一款CPU的编程特征,是这款CPU的设计者制定的。CPU的内部电路设计就是为了实现这些指令集的功                    能。机器指令集就好像CPU的API接口一样。
编程语言的发展过程:
                纯机器人编程
                汇编语言编程
                C语言编程
                C++语言编程
                JAVA C#等语言编程
                脚本语言编程
每一款CPU都有自己的汇编指令集
总结:
    汇编语言就是CPU的机器指令集的助记符,是一款CPU的本质特征。
    不同CPU的机器指令集设计不同,因此汇编程序不能再不同CPU间互相移植。
    使用汇编编程可以充分发挥CPU的设计特点,所以汇编编程效率最高,因此再操作系统内核中效率机器重要处都需要用汇编处      理。
3.RISC和CISC的区别
 CISC
    complex instruction set computer复杂指令集CPU    CISC体系的设计理念是用最少的指令来完成任务(譬如计算乘法只需要一条MUL指令即可),因此CISC的CPU本身设计复杂,工艺复杂,但是好处是编译器好设计。CISC出现较早,至今intel还一直采用CISC设计。
 RISC
    Reduced instruction-set Computer精简指令集
    RISC的设计理念是让软件来完成具体的任务,CPU本身仅提供基本的功能指令集。因此RISC CPU的指令集只有很少的指令,这种设计相对于CISC,CPU的设计和工艺简单了,但是编译器的设计变难了。
RISC和CISC指令数对比
    一般典型的CISC CPU指令再300条左右
    ARM CPU常用指令30条左右
发展趋势:没有纯粹的RISC和CISC,发展反向是RISC和CISC的结合,形成一种介于2者之间的CPU类型。
4.统一编址和独立编址   哈佛结构和冯诺依曼结构
什么是内存?什么是IO?
    内存是程序的运行场所,内存和CPU之间通过总线连接,CPU通过一定的地址来访问具体内存单元
    IO是指CPU的各种内部或者外部设备。
内存的访问方式
    内存通过CPU的数据总线来寻址定位,然后通过CPU数据总线来读写。
    CPU的地址总线的位数是CPU设计时确定的,因此一款CPU所能寻址的范围是一定的,而内存是需要占用CPU的寻址空间的。
    内存与CPU的这种总线式连接方式是一种直接连接,优点是效率高访问快,缺点是资源有限,扩展性差。
IO的访问方式
    IO指的是与CPU连接的各种外设
    CPU访问各种外设有2种方式:
        一种是类似于访问内存的方式,即把外设的寄存器当作一个内存地址来读写,从而以访问内存相同的方式来操作外设,叫IO与内存统一编址方式。(ARM)RISC
        另一种是使用专用的CPU指令来访问某种特定外设,叫IO与内存独立编址。(CISC)
对比
    由于内存访问频率高,因此采用总线式连接,直接地址访问,效率最高。
    IO与内存统一编址方式,优势是IO当作内存来访问,编程简单;缺点是IO也需要占用一定的CPU地址空间,而CPU的地址空间是有限资源。
    IO与内存独立编址方式,优势是不占用CPU的地址空间,缺点是CPU的设计变复杂了。
程序和数据
    程序运行时两大核心元素:程序+数据
    程序是我们写好的源代码经过编译,汇编之后得到的机器码,这些机器码可以拿给CPU去解码执行,CPU不会也不应该去修改程序,所以程序是只读的。
    数据是程序运行过程中定义和产生的变量的值,是可以读写的,程序运行实际就是为了改变数据的值。
冯诺依曼结构与哈佛结构
    程序和数据都放在内存中,且不彼此分离的结构称为冯诺伊曼结构。譬如INTEL的CPU均为冯诺伊曼结构。
    程序和数据分开独立放在不同的内存块中,彼此完全分离的结构称为哈佛结构。譬如大部分的单片机MCS51,ARM9等均采用哈佛结构。
优劣对比
    冯诺伊曼结构程序和数据不区分的放在一起,因此存在安全和稳定性是个问题,好处是处理起来简单。
    哈佛结构中程序一般放在ROM,FLASH中和数据(一般放在RAM中)独立分开存放,因此好处是安全和稳定性高(可以管理内存的可读与可写),缺点是软件处理复杂一些(需要统一规划连接地址等)。
5.软件编程控制硬件的关键-寄存器
什么是寄存器?
    寄存器属于CPU外设的硬件组成部分
    CPU可以像访问内存一样访问寄存器
    寄存器是CPU的硬件设计者制定的,目的是留作外设被编程控制的“活动开关”
    正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。
两类寄存器
    通用寄存器:ARM中有37个  是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持与参与,通用寄存器的功能再CPU  设定时没有定。
    SFR寄存器:特殊功能寄存器不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。
6.ARM体系结构要点总结
ARM是RISC结构
    常用ARM汇编指令只有二三十条
    ARM是低功耗CPU
    ARM的架构非常适合单片机,嵌入式,尤其是物联网领域;而服务器等高性能领域目前主导还是INTEL。
ARM是统一编址的
    大部分ARM都是32位结构
    32位ARM CPU支持的内存少于4G,通过CPU地址总线来访问
    SOC中的各种内部外设通过各自的SFR编程访问,这些SFR的访问方式类似于普通内存,这叫做IO与内存统一编址。
ARM是哈佛结构
    常见ARM(除ARM7)都是哈佛结构的。
    哈佛结构保证了ARM CPU运行的稳定性和安全性,因此ARM适用于嵌入式领域。
    哈佛结构也决定了ARM裸机程序(使用实地址即物理地址)的链接比较麻烦,必须使用复杂的链接脚本告知链接器如何组织程序;对于OS之上的应用(工作在虚拟地址之中)则不需要考虑
    这么多。
7.S5PV210的内存映射详解
    S5PV210属于ARM Cortex-A8架构,32位CPU,CPU设计时就有32根地址线和32根数据线
    32根地址线决定了CPU的地址空间为4G,那么这4G空间如何分配使用?
    这个问题就是内存映射问题(好像准确点应该叫地址映射)
    reserved理论上存在,实际上不存在。
一些专业术语
ROM  read only memory     只读存储器                  只能读不能写(CPU不能通过地址总线和数据总线去写,可以通过接口去写) FLASH和硬盘   顺序访问
RAM  random access memory 随机访问存储器              不用按页顺序访问,可以直接访问一个地址       内存
IROM internal rom         内部ROM  ,集成到SOC内部的ROM  
IRAM internal ram         集成到SOC内部的RAM
DRAM dynamic ram          动态RAM    
SRAM static ram           静态RAM
SROM 
ONENAND/NAND
SFR special function register  特殊功能寄存器
8.CPU和外部存储器的接口
内存   内部存储器    用来运行程序的  RAM
外存   外部存储器    用来存储东西的  ROM      硬盘 FLASH  NAND iNAND U盘  SSD 
CPU连接内存和外存的连接方式不同。
    内存需要直接地址访问,所以是通过地址总线和数据总线的总线式访问方式连接的(好处是直接访问,随机访问;坏处是占用CPU的地址空间,大小受限);
    外存是通过CPU的外存接口来连接的(好处是不占用CPU的地址空间,坏处是访问速度没有总线式快,访问时序较为复杂)。
SoC常用的外部存储器
NorFlash                   总线式访问,接到SROM bank,优点是可以直接总线式访问,一般用来启动。BIOS

NandFlash                  非总线式访问。分为SLC和MLC      SLC:容量小稳定成本高    MLC:容量大不稳定成本低,容易出现坏块
eMMC/iNand/moviNand        嵌入式的MMC卡,目前用的比较多的EMMC,iNand是Sandisk公司出产的eMMC,moviNand是三星公司出产的eMMC,EMMC是NANDFLASH+主控IC,对外接口类似
                            于SD卡/TF卡
oneNAND                    oneNand是三星公司出的一种Nand
SD卡/TF卡/MMC卡             
eSSD                       嵌入式SSD

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

X210开发板支持的外部存储器
X210有两个版本,NAND和iNAND版,分别使用NANDFLASH和iNAND(eMMC)为外部存储器。我们是哦那个的是iNand,板载4GB iNAND
S5PV210共支持4个SD/MMC通道,其中通道0和2依次用作启动。X210开发板中的SD/MMC0通道用于连接板载MMC,因此外部启动时只能使用SD/MMC2通道(注意通道3不能启动)。
总结:    
    现代SoC支持多种外部存储器
    外部存储器只要用来存储程序(可执行代码),相当于电脑的硬盘。
    各种不同外部存储器原理不同,大小,性价比不同,一般产品厂家根据需要选择适合自己产品的外存使用。
    外部存储器和CPU连接一般不是通过地址&数据总线直接相连,因为地址空间不够用。一般都是通过专门的接口来连接的。
9.S5PV210的启动过程
内存:
    SRAM  静态内存    容量小,价格高,优点是不需要软件初始化直接上电就能用
    DRAM  动态内存       容量大,价格低,缺点是上电后不能直接使用,需要软件初始化后才能使用
    单片机中:      内存需求量小,而且希望开发尽可能简单,适合全部用SRAM
    嵌入式系统:    内存需求量大,而且没有NorFlash等可启动介质
    PC机:          内存需求量大,而且软件复杂,不在乎DRAM的初始化开销,适合全用DRAM
外存:
    NorFlash    :特点是容量小,价格高,优点是可以直接和CPU总线式连接,CPU上电后可以直接读取,所以一般用作启动介质
    NandFlash   :跟硬盘一样,特点是容量大,价格低,缺点是不能总线式访问,也就是说不能上电CPU直接读取,需要CPU先运行一些初始化软件,然后通过时序接口读写。
所以一般PC机都是:很小容量的BIOS(NorFlash)+很大容量的硬盘(类似于NANDFLASH)+大容量DRAM  ,BIOS同时初始化NANDFLASH和DRAM
一般的单片机:   很小容量的NorFlash + 很小容量的SRAM
嵌入式系统:     因为NORFLSH很贵,所以现在很多嵌入式系统倾向于不用NORFLASH,直接用:外接大容量NAND+外界大容量DRAM+ SOC内置SRAM
S5PV210使用的启动方式是: 外接大容量NAND+外界大容量DRAM+ SOC内置SRAM
210内置了一块96KB大小的SRAM(iRAM),通古斯还有一块内置的64KB的NorFlash(iROM).
210的启动过程大致是:
    第一步:CPU上电后先从内部IROM中读取预先设置的代码(BL0),执行。这一段IROM代码做了一些基本的初始化(CPU时钟,关看门狗。。。)
            (这一段IROM代码是三星出厂前设置的,三星也不知道我们板子上将来接的是什么样的DRAM,因此这一段IROM是不能负责初始化外界的DRAM的,因此这一段代码只初始化    SoC内部的东西);然后这一段代码会判断我们选择的启动模式(我们通过硬件跳线可以更改板子的启动模式),
            然后从相应的外部存储器去读取第一部分启动代码BL1到内部SRAM()。
    第二步:从SRAM去运行刚上一步读取来的BL1(16KB),然后执行.BL1负责初始化NANDFLASH,然后将BL2读取到IRAM(剩余80KB),然后运行。
    第三步:从IRAM运行BL2,BL2初始化DRAM,然后将OS读取到DRAM,然后启动OS,启动过程结束。

    思路:因为启动代码的大小是不定的,有些公司可能96KB就够了,有些公司可能1MB都不够。所以刚才说的2步的启动方式不适合.
    三星的解决方案是:把启动代码分为2半(BL1和BL2),这两部分协同工作来完成启动。
iROM和iRAM
    S5PV210出厂时内置了64KB iROM和96KB iRAM.iROM中预先内置烧录了一些代码(iROM代码),iRAM属于SRAM(不需软件初始化,上电即可使用)。210启动时首先在内部运行iROM代码,然后由iROM代码开启外部启动流程。
为什么需要设计iROM和iRAM? 
    答案是为了支持多种外部设备启动。
使用iROM启动的好处:
    降低BOM成本。因为iROM可以使SOC从各种外设启动,因此可以省下一块boot rom(专门用来启动的rom,一般是norflash)
    支持各种校验类型的nand
    可以在不使用编程器的情况下使用一种外部存储器运行程序来给另一种外部存储器编程烧录。这样生产时就不用额外购买专用编程器了,降低了量产成本。
BL0做了什么?  在irom内部
    关看门狗
    初始化指令cache
    初始化栈
    初始化堆
    初始化块设备的复制函数
    初始化PLL和设置SoC时钟系统
    复制BL1到内部的SRAM
    检查BL1的校验和
    检查是否时安全启动
    跳转到BL1启动
wakeup status   唤醒状态/
上电irom里面的bl0运行,加载BL1到SRAM执行,加载BL2到SRAM执行初始化DRAM,加载OS到DRAM执行,正常运转。
S5PV210的所有启动
    先1st启动,通过OMpin选择启动介质
    再2nd启动,从SD2
    再UART启动
    再USB启动

1.2.12 ARM的编程模式和七种模式
ARM采用的是32位架构
ARM约定:
    -Byte :8 bits
    -Halfword: 16 bits(2 byte)
    -Word:     32 bits(4 byte)
大部分的ARM CORE提供:
    -ARM指令集(32 bit)
    -Thumb指令集 16-bit
    -Thunb2指令集 16&32 bit
ARM处理器工作模式
    -User:非特权模式,大部分任务执行在此模式
    -FIQ:当一个高优先级FAST中断产生时将会进入这种模式‘
    -IRQ:当一个低优先级中断产生时将会进入这种模式
    -Supervisor:当复位或者软中断指令执行时将会进入这种模式
    -Abort:当存取异常时将会进入这种模式
    -Undef:当执行未定义指令时将会进入这种模式
    -System:使用和USER模式相同寄存器的特权模式
注意:
    除USER模式是normal模式外,其他六种都是Privilege特权模式
    Privilege中除了Sys模式外,其余五种为异常模式
    各种模式的切换,可以是程序员通过代码主动切换(CPSR寄存器);也可以是CPU在某些情况下完成自动切换
    各种模式下权限和可以访问的寄存器不同
CPU为什么要设计这些模式?
    CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件需要,便于实现软件特性。
    操作系统有安全级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要。
 1.1.13 ARM的37个寄存器详解
    ARM总共有37个寄存器,但是每种模式下最多智能看见18个寄存器,其他寄存器虽然名字相同,但是当前模式不可见。
    对于r14这个名字来说,在ARM中共有6个名叫r14(又叫sp)的寄存器,但是在每种特定处理器模式下,只有一个r14是当前可见的,其他的r14必须切换
    到他对应的模式下才能看到,这种设计叫影子寄存器(banked register)
总结:
    ARM共有37个寄存器,都是32位长度。
    37个寄存器中的30个为“通用型”,1个固定用作PC,一个固定用作CPSR,5个固定用作5种异常模式下的SPSR。
    CPSR程序状态寄存器
    ARM处理器两种状态ARM状态和thumb状态
    CPSR寄存器中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E和CPSR中的Z标志位有关)
    CPSR中的I,F和开中断,关中断有关
    CPSR中的Mode位决定了CPU的工作模式,在uboot代码中会使用汇编进行设置。
    PC(r15)程序控制寄存器
    PC为程序指针,PC指向哪里,CPU就会执行哪条指令(所以程序跳转时就是把目标地址代码放到PC中)
    整个CPU中只有一个PC(CPSR也只有一个,但是SPSR有5个)。

1.2.14 ARM的异常处理方式简单介绍
什么是异常?
    正常工作之外的流程都叫异常
    异常会打断正在执行的工作,并且一般我们希望异常处理完成后继续回来执行原来的工作
    中断是异常的一种
    
    -User:非特权模式,大部分任务执行在此模式                   正常工作模式
    
    -FIQ:当一个高优先级FAST中断产生时将会进入这种模式‘
    -IRQ:当一个低优先级中断产生时将会进入这种模式
    -Supervisor:当复位或者软中断指令执行时将会进入这种模式      中断

    -Abort:当存取异常时将会进入这种模式
    -Undef:当执行未定义指令时将会进入这种模式                  异常
    
    -System:使用和USER模式相同寄存器的特权模式                  正常工作模式
    
    
    异步的      靠中断(一种特殊的异常)来实现
    同步的        同步时钟

    所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的。
    当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作)
    异常向量表是硬件向软件提供的处理异常的支持。
ARM的异常处理机制
    当异常产生时,ARM核
        拷贝CPSR到SPSR
        设置适当的CPSR位:
            改变处理器状态进入ARM态
            改变处理器模式进入相应的异常模式
            设置中断禁止位禁止相应中断
        保存返回地址到LR
        设置PC为相应的异常向量
    返回时,异常处理需要
        从SPSR恢复CPSR
        从LR恢复PC
        NOTE:这些操作只能在ARM态,Thumb状态无法处理异常
总结:
    异常处理中有一些是硬件自动做的,有一些是程序员需要自己做的。需要搞清楚哪些是需要自己做的,才知道如何写代码。
    以上说的是CPU设计时提供的异常向量表,一般称为一级向量表。有些CPU为了支持多个中断,还会提供二级中断向量表,处理
    类似于这里说的一级向量表。

1.2.15  ARM汇编指令集1
学习是一个先模仿后创新的过程
指令和伪指令
    汇编指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由CPU读取执行。
    汇编伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令
    最终不会生成机器码。
两种不同风格的ARM指令
    ARM官方的ARM汇编风格:指令一般用大些,WINDOWS中IDE开发环境(如ADS,MDK等)常用.如:LDR R0,[R1]
    GNU风格的ARM汇编:指令一般用小写字母,linux中常用。如:ldr r0,[r1]
ARM汇编特点:LDR/STR架构
    ARM采用RISC架构,CPU本身不能直接读取内存,而需要先将内存中内容加载入CPU中通用寄存器才能被CPU处理
    ldr(load register)指令将内存内容加载入通用寄存器
    str(store register)指令将寄存器内容存入内存空间中
    ldr/str组合用来实现ARM CPU和内存数据交换
ARM汇编特点2::8种寻址方式
    寄存器寻址:    mov r1,r2                   将r2的值赋给r1
    立即寻址:      mov r0,#0xFF00                将0xFF00赋给r0,#表示数
    寄存器移位寻址:mov r0,r1,lsl #3            将r1左移3位的值赋给r0.左移3位表示乘以8
    寄存器间接寻址:ldr r1,[r2]                 r2里面存的是内存地址,将内存地址里面的值赋给r1
    基址变址寻址:  ldr r1,[r2,#4]              在r2的地址里面加4的地址里面的值赋给r1
    多寄存器寻址:  ldmia r1!,{r2-r7,r12}       弹栈操作
    堆栈寻址:      stmfd sp!,{r2-r7,lr}        堆栈操作

    相对寻址:         beq flag
                    flag:
ARM汇编特点3:指令后缀
    同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:
    B(byte)功能不变,操作长度变为8位。
    H(Half word)功能不变 ,长度变为16位。
    S(signed)功能不变,操作数变为有符号
    如ldr ldrb ldrh ldrsb ldrsh
    S(S标志)功能不变,影响CPSR标志位
    如mov和movs     mov r0,#0 
ARM汇编特点4:条件执行后缀
mov r0,r1    @相当于C语言中的r0=r1
moveq r0,r1  @如果eq后缀成立,则直接执行mov r0,r1;如果eq不成立则本句代码直接作废,相当于没有
             @类似于C语言中的if (eq){r0 =r1;}
条件后缀执行注意2点:
1.条件后缀是否成立,不是取决于本本句代码,而是取决于这句代码之前的代码运行后的结果
2.条件后缀决定了本句代码是否被执行,而不会影响上一句和下一句代码是否被执行。
ARM汇编特点5:  多级指令流水线
    为增加处理器指令流的速度,ARM使用多级流水线,下图为3级流水线工作原理示意图。(S5PV210使用13级流水线,ARM11为8级)
    允许多个操作同时处理,而非顺序执行。

1.2.17   ARM汇编指令集3
常用ARM指令1:数据传输指令   
mov(move)   mov r1,r0    @两个寄存器之间数据传递
            mov r1,#0xff  @将立即数赋值给寄存器
mvn和mov用法一样,区别是mov是原封不动的传递,mvn是按位取反后传递
譬如r1=0x000000ff,然后mov r0,r1 后,r0=0x000000ff,但是 mvn r0,r1后,r0=0xffffff00

算数运算指令
add
sub
rsb
adc
sbc
rsc

逻辑指令
and    逻辑与
orr    逻辑或
eor    逻辑异或(结果不相等结果为真,相等的话结果为假)

位清除指令
bic    bic r0,r1,#0x1f   0x0000001f   @将r1中的数的bit0到bit4清0后赋值给r0

比较指令
cmp    cmp r0,r1   等价于 sub r2,r0,r1(r2=r0-r1)
cmn    cmn r0,r1   等价于 add r0,r1
tst       tst r0,#0xf   测试bit3是否为8
teq       
比较指令用来比较两个寄存器中的数
注意:比较指令不用后加s后缀就可以影响cpsr中的标志位

乘法指令
mvl
mla
umull
umlal
smull
smlal

前导零计数
clz

常用ARM指令2:cpsr访问指令
cpsr和spsr的区别和联系:
    cpsr是程序状态寄存器,整个soc中只有一个;
    而spsr有五个,分别在五中异常模式下,作用是当从普通模式进入异常模式时,用来保存之前普通模式下的cpsr的,以在返回普通模式时恢复原来的
    cpsr
mrs&msr
mrs用来读psr,msr用来写psr
CPSR寄存器比较特殊,需要专门的指令
    
常用ARM指令3:跳转(分支)指令
b&bl&bx
    b:直接跳转
    bl:branch and link ,跳转前把返回地址放入lr中,以便返回,以便用于函数调用
    bx:跳转同时切换到ARM模式,一般用于异常处理的跳转。

常用ARM指令4:访存指令
ldr/str & ldm/stm &swp
单个字/半字/字节访问  ldr/str
多字批量访问 ldm/stm
swp r1,r2,[r0]       把将r0作为内存地址的内容读取到r1,再将r2中的值存放到r0作为内存地址 ,边读边写
swp r1,r1,[r0]       寄存器和内存交换内容

ARM汇编中的立即数
合法立即数与非法立即数    
    ARM指令都是32位的,除了指令标记和操作标记外,本身智能附带很少位数的立即数。因此立即数有合法和非法之分。
    合法立即数:经过任意位数的移位后非零部分可以用8位表示的即为合法立即数。
    
常用ARM指令5:软中断指令
swi:
软中断指令用来实现操作系统中系统调用


1.2.18  ARM汇编指令集4
mcr&mrc
mrc用于读取CP15中的寄存器
mcr用于写入CP15中的寄存器

什么是协处理器?
    SOC内部另一处理核心,协助CPU实现某些功能,被主CPU调用执行一定任务。
    ARM设计上支持多达16个协处理器,但是一般SOC只实现其中的CP15(CP15就是协处理器的意思)
    协处理器和MMU,cache,TLB等处理有关,功能上和操作系统的虚拟地址映射、cache管理等有关。
协处理器学习要点
    不必深究,将UBOOT中和KERNEL中起始代码的一般操作搞明白即可
    只看一般用法,不详细区分参数细节,否则会陷入很多复杂未知中
    关键在于理解,而不在于记住

1.2.19 ARM汇编指令集5
为什么需要多寄存器访问指令
ldr/str每周期只能访问4字节内存,如果需要批量读取、写入内存时太慢,解决方案是stm/ldm
ldm(load register mutiple)
stm(store register mutiple)
stmia sp,{r0-r12} :将r0存入sp指向的内存处(假如为0x30001000);然后地址+4(即指向0x30001004),将r1存入该地址;直到将r12内容放入,指令完成
一个访问周期同时完成13个寄存器的读写。

8种后缀
-ia   先传输,再地址加4   
-ib   先地址+4,再传输
-da   先传输,再地址-4
-db   先地址-4,再传输
-fd   满递减堆栈
-ed   空递减堆栈
-fa   满递增堆栈
-ea   空递增堆栈

四种栈
    空栈:栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格;而取出时需要先移动一格才能取出
    满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;取出时可以直接取出,然后再移动指针
    增栈:栈指针移动时向地址增加的方向移动的栈
    减栈:栈指针移动时向地址减小的方向移动的栈
!的作用
    ldmia r2,{r2-r3}
    ldmia r2!,{r2-r3}
    感叹号的作用就是r0的值在ldm过程中发生的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值
^的作用 
    ldmfd sp!,{r0-r6,pc}
    ldmfd sp!,{r0-r6,pc}^
    在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于异常模式返回
总结:批量读取或写入内存时需要用到ldm/stm指令
      各种后缀以理解为主,不需要记忆,最常见的是stmia和stmfd,ARM默认使用满减栈
     谨记:操作栈时使用相同的后缀就不会出错,不管是满栈还是空栈,增栈还是减栈
    
1.2.20 ARM汇编伪指令
伪指令不是指令,伪指令和指令的根本区别是经过编译之后会不会生成机器码
伪指令的意义在于指导编译过程
伪指令和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令

gnu汇编中的一些符号
@注释
#注释
:以冒号结尾的是标号
. 点号在gnu汇编中表示当前指令的地址
# 立即数前面要加#或者$,表示这是个立即数

常见的gnu伪指令
.global_start   @给_start外部链接属性
.section .text  @指定当前段为代码段
.ascii .byte .short .long .word .quad .float .string @定义数据
.align 4  @以16字节对齐  2*2*2*2
.align 2  @以4字节对齐  2*2
.balignl 16 0xabcdefgh    @16字节对齐+填充    b表示位   l表示long,以四字节为单位填充   16表示16字节对齐  0xdeaddddd是用来填充的原料
.equ   @类似于C中宏定义    

偶尔用到的gnu伪指令
.end                           @标识文件结束
.include                       @头文件包含
.arm/.code32                   @中等范围的地址加载指令
.thumb/.code 16                @空操作

经常用到的伪指令
ldr     大范围的地址加载指令
adr     小范围的地址加载指令
adrl    中等范围的地址加载指令
nop     空操作
ARM中有一个ldr指令,还有一个ldr伪指令
一般都使用ldr伪指令而不使用ldr指令

ldr指令:   ldr r0,#0xff
伪指令:    ldr r0,=0xff1     @设计到合法立即数和非法立即数   涉及到ARM文字池

adr与ldr
adr编译时会被1条sub或者add指令替代,而ldr编译时会被一条mov指令替代或者文字池方式处理
adr总是以PC为基准来表示地址,因此之灵本身和运行地址有关,可以用来检测程序当前的运行地址在哪里
ldr加载的地址和链接时给定的地址有关,由链接脚本决定
adr和ldr的区别:ldr加载的地址在链接时确定,而adr加载的地址在程序运行时

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值