ARM体系结构简介

ARM 版本号问题

在这里插入图片描述

ARM 是 RISC 架构:
  • 常用ARM汇编指令只有二三十条
  • ARM是低功耗的CPU
  • ARM的架构非常适合单片机、嵌入式、尤其是物联网领域;而服务器等高性能领域主导还是Intel
ARM是IO与内存统一编址的
  • 大部分ARM(M0 M3 M4 M7 ARM9 ARM11 A8 A9)都是32架构
  • 32位ARM CPU支持的内存少于4G,通过CPU地址总线来访问
  • SOC中的各个内部外设通过各自的SFR编程访问,这些SFR的访问方式类似于访问普通内存,这叫IO与内存统一编址
ARM是哈佛结构的
  • 常见ARM(除ARM7外)都是哈佛结构的
  • 哈佛机构保证了ARM CPU运行的稳定性和安全性,因此ARM适用于嵌入式领域
  • 哈佛结构也决定了ARM裸机程序(使用实地址即物理地址)的连接比较麻烦,必须使用复杂的连接脚本告知连接器如何组织程序;对于OS之上的应用(工作在虚拟地址之中)则不需要考虑这么多
ARM的基本设定:
  • ARM 采用的是32位架构
  • ARM 约定:
    Byte :8bits Halfword:16bits(2byte) Word:32bits(4byte)
  • 大部分ARM core提供
    ARM指令集(32-bits) Thumb指令集(16-bits) Thumb指令集(16 & 32bits)
ARM 处理器工作模式(必须看哦!)

ARM 有7个基本工作模式:

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

注意:

  • 除User(用户模式)是Normal(普通模式)外,其它6种都是privilege(特权模式)
  • Privilege中除Sys模式外,其余5种为异常模式
  • 各种模式的切换(CPSR),可以是程序员通过代码主动切换(通过写CPSR寄存器);也可以是CPU在某些情况下自动切换
  • 各种模式下权限和可以访问的寄存器不同。

CPU为什么设计这些模式

  • CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件的需要,便于实现软件特性
  • 操作系统有安全级别级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要
ARM的37个寄存器详解(必须看哦!)

在这里插入图片描述

  • ARM 共有37个寄存器,都是32位长度
  • 37个寄存器中30个为通用型,1个固定用作PC,一个固定用作CPSR(切换CPU工作模式),5个固定用作异常模式下的SPSR(保存之前普通模式下的CPSR,以便返回)

r13(sp) 栈指针寄存器
堆栈式一段按照后进先出原则组织起来的连续存储区域。用于程序保存或恢复数据,或用于子程序调用及中断响应时保护与恢复现场。sp是堆栈指针寄存器,存放着当前堆栈栈顶地址

r14(lr) 寄存器
**子程序的返回地址:**从子程序返回后,主程序继续执行的指令的地址称为子程序的返回地址
LR也叫链接寄存器,用于存放子程序的返回地址。在要进入子程序之前,先将子程序的返回地址存入LR

PC (r15)程序控制寄存器
PC 为程序指针,PC指向哪里,CPU就会执行哪条指令(所以跳转时就是把目标地址代码放到PC中)

CPSR,程序状态寄存器,important
在这里插入图片描述在这里插入图片描述

  • CPSR中各个bit位表明了CPU的某些信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E就和CPSR中的z标志位有关)
  • CPSR中的I、F位和开中断、关中断有关
  • CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置

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

ARM指令
#ARM采用RISC架构,CPU本身不能直接读取内存,而需要先将内存中内容加载CPU的通用寄存器后才能被CPU处理
ldr   将内容从内存搬到通用寄存器load register
str   将内容从通用寄存器搬到内存store register
ldr/str组合实现ARM CPU和内存数据交换


#ARM 寻址方式
mov r1,r2 		 	寄存器寻址
mov r0,#0xFF00  	立即寻址
mov r0,r1,lsl #3 	寄存器移位寻址
ldr	r1,[r2,#4] 		基址变址寻址
ldmia r1!,{r2~r7,r12} 多寄存器寻址
stmfd sp!,{r2-r7,lr}  堆栈寻址


#ARM 指令后缀,同一个指令附带不同后缀,变成不同的指令
B(byte)功能不变,操作长度为8位
H(half word)功能不变,操作长度为16位
S(signed)功能不变,操作数变为有符号
	ldr ldrb ldrh ldrsb ldrsh
S(S标志)功能不变,影响CPSR标志位


#ARM 条件执行后缀
moveq r0, r1 @ 如果 eq 后缀成立,则直接执行 mov r0, r1
条件后缀是否成立,不是取决于本句代码,而是取决于这句代码之前的代码运行后的结果。
条件后缀决定了本句代码是否被执行,而不会影响上一句和下一句代码是否被执行


#ARM 多级指令流水线
为了增加处理器的指令流的速度,ARM使用多级流水线
不同arm架构会有所不同


#ARM 数据传输和跳转指令
① 数据处理指令:
mov mvn 数据传输指令
add sub rsb adc sbc rsc 逻辑指令
and orr eor bic 逻辑指令
cmp cmn tst teq 比较指令
mvl mla umull umlal smull smlal 乘法指令
clz 前导零计数

② cpsr 访问指令
mrs / msr 	
mrs 用来读cpsr msr用来写cpsr
cpsr寄存器比较特殊,需要专门的指令访问

③ 跳转(分支)指令
b / bl / bx
-b  直接跳转
-bl 跳转前把返回地址放入lr中,以便返回branch and link
-bx 跳转同时切换到ARM模式,一般用于异常处理的跳转

④ 访存指令
ldr / str &   ldm / stm & swp
单个字/半字/字节访问 ldr/str
多字批量访问 ldm/stm

⑤ 软中断指令
swi(software interrupt) 软中断指令用来实现操作系统中系统调用

ARM协处理器和协处理器指令

什么是协处理器

  • SoC内部另一处理器核心,协助主CPU实现某些功能,被主CPU调用执行一定任务
  • ARM设计上支持多达16个协处理器马,但是一般SoC实现其中的CP15(cp:coprocessor)
  • 协处理器和MMU、cache、TLB等处理有关,功能上和操作系统的虚拟地址映射、cache管理有关

协处理器cp15操作指令

mcr & mrc

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

MRC & MCR的使用方法
mcr{<cond>} p15,<opcode_1>,<Rd>,<Crn>,<Crm>,{<opcode_2>}
- opcode_1:对于 cp15 永远为 0
- Rd:ARM 的普通寄存器
- Crn:cp15 的寄存器,合法值是 c0~c15
- Crm:cp15 的寄存器,一般均设为 c0
- opcode_2:一般省略或为 0

mrc p15,0,r0,c1,c0,0
orr r0,r0,#1
mcr p15,0,r0,c1,c0,0
  • 不必深究,将uboot中的kernel中起始代码中的一般操作搞明白即可
  • 只看一般用法,不必详细区分参数细节,否则掉坑
  • 不必死记硬背,理解即可
ldm / stm 与栈处理
#r举例子
- ldr / str每周期只能访问4字节内存,如果需要批量读取、写入内存时太慢,就用ldm / stm
- ldm load multiple
- stm store register multiple

stmia sp,{r0-r12}
将r0存入sp指向的内存处(假设为0x30001000)
然后地址+4(指向0x30001004),将r1存入该地址
然后地址+4(指向0x30001008),将r2存入该地址,。。。。。。。。。直到存完

#uu一个访存周期同时完成 13 个寄存器的读写uu
8 种后缀:
ia(increase after)先传输,再地址+4 
ib(increase before)先地址+4,再传输 
da(decrease after)先传输,再地址-4 
db(decrease before)先地址-4,再传输 
fd(full decrease)满递减堆栈,即一开始指向栈满的一下个可用位置 
ed(empty decrease)空递减堆栈 
fa(·······) 满递增堆栈 
ea(·······)空递增堆栈

#i四种栈
空栈:栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格;
				    而取出时需要先移动一格才能取出
满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;
					取出时可以直接取出,然后再移动指栈指针
增栈:栈指针移动时向地址增加的方向移动的栈
减栈:栈指针移动时向地址减小的方向移动的栈
ARM汇编伪指令

伪指令的意义

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

gnu汇编中伪指令符号

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

常用 gnu 伪指令

  • .global _start @ 给_start 外部链接属性
  • .section .text @ 指定当前段为代码段
  • .ascii .byte .short .long .word
  • .quad .float .string @ 定义数据
  • .align 4 @ 以 16 字节对齐
  • .balignl 16 0xabcdefgh @ 16 字节对齐填充
  • .equ @ 类似于 C 中宏定义

偶尔会用到的 gnu 伪指令

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

最重要的几个伪指令

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

adr 和 ldr 的差别:ldr 加载的地址在链接时确定,而 adr 加载的地址在运行时确定;所以我们可以通过 adr 和 ldr 加载的地址比较来判断当前程序是否在链接时指定的地址运行。

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栋哥爱做饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值