ARM基本知识

ARM 内核版本号

  • ARM一款微处理器
  • ARMv7(ARM version 7):ARM的第七版本

ARM soc版本号

  • ARMv7对应的soc版本号:Cortex-M、Cortex-A、Cortex-R。
  • M:microcontriller微控制器,就是单片机
  • A:application利用级处理器,就是手机、平板、电脑的CPU
  • R:realtime实时处理器,响应速度快,用于工业等畛域

SoC和CPU

  • SoC:System on Chip,零碎级芯片,外部蕴含CPU并且内置了其余外设。
  • CPU:Central Processing Unit,中央处理器,一块超大规模的集成电路。
  • 当初所说的CPU和芯片其实都是SoC。

嵌入式与单片机

  • 单片机平台:51、PIC、STM32、AVR等
  • 嵌入式平台:ARM、PPC、MIPS等
  • 单片机上资源无限、价格低、应用领域多为小家电等。
  • 嵌入式零碎片上资源丰盛、价格较高、应用领域宽泛、例如智能手机/平板/游戏机/摄像机等。

嵌入式零碎特点

  • 专用、软硬件可裁剪可配置。
  • 低功耗、高可靠性、高稳定性。
  • 软件代码短小精悍。
  • 代码可固化(代码能够烧录到硬件中,且断电后不失落)
  • 实时性。
  • 弱交互性。
  • 专用开发工具及开发环境。

嵌入式零碎的组成

  • 硬件组成:微处理器、存储器、I/O接口、输入输出设施等
  • 软件组成:

    • 嵌入式操作系统
    • BSP(board support package板级反对包)
    • 应用软件

穿插编译

  • 非嵌入式开发模式:A类操作系统机型编写源代码,编译失去可执行程序,公布给A类操作系统机型运行(机型可能变过,然而操作系统没变)
  • 嵌入式开发:A类机型编写程序,编译失去可执行程序,公布给B类操作系统机型运行(操作系统变了,例如Windows和Linux)
  • 嵌入式开发环境的CPU比拟简答,自身无奈搭建开发环境,有的甚至操作系统都没有,所以要应用穿插编译。
  • 穿插编译能够用高性能机为低性能机开发软件。
  • 穿插编译特点:

    • 必须应用专用的穿插编译工具链。
    • 因为可执行程序不能本地运行调试,因而必须配合肯定伎俩将可执行程序加载到指标嵌入式设施上运行及调试(JTAG调试器、USB下载等)

地址总线和数据总线

  • CPU通过地址总线寻址,而后通过数据总线与外部设备交互信息。
  • 地址总线位数决定CPU寻址范畴。
  • 数据总线位数决定CPU单次通信能替换的信息数量。
  • 总线的速度决定CPU与外设交互信息的速度。
  • CPU地址总线的位数和数据总线的位数是能够不雷同的,但个别都雷同。
  • CPU的位数是指数据总线的位数。

ARM体系结构与汇编指令

可编程器件的特点

  • CPU在固定频率的时钟管制下有节奏的运行。
  • CPU能够通过总线读取内部存储设备中的二进制指令集,而后解码执行。
  • 这些能够被CPU解码执行的二进制指令集是CPU设计时就确定了的,实质上是一串由1和0组成的数字,这就是CPU的汇编指令集。

汇编语言

  • 汇编语言就是CPU的机器指令集的助记符,是一款CPU的本质特征。
  • 不同CPU的机器指令集设计不同,因而汇编程序不能在不同CPU之间互相移植。
  • 汇编编程效率高响应快,因而在操作系统内核中效率极其重要处都须要用汇编语言编写。

RISC和CISC

  • CISC:complex instruction set computer 简单指令集CPU。
  • CISC体系的设计理念是用起码的指令来实现工作,因而CISC的CPU自身设计简单、工艺简单,但益处是编译器好设计。
  • RISC:reduced instruction set conputer 精简指令集CPU。
  • RISC体系的设计理念是让软件来实现具体任务,CPU自身只提供基本功能指令集。

对立编址/独立编址

  • 内存:内存是程序的运行场合,内存和CPU之间通过总线连贯,CPU通过肯定的地址来拜访具体的内存单元。
  • IO:指输入输出接口,是CPU和其余外部设备之间的通信路线,个别说的IO指的就是CPU的各种外部或内部外设。
  • 内存的拜访形式:内存通过CPU的地址总线来寻址定位,而后通过CPU的数据总线传输数据。
  • IO的拜访形式:

    * 对立编址:用相似于拜访内存的形式,即把外设的寄存器当作一个内存地址来读写,从而以拜访内存的形式来操作外设,这叫IO与内存对立编址。* 独立编址:应用专用的CPU指令来拜访某种特定外设,这叫IO与内存独立编址。

哈佛构造/冯诺依曼结构

  • 程序和数据

    • 程序运行时有两大元素:程序+数据。
    • 程序是咱们写好的源代码通过编译、汇编之后失去的机器码,这些机器码能够拿给CPU去解码执行,CPU也不会去批改程序,所以程序是只读的。
    • 数据是程序运行过程中定义和产生的变量的值,是能够读写的,程序运行理论就是为了扭转数据的值。
  • 哈佛构造:程序和数据离开独立放在不同的内存块中,彼此齐全拆散的构造

    • 程序个别放在ROM和flash,数据个别放在RAM中。
    • 劣势:平安和稳定性高。
    • 劣势:软件解决简单,须要统一规划链接地址等。
  • 冯诺依曼结构:程序和数据都放在内存中,且彼此不拆散的构造

    • 劣势:解决起来简略。
    • 劣势:平安和稳定性低

寄存器

  • 寄存器:是软件管制硬件的要害,是外部设备的硬件组成部分。
  • 寄存器就相当于外设硬件的软件接口API,应用软件编程管制某一硬件,本质就是编程读写该硬件的寄存器。
  • 寄存器中每个bit位都有特定含意,因而编程时须要位操作。
  • 编程操作寄存器相似与拜访内存。
  • SoC中有两类寄存器

    • 通用寄存器:ARM中有37个,是CPU的组成部分。
    • SFR非凡性能寄存器:不在CPU中,存在于CPU的外设中,通过拜访外设的SFR来编程管制这个外设,这就是硬件编程管制的办法。

地址映射

  • 为了保障CPU执行指令时可正确拜访存储单元,需将用户程序中的逻辑地址转换为运行时由机器间接寻址的物理地址,这一过程称为地址映射。也就是说咱们常说的内存中某个地址0x0fffffff其实是理论内存中某个地址的代名词。

内存与外存

  • 内存:

    • SRAM:动态内存,毛病是容量小、价格高,长处是不须要软件初始化间接上电就能用。
    • DRAM:动态内存,长处是容量大、价格低,毛病是上电后不能间接应用,须要软件初始化。
  • 单片机中:内存需要小,且心愿开发更简略,适宜全用SRAM。
  • 嵌入式零碎中:内存需要大,而且没有NorFlash等启动介质(个别是NandFlash+DRAM+SoC内置的SRAM)
  • PC机中:内存需要大,而且软件简单,不在乎DRAM的初始化开销,适宜全用DRAM。
  • 外存:

    • NorFlash:毛病是容量小、价格高,长处是能够和CPU间接总线式相连,CPU上电后能够间接读取,所以个别罕用作启动介质。
    • NandFlash:跟硬盘一样,容量大、价格低,毛病是不能总线式拜访,也就是说上电后CPU不能间接读取,须要CPU先运行一些初始化软件,而后通过时序接口读写。

ARM的7种工作模式

  • User:非特权模式,大部分工作执行在这种模式下。
  • FIQ:当一个高优先级中断产生时将会进入这种模式。
  • IRQ:当一个低优先级中断产生时将会进入这种模式。
  • Supervisor:当复位或软件中断指令执行时将会进入这种模式。
  • Abort:当存取异样时将会进入这种模式。
  • Undef:当执行未定义指令时将会进入这种模式。
  • System:应用和User模式雷同寄存器集的特权模式。
  • 各种模式下权限和能够拜访的寄存器是不同的。
  • 除了User是一般模式外,其余都是特权模式。
  • 操作系统有安全级别要求,因而设计多种模式是为了不便操作系统的多种角色安全等级须要。

ARM的寄存器

  • ARM总共有37个寄存器。
  • 寄存器的应用与ARM的工作模式相干,每种模式下最多只能看到18个寄存器。
  • 例如:对于r14这个寄存器,在ARM中有6个寄存器是同样的名字,然而在每种特定的模式下只能看到其中一个,其它的r14寄存器必须切换模式后能力看到。
    • 切换模式后,以User寄存器为根底(彩色局部),会用备用寄存器替换以后可见寄存器中的同名寄存器。(图中就是切换到Abort模式时,看到的寄存器)

ARM的异样解决形式

  • 什么是异样:失常工作之外的流程都叫异样,异样会打断正在执行的工作,并且个别咱们心愿异样解决完后继续执行之前的工作,中断也是异样的一种。
  • 异样向量表:所以的CPU都有异样向量表,是由硬件决定的。当产生异样时,CPU会主动动作(PC跳转到异样向量处解决异样,有时还伴有一些辅助动作),异样向量表是硬件向软件提供的解决异样的反对。

ARM汇编指令集

指令与伪指令

  • 汇编指令:是指CPU机器指令的助记符,记功编译后能够失去一串由1和0组成的机器码,能够由CPU读取执行。
  • 汇编伪指令:其本质上不是指令,只是和指令一起写在代码中,它是编译环境提供的用来领导编译过程,通过编译后伪指令不会生成机器码。

ARM汇编指令集

  • ARM采纳RISC架构,CPU自身不能间接读取内存,须要先将内存中内容加载如CPU的通用寄存器中能力被CPU解决。

    • ldr指令:将内存中内容加载入通用寄存器。
    • str指令:将寄存器内容存入内存空间。
    • ldr/str组合实现ARM的CPU和内存的数据交换。
  • ARM反对8种寻址形式

    • 寄存器寻址:mov r1, r2(把r2的值赋给r1)
    • 立刻数寻址:mov r0,#0xFF00(把xff00这个数立刻赋给r0)
    • 寄存器移位寻址:mov r0,r1,lsl #3(r1左移3位,再赋给r0,lsl是左移符)
    • 寄存器间接寻址:ldr r1,[r2]
    • 基址变址寻址:ldr r1,[r2,#4]
    • 多寄存器寻址:ldmia r1!,{r2-r7,r12}
    • 堆栈寻址:stmfd sp!,[r2-r7,r12,lr]
    • 绝对寻址:flag1 :beq flag2 (在汇编代码中,在flag1中应用绝对寻址时,程序会跳转到flag2处去执行)
  • 指令后缀

    • 同一指令常常附带不同的后缀,变成不同的指令。
    • B(byte):性能不变,操作长度变为8位。
    • H(half word):性能不变,操作长度变为16位。
    • S(signed):性能不变,操作数变为有符号数。
    • 例如:ldr、ldrb、ldrh、ldrsh、ldrsb
    • S(S标记):性能不变,影响CPSR标记位。
    • 例如:mov、movs
  • 条件指令后缀

    • 例如:moveq r0,r1 (如果eq后缀条件成立,则执行mov r0,r1;如果不成立则作废)
    • 条件后缀是否成立,不是取决于本句代码,而是取决于之前的代码运行后的后果。

数据处理指令

  • 数据传输指令:mov、mvn

    • mov r1,r0 :将r0寄存器中的值一成不变的传递给r1
    • mvn r1,r0 :将r0寄存器中的值按位取反后传递给r1
  • 算数指令:add加、sub减、rsb、adc、sbc、rsc
  • 逻辑指令:and与、orr或、eor异或、bic

    • bic :位革除指令
    • bic r0,r1,#0x1f :将r1中的值的bit0位到bit4清零后赋值给r0,分明前面那个数中为一的那些位。
  • 比拟指令:cmp、cmn、tst、teq

    • 比拟指令不必加S后缀就能够影响cpsr中的标记位。
    • cmp :与负数相比拟
    • cmn :与正数相比拟
    • tst :检测某位是否为零;tst r0,#0x08 ;检测bit3位是否为零。
    • teq :测试等价
  • 乘法指令:mvl、mla、umull、umlal、smull、smlal
  • 前导零计数:clz (计算一个数后面有多少个0)

cpsr拜访指令

  • cpsr寄存器较为非凡,不能用mov指令拜访,须要专门的指令。
  • cpsr寄存器是程序状态寄存器,整个SoC中只有一个。
  • spsr寄存器在SoC中有5个,别离在5中异样模式下,作用是当从一般模式进入异样模式时,用来保留之前一般模式下的cpsr,以便在返回一般模式时复原原来的cpsr。
  • mrs指令:用来读psr寄存器。
  • msr指令:用来写psr寄存器。

跳转指令

  • b :间接跳转
  • bl :跳转前把返回地址放入lr中,以便返回,个别用于函数调用。
  • bx :跳转的同时切换到ARM模式,个别用于异样解决的跳转。

访存指令

  • 字节拜访:ldr/str
  • 多字节批量拜访:ldm/stm
  • swp指令:

    • swp r1,r2,[r0] 将r0地址中内容读到r1中,再将r2中内容读到r0地址中

软中断指令

  • swi (software interrupt):用软件来产生中断,实现操作系统中零碎调用。

协处理器CP15操作指令

  • 协处理器:SoC外部另一解决外围,帮助主CPU实现某些性能,被主CPU调用执行肯定的工作。
  • ARM设计上反对多达16个协处理器,但个别SoC只实现其中的CP15(总共是CP0--CP15)
  • CPU中的寄存器都是以r结尾,协处理器中的寄存器都是以c结尾。
  • mrc :用于读取CP15中的寄存器。
  • mcr :用于写入CP15中的寄存器。

多字节批量拜访

  • ldm :读取存储器内容到寄存器中
  • stm :将寄存器中值写入存储器中
  • 例如 :

    • stmia sp,{r0-r12}
    • 将r0存入sp所指向的内存处,而后地址加4,再将r1存入该地址,而后地址再加4,始终到r12内容放入内存处,指令实现。
  • 感叹号的作用:将内存中运算后的值返回到寄存器中。

    • ldmia sp!,{r0-r12}
    • 读取sp指向的地址到r0-r12中,每读一次,地址会+4,然而sp所指向的地址没有产生扭转,加上!号后,会将减少的地址返回到sp中,使sp指向新的地址。
  • ^ 符号的作用:在指标寄存器中有pc时才起作用,将spsr中的内容写入cpsr中

    • 例如:ldmfd sp!,{r0-r6,pc}^
    • 读取sp指向的地址到r0-r6和pc寄存器中,同时将spsr中的内容写入cpsr中。
  • 8中后缀:

    • ia :先传输,后地址+4。
    • ib :先地址+4,后传输。
    • da :先传输,后地址-4。
    • db :先地址-4,后传输。
    • fd :满递加堆栈(ARM中默认应用满减栈)
    • ed :空递加堆栈
    • fa :满递增堆栈
    • ea :空递增堆栈

  • 空栈:栈指针指向空位,每次入栈时都能够间接存入,而后指针挪动一格,而出栈时须要先挪动一格能力取出。
  • 满栈:栈指针指向栈中最初一格数据,入栈时须要指针先挪动一格再存入,出栈时能够间接取出,而后再挪动一格。
  • 增栈:栈指针挪动时向地址减少的方向挪动的栈。
  • 减栈:栈指针挪动时向地址缩小的方向挪动的栈。
  • 操作栈时尽量应用雷同后缀,不容易出错。

ARM伪指令

  • @符号:用来做正文,能够在首行也能够在代码前面,和C语言的//正文符类型。
  • 符号:用来做正文,个别放在首行,示意这一行都是正文而不是代码。

  • .符号:在gnu汇编中示意以后指令的地址。
  • /$符号:立刻数后面加#号或$号示意这是个立刻数。

  • :符号:在gnu汇编中以冒号结尾的,示意这是个标号,不是指令。
  • .global符号:.global _start 申明_start为内部链接属性(在别的文件也能够拜访_satrt)
  • .section符号:指定以后段为代码段。
  • 定义数据的符号:

    • .ascii 定义字符长度
    • .byte 定义字节长度
    • .shour 定义两个字节长度
    • .long 定义四个字节长度
    • .word 定义四个字节长度(一个字)
    • 例如 a:
    • .word 0xffffffff @示意a = 0xffffffff
    • .quad 定义双字,8个字节
    • .float 定义浮点型
    • .string 定义字符串
  • .align 4 以16字节对齐
  • .align 2 以4字节对齐
  • .balignl 16,0xabcdefgh @b示意位填充,align示意对齐,l示意long以四字节填充,16示意16字节对齐,0xabcdefgh是用来填充的原料。
  • .equ 相似于C语言的宏定义。
  • ldr 大范畴的地址加载指令
  • adr 小范畴的地址加载指令
  • adrl 中等范畴的地址加载指令
  • nop 空操作