一、ARM架构简介
- ARM(Advanced RISC Machine)是一种基于RISC(精简指令集计算机)原理的计算机处理器架构。
1.ARM寄存器组
- ARM处理器有16个通用寄存器 (R0-R15),(严格来说,R0到R12是通用寄存器)其中每个寄存器都可以存储一个32位的数据。
- 寄存器并不直接映射到内存地址,因此它们没有特定的内存地址。寄存器是CPU内部的硬件资源,与内存不同,它们不需要通过内存地址访问。具体图为
- R0~R12:通用寄存器,用于各种用途,包括传递参数、存储临时数据等。它们都可以用于任何用途,只不过存在一些惯用约定。
- R13(SP、Stack Pointer):栈指针寄存器,指向当前栈顶
- 在函数调用 、局部变量存储 和中断处理时使用。
- R14(LR、Link Register):链接寄存器,用于存储函数调用的返回地址 。
- 在使用BL指令调用子程序时,返回地址会存储在LR中。
- 在子程序结束时,将LR的值加载到PC以返回调用点。
- R15(PC,Program Counter)是程序计数器,存储当前指令的下一条指令的地址。
- 每次指令执行后,PC自动更新以指向下一条指令。
- 修改PC的值可以实现跳转 和函数调用。
- CPSR(Current Program Status Register):当前程序状态寄存器,存储 当前处理器状态,包括条件标志、中断禁用位、处理器模式等。
- SPSR (Saved Program Status Register): 保存程序状态寄存器,在异常处理时保存CPSR的值,以便异常处理完成后恢复处理器状态。
2.寄存器的保存和恢复
- 在嵌套的函数调用中,特别是当函数使用了R4-R11寄存器时,通常需要在进入函数时保存这些寄存器的值,并在函数返回前恢复它们
- 代码实例
matlab
save_registers:
PUSH {R4-R11} // 保存R4到R11的值到栈中
BL some_function // 调用子函数
POP {R4-R11} // 恢复R4到R11的值
MOV PC, LR // 返回到调用点
matlab
--入栈
PUSH {LR} // 保存链接寄存器
PUSH {R4-R6} // 保存R4到R6寄存器
SUB SP, SP, #12 // 为局部变量分配空间(假设3个局部变量,每个4字节)
--返回
ADD SP, SP, #12 // 释放局部变量的空间
POP {R4-R6} // 恢复R4到R6寄存器
POP {LR} // 恢复链接寄存器
--如下图
二、RISC(Reduced Instruction Set Computer)特点
1.简单且统一的指令集
- 指令集简单:RISC处理器使用少量的简单指令,每条指令通常在一个时钟周期内完成。这与CISC(复杂指令集计算机)处理器的复杂多时钟周期指令形成对比。
- 固定长度的指令:有助于简化指令解码和流水线处理。
2.大量通用寄存器
- 寄存器优先:RISC架构通常包含大量的通用寄存器,以减少对内存操作的依赖。大多数操作是在寄存器之间进行的,而不是在内存和寄存器之间。
- 减少内存访问,从而提高了性能。
3. 单周期指令执行
- 每条指令一个时钟周期:大多数RISC指令在一个时钟周期内完成,使得处理器能够更快地执行指令。
- 简化的控制逻辑:由于指令的执行时间一致,RISC处理器的控制逻辑比CISC处理器更简单。
4.硬件流水线
- 流水线技术 :RISC处理器广泛使用指令流水线,通过将指令的执行过程分解为多个阶段(如取指、解码、执行、访存、写回),使得多个指令可以并行处理,从而提高了指令吞吐量。
- 优化的流水线设计:RISC架构设计注重优化流水线效率,减少流水线停顿和数据冒险。
5. 加载/存储架构
- Load/Store架构:RISC处理器采用加载/存储(Load/Store)架构,只有特定的加载和存储指令可以访问内存。LDR和STR
6.指令并行级
- 指令并行执行:RISC架构设计强调指令级并行性,通过优化编译器和处理器设计,尽可能地并行执行指令。
- 延迟槽:一些RISC处理器(如MIPS)使用延迟槽技术,在跳转指令之后执行一条指令,以提高流水线效率。
7. 简化的寻址模式
- 有限的寻址模式:常见的RISC寻址模式包括立即数寻址、寄存器间接寻址和基址加偏移寻址。
8.优缺点
- 优点:高性能,低功耗,易于实现和扩展
- 缺点:代码密度较低,对编译器依赖程度较高
三、一些零散知识点
- ARM指令集
指令长度:ARM指令集中的每条指令长度为32位,即4个字节,一行就是ARM指令
指令对齐:ARM指令需要4字节对齐,因为每条指令在内存中都占据4字节。
1.一些常用的伪指令
.bss 伪指令
未初始化数据段:.bss 用于定义未初始化数据段,用于存放程序中未初始化的全局变量。
.data 伪指令
数据段定义:.data 用于定义数据段,在此之后的部分通常包含程序使用的静态数据或初始化数据。
.text 伪指令
指示从此开始的部分是可执行代码。
.end 伪指令
标记汇编代码的结束。
在汇编语言中采用@注释
2.LDR和STR指令一些常见用法
- LDR指令用于从内存中加载数据到寄存器中。这是一条将数据从内存复制到寄存器的指令。
matlab
<----------
LDR R0,[R1] @将R1指向的内存地址加载数据到R0中。
LDR R0, =0x1000 @ 将立即数0x1000加载到R0
@使用=符号表示将一个立即数加载到寄存器中,这实际上在汇编过程中生成了一条伪指令。
LDR R0, [R1, #4] @ 从R1指向的地址加上偏移4处加载数据到R0
LDR R0, [R1, R2] @ 从R1加上R2的地址处加载数据到R0,允许偏移量由另一个寄存器提供
- STR指令用于将寄存器中的数据存储到内存中。这是一条将数据从寄存器写入内存的指令。
matlab
------------->
STR R0, [R1] @将R0中的数据存储到R1指向的内存地址
STR R0, [R1, #8] @将R0中的数据存储到R1加8的内存地址
STR R0, [R1, R2] @将R0中的数据存储到R1加R2的内存地址,允许偏移量由另一个寄存器提供