ARM学习笔记
ARM系列芯片
- Cortex - A
特点:Cortex-A核是ARM架构中的应用处理器核。它通常用于高性能计算和通用操作系统的执行,如Android、Linux等。Cortex-A核具有多级流水线、超标量执行、乱序执行等高级特性,使其能够高效处理多线程和多任务。
应用场景:Cortex-A核广泛应用于智能手机、平板电脑、服务器、网络设备、物联网网关等需要高性能和通用计算的领域 - Cortex - R
特点:Cortex-R核是ARM架构中的嵌入式实时处理器核。它专注于实时性能和可预测性,适用于处理实时控制任务,如汽车电子、工业控制、嵌入式系统等。Cortex-R核具有低延迟、高吞吐量和硬实时性能。
应用场景:Cortex-R核广泛用于汽车电子控制器、工业自动化、无线通信基站、嵌入式控制系统等需要实时响应和可靠性的领域。 - Cortex - M
特点:Cortex-M核是ARM架构中的微控制器处理器核。它专注于低功耗、紧凑尺寸和实时控制,适用于小型嵌入式系统。Cortex-M核通常具有单一周期执行、中断处理能力和低功耗模式。
应用场景:Cortex-M核广泛应用于微控制器(MCU)、传感器节点、物联网设备、嵌入式传感器、医疗设备等需要低功耗和实时控制的领域。
异同点: - 性能差异:Cortex-A核具有最高的性能,适合处理复杂的计算任务。Cortex-R核次之,专注于实时性能。Cortex-M核性能最低,专注于低功耗。 - 架构特性:Cortex-A核通常具有高级特性,如乱序执行,用于通用计算。Cortex-R核和Cortex-M核注重实时性能和可预测性,通常采用顺序执行。 - 功耗特性:Cortex-A核通常功耗较高,适用于设备拥有足够电源和散热能力的场景。Cortex-R核和Cortex-M核注重功耗效率,适用于电池供电或低功耗要求的设备。 - 应用领域:Cortex-A核适用于高性能计算、通用操作系统和复杂应用。Cortex-R核适用于实时控制领域。Cortex-M核适用于小型嵌入式系统和低功耗设备。
Core-A 内核体系
- 指令集 -> 编译
- 寄存器
- ARM汇编
- cache
- mmo 片外内存
- 链接协议
ARM 内容大纲 www.arm.com
- ARM架构和处理器
- 工具、操作系统和开发板
- ARM寄存器、数据类型、模式和指令集
- ARM汇编语言
- SIMD和NEON
- ARM缓存(Caches)架构
- 内存管理单元
- 中断处理(Interrupt Handling)
- 异常处理(Exception Handling)
- 启动代码
- 多处理器结构
哈弗结构和普林顿结构
- 冯诺依曼结构
冯诺依曼结构也称为普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。其特点包括:
(1)一般用于PC处理器。
(2)指令与数据存储器合并在一起。
(3)指令与数据都通过相同的数据总线传输。 - 哈佛结构
哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。哈佛结构是一种并行体系结构,它的主要特点是将程序和数据存储在不同的存储空间中,即程序存储器和数据存储器是两个独立的存储器,每个存储器独立编址、独立访问。其特点包括:
(1)一般用于嵌入式系统处理器(DSP)。
(2)指令与数据分开存储,可以并行读取,有较高数据的吞吐率。
(3)有4条总线,包括指令和数据的数据总线和地址总线。
工具
-
QEMU
QEMU是一套由法布里斯·贝拉(Fabrice Bellard)所编写的以GPL许可证分发源码的模拟处理器软件,在GNU/Linux平台上使用广泛。Bochs,PearPC等与其类似,但不具备其许多特性,比如高速度及跨平台的特性,通过KQEMU这个闭源的加速器,QEMU能模拟至接近真实电脑的速度。 -
BusyBox
BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Linux 系统的自带的shell。 -
Scratchbox
-
U-Boot
Das U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC、ARM、AVR32、MIPS、x86、68k、Nios与MicroBlaze。这也是一套在GNU通用公共许可证之自由软件。下发布的Das U-Boot可以在x86计算机上建构,但这部x86计算机必须安装有可支持特定平台结构的交互发展GNU工具链,例如crosstool、Embedded Linux Development Kit (ELDK)或OSELAS.Toolchain。 -
UEFI and Tianocore
统一可扩展固件接口(英语:Unified Extensible Firmware Interface,缩写UEFI)是一种个人电脑系统规格,用来定义操作系统与系统固件之间的软件界面,作为BIOS的替代方案。可扩展固件接口负责加电自检(POST)、联系操作系统以及提供连接操作系统与硬件的接口。
ARM工具链
编译过程
1、编译,由编译器将c源代码(.cpp)转变成汇编代码(.s)
2、汇编,由汇编器将汇编代码(.s)转变成目标代码(.o)
3、链接,由链接器将代码在执行过程用到的其他目标代码和库文件链接成为一个可执行程序也就是目标程序。
其他工具
ARM Compile Tollchain
CPU的组成
CPU的组成
处理器一般指中央处理器,中央处理器(CPU,Central Processing Unit)是一块超大规模集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。大多数现代电路设计都是用信号线上的高电压和低电压来表示不同的位值。
要实现一个数字系统需要三个主要的组成部分:
- 计算对位进行操作的函数的组合逻辑(ALU);·
- 存储位的存储器元素(寄存器);
- 控制存储器元素更新的时钟信号。
处理器模式
USER、FIQ、IRQ、SVC、MON、ABT、HYP、UND、SYS
寄存器组
Cortex-M3和Cortex-M4处理器(ARM架构)用于数据处理与控制的寄存器组中有16个寄存器,其中13个(R0 ~ R12)为通用目的寄存器,另外三个具有特殊用途
R0 ~ R12
寄存器R0 ~ R12为通用目的寄存器,其中前8个(R0 ~ R7)也被称作低寄存器,由于指令中可用的空间有限,许多16位指令只能访问低寄存器。而其它寄存器(R8 ~ R12)被称为高寄存器,可用于32位指令和部分16位指令,如MOV。
R0 ~ R12的初始值是未定义的。
R13
R13为栈指针(SP),设置该指针的值后可通过PUSH和POP指令访问栈。
物理上存在两个栈指针:
1.主栈指针(MSP,有些ARM文献也称其为SP_main)为默认的栈指针,在复位后或处理器处于处理模式时该指针被处理器选择使用。
2.进程栈指针(PSP,有些ARM文献也称其为SP_ process),只用于线程模式。
栈指针的选择由特殊寄存器CONTROL决定。对于一般的程序,这两个寄存器(即MSP和PSP两个寄存器)只有一个可见。
MSP和PSP都是32位寄存器,但最低两位固定为0。对于 ARM Cortex-M处理器,PUSH和POP指令总是32位的,栈操作的地址也必须对齐到32位的字边界上。
注:大多情况下,若不需要使用嵌入式OS则没必要使用PSP。许多简单的应用可以完全依赖MSP。一般在用到嵌入式OS时才会使用PSP,此时OS内核同应用任务的栈是相互独立的。PSP的初始值未定义,而MSP的初始值则需要在复位流程中从存储器的第一个字中取出。
R14
R14为链接寄存器(LR),用于保存函数或子程序调用时返回地址。
在函数或子程序结束时,程序将LR的数值加载至程序计数器(PC)中返回调用程序处并继续执行(也就是跳转回上层函数)。
当执行了函数或子程序调用后,LR的数值会自动更新。若某函数调用另外一个函数或子程序,则需要将LR的数值保存在栈中,否则,函数执行后,LR的当前值会丢失(函数嵌套必须将对应的上层函数地址保存在栈中)。
在异常处理期间,LR自动更新为特殊的EXC_RETURN(异常返回)数值,以在异常处理结束时触发异常返回。
R15
R15为程序计数器(PC),可读写寄存器,读操作返回当前指令地址加4(由于设计的流水线特性及同ARM7 TDMI处理器兼容的需要)。写操作(例如,使用数据传输/处理指令)产生程序跳转。
由于指令必须对齐到长度(半字或字),PC的最低位(LSB)为0。但使用部分跳转/读存储器指令更新PC时,需要将PC值的LSB置1表示 Thumb状态,否则就会由于试图使用不支持的ARM指令(如ARM7TDMI中的32位ARM指令)而触发错误异常。高级编程语言(包括C和C+)编译器会自动将跳转目标的LSB置位。
多数情况下,跳转和调用由专门的指令实现。访问位于程序存储器中的字符数据时,PC的数值非常有用,因此存储器读操作经常将PC作为基地址寄存器,并通过指令中的立即数生成偏移地址。
寄存器
1,R0-R12通用寄存器,放通用数据,32bit
2,各个模式的RO-R12与USR模式是共享的 (除了FIQ,R8-R12),PC,CPSR共享的
3,USR模式没有SPSR
SP-栈指针,存储栈地址
LR-链接寄存器,存储子程序返回地址
PC-程序计数器
APSR/CPSR-应用程序状态寄存器/当前程序状态寄存器
SPSR-已存储程序状态寄存器
指令集流水pipeLine
指令分解过程
分解指令过程
- 指令预读取(决定从内存哪儿取指令).PerFetch
- 指令读取(从内存系统中读取指令).Fetch
- 指令译码(解读指令并且生成控制信号).
- 寄存器读取(提供寄存器的值给操作单元).
- 分配(分配指令给执行单元)
- 执行(实际的ALU单元处理).
- 内存访问(数据的存取).
- 寄存器回写(更新运行结果到寄存器).
简而言之:程序 = 数据结构 + 算法
汇编局限于平台
向寄存器中一个值添加100
x86: add eax, #100
68K: ADD #100.D0
ARM: add r0, r0, 100
从一个寄存器指针加载到寄存器
x86: mov eax, DWORD PTR [ebx]
68K: MOVE.L (A0), D0
ARM: Idr r0, [r1]
arm起始代码
AREA Example,CODE,READONLY
ENTRY
CODE32
START
MOV RO, #1
MOV RO, #0
END
ARM汇编指令格式
Operation{cond}{s} Rd, Rn, Operand2
Cond
Status
左移 = 乘以2的n次方
右移 = 除以2的n次方
ARM中有效立即数:立即数整除4能够在 0 - 255之间。
寻址方式
- 立即数寻址
ADD RO,R0, #0x3F - 寄存器寻址
ADD RO,R1,R2 - 寄存器间接寻址
LDR RO.[R1]
STR R0,[R1] - 寄存器移位寻址
ADD R3,R2,R1,LSL #2 - 基址地址寻址
LDR RO,[R1,#4]
LDR RO [R1] #4
LDR RO,[R1,R2] - 多寄存器寻址
LDMIA RO, R1,R2,R3,R4} - 相对寻址
BL NEXT
MOV PC.LR
ARM堆栈
熟悉以下几个概念,以后用的上:
满堆栈
空堆栈
递增堆栈
递减堆栈
数据操作(ALU操作)
数学操作
逻辑操作
关于逻辑运算-与,或,非,异或
逻辑运算主要包括三种基本运算:
逻辑加法("或"运算)、
逻辑乘法("与"运算)
逻辑否定(又称"非"运算)
此外,"异或"运算也很有用
内存操作
多寄存器内访问指令
大小端存储模式
大端存储模式 - 大端存储模式是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。这种方式类似于把数据当作字符串顺序处理。
小端存储模式 - 小端存储模式是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
eg:数据12345678的存储
内存地址 | 小端模式存放内容 | 大端存放内容 |
---|---|---|
0x4000 | 0x78 | 0x12 |
0x4001 | 0x56 | 0x34 |
0x4000 | 0x34 | 0x56 |
0x4000 | 0x12 | 0x78 |
汇编读取数据
汇编读取地址的值时,按照一个字(32 bit )的大小来进行内存划分,具体看地址属于哪个字里面。一般对寄存器的操作是按照字长进行操作
eg:32位芯片,小端模式
LDR R0,[R1,#0x14]
LDR R2,[R3,#0x19]
解析
读取地址为0x00000014段的数据。从图上可以看到0x00000014地址段的内容是[00 e8 00 e8],小端模式所以 R0的值等于0xE8 00 E8 00
读取地址为0x00000019段的数据。从图上可以看到0x00000019地址段的内容是[10 00 ff e7],小端模式所以 R0的值等于0x10 e7 ff 00
跳转,状态操作
异常产生指令
- B上下32个字节跳转,mov 任意字节跳转
PC寄存器的作用
PC(Program Counter,程序计数器)寄存器是计算机CPU内部用于存储当前执行的指令地址的寄存器。它的作用是记录当前正在执行的指令的位置,以便CPU在执行指令时能够准确地跳转到该指令。PC寄存器是计算机程序中的重要组成部分,它的正确使用能够提高程序的执行效率和稳定性。
在计算机程序中,当CPU从内存中读取指令时,它会将指令地址存储在PC寄存器中。然后,CPU会执行指令,并根据指令的内容和执行结果来更新PC寄存器的值。这样,CPU就能够准确地跳转到下一条指令,从而执行程序的逻辑。如果CPU在执行指令时发生了中断或异常,它会将PC寄存器的值保存下来,以便在恢复执行时能够跳转回中断或异常发生的位置。
总之,PC寄存器在计算机程序中扮演着非常重要的角色。它的正确使用可以提高程序的执行效率和稳定性,同时也能够保证计算机系统的稳定性和可靠性。在现代计算机体系结构中,PC寄存器是不可缺少的组成部分。
伪指令作用及类别
我们的指令已经可以做各类操作了,但我们操作起来太麻烦了。
比如我现在要设置一个值给寄存器R0,但下次我修改了寄存器R0之后又需要读出来刚才的值,那我们就要先临时保存值到SPSR or CPSR,然后不断切换。
再比如,我们要做一个循环,就要用label结合BL不断进行,但如果我们要循环很多次。
我们就定义了一些类似于带参数的宏的操作一样,来定义我们的伪指令,方便我们更好的实现汇编程序逻辑。伪指令只是在汇编器之前作用,汇编之后会翻译为标准的汇编指令集。
我们又分为ARM汇编伪指令和GNU汇编伪指令
符号命名约定
一 符号区分大小写,同名的大、小写符号会被编译器认为是两个不不同的符号
一 符号在其作用范围内必须唯一。
一 自定义的符号名不能与系统的保留字相同。
一 符号名不应与指令或伪指令同名
一 关于ADS里面可恶的Tab和项行"ADS Style"
符号,变量
存储在内存中
常量
- 数字常里一般为32位的整数,当作为无符号数时,其取值范国为0-2的32次方 - 1,当作为有符号数时,其取值范围为-2的31次方-2的31次方 - 1。
- 逻辑常重只有两种取值情况:真或假。
- 字符串常里为一个固定的字符串,一般用于程序运行时的信息提示
变量代换$
程序中的变量可通过代换操作取得一个常量。代换操作符为"$"
Sample
LCLS S1
LCLS S2
S1 SETS “Test! "
S2 SETS “This is a $S1”;字符串变量S2的值为"This is a Test!”
表达式和运算符
- “+”、“-”、“x”、"/"及"MOD"算术运算符
- “ROL”、“ROR”、"SHL"及"SHR"移位运算符
- “AND”、“OR”、"NOT"及"EOR"按位逻辑运算:符
逻辑表达式及运算符
- “=” , “>” ,“<” ,“>=”, “<=”, “/=”, "<>"运算符
- “LAND”、“LOR”、"LNOT"及"LEOR"运算符