ARM IMX6ULL 基础学习记录 / ARM 寄存器介绍

编辑整理 by Staok

本文大部分内容摘自"100ask imx6ull"开发板的配套资料(如《IMX6ULL裸机开发完全手册》等等),侵删。进行了精髓提取,方便日后查阅。过于基础的内容不会在此提及。如有错误恭谢指出!

注:在 Github 上的原版文章日后可能会更新,在其它位置发的不会跟进。文章的 Gitee 仓库地址,Gitee 访问更流畅


ARM & Linux 相关

p.s 汇编基本指令和 ARM 的汇编启动代码看 "ARM异常处理 及其模板" 文件夹里的 startup.s 文件。

cpsr 寄存器详情

运行模式

Cortex-A7架构的运行模式有9种。运行模式可以通过软件进行任意切换,也可以通过中断或者异常来进行切换。大多数的程序都运行在用户模式,用户模式下是不能访问系统所有资源的,有些资源是受限的,要想访问这些受限的资源就必须进行模式切换。但是用户模式是不能直接进行切换的,用户模式下需要借助异常来完成模式切换,当要切换模式的时候,应用程序可以产生异常,在异常的处理过程中完成处理器模式切换。

模式 描述
User 用户模式,非特权模式,大部分程序运行的时候就处于此模式
Sys(System) 系统模式,用于运行特权级的操作系统任务
FIQ 快速中断模式,进入 FIQ 中断异常
IRQ 一般中断模式
ABT(Abort) 数据访问终止模式,用于虚拟存储以及存储保护
SVC(Supervisor) 超级管理员模式,供操作系统使用
UND(Undef) 未定义指令终止模式
MON(Monitor) 用于安全扩展模式
Hyp 用于虚拟化扩展

几点说明:

  • 板子上电时,CPU处于SVC模式,它用的是SVC模式下的寄存器。

  • 程序运行时发生了中断,CPU进入IRQ模式,它用的IRQ模式下的寄存器。

  • CPU发生某种异常时,比如读取内存出错,它会进入ABT模式,使用ABT模式下的寄存器来处理错误。

每一种模式对应使用的寄存器

几点说明:

  • 如果某个程序处于 FIQ 模式下访问寄存器 R13(SP),那它实际访问的是寄存器 SP_fiq。

  • 如果某个程序处于 SVC 模式下访问寄存器 R13(SP),那它实际访问的是寄存器 SP_svc。

  • 除了 FIQ 模式,寄存器 R0~R12 都是通用的,即模式之间切换前这些寄存器的值应该保存。

  • 假如某个ARM处理器是三级流水线:取指->译码->执行,循环执行,那么程序计数器 R15(PC) = 当前执行指令地址 + 4 * 2 个字节。

  • 未定义指令异常的个别用法:在某些系统中,代码可能包含用于协处理器(例如VFP协处理器)的指令,但是系统中不存在相应的VFP硬件。另外,VFP硬件有可能无法处理特定指令,而是想调用软件来对其进行模拟。或者,可能会禁用VFP硬件,采用异常处理,以便可以启用它,然后重新执行指令。使用未定义的指令,可以实现一些仿真器(软件模拟硬件的实现)。比如在你的芯片中,它并未支持某条硬件除法指令,但是你还可以在代码中使用它。当CPU执行这条指令时会发生异常,在异常处理函数中,你用软件来实现该指令的功能。对于不是特别设置的未定义指令,在异常处理函数中不能处理它时,通常做法是记录适当的调试信息,并关掉(kill)对应的应用程序。在某些情况下,未定义指令异常的另一个用途是实现用户断点:调试器(如gdb)去修改代码,替换断点位置的指令为一条未定义指令。

  • SVC异常的个别用法:软中断 swi 指令可以触发此异常,获得 SVC 权限。在Linux中对文件的open/read/write等APP层的系统函数,它的本质都是执行SVC指令,从而进入Linux内核中预设的SVC异常处理函数,在内核里操作文件。可以使用寄存器或者操作码中某个字段将参数传递给SVC处理程序。

程序状态寄存器 cpsr

所有运行模式都共用一个 CPSR 物理存在的寄存器叫 程序状态寄存器,CPSR 可以在任何模式下被访问。当特定异常中断发生时,备份程序状态寄存器 SPSR 用来保存 CPSR 的值,当异常退出以后可以用 SPSR 中保存的值来恢复 CPSR。

各个位的说明:

  • N(bit31):当两个有符号整数(补码表示)运算时,结果用N表示,N=1/0 表示 负数/正数。

  • Z(bit30):对于 CMP 指令,Z=1 表示进行比较的两个数大小相等。

  • C(bit29):

    • 在加法指令中,当结果产生了进位,则C=1,表示无符号数运算发生上溢,其它情况下 C=0;

    • 在减法指令中,当运算中发生借位,则C=0,表示无符号数运算发生下溢,其它情况下 C=1;

    • 对于包含移位操作的非加/减法运算指令,C 中包含最后一次溢出的位的数值;

    • 对于其它非加/减运算指令,C 位的值通常不受影响。

  • V(bit28):对于加/减法运算指令,当操作数和运算结果表示为二进制的补码表示的带符号数时,V=1 表示符号位溢出,通常其他位不影响 V 位。

  • Q(bit27):仅 ARM v5TE_J 架构支持,表示饱和状态,Q=1/0 表示累积饱和/累积不饱和。

  • IT[1:0] (bit26:25) 和 IT[7:2] (bit15:bit10)一起组成 IT[7:0],作为 IF-THEN 指令执行状态。

  • J(bit24) 和 T(bit5):控制指令执行状态,表明本指令是ARM指令还是Thumb指令。{J,T} = b00 为 ARM;= b01 为 Thumb;= b11 为 ThumbEE;= b10 为 Jazelle。

  • GE[3:0] (bit19:16):SIMD(单指令多数据,处理器为提升并行操作的一种功能) 指令有效,大于或等于。

  • E(bit9):大小端控制位,E=1/0 表示大/小端模式。

  • A(bit8):禁止异步中断位,A=1 表示禁止异步中断。

  • I(bit7):I=1/0 代表 禁止/使能 IRQ。

  • F(bit6):F=1/0 代表 禁止/使能 FIQ。

  • M[4:0]:运行模式控制位,如表

    M[4:0] 运行模式
    10000 User 模式
    10001 FIQ 模式
    10010 IRQ 模式
    10011 Supervisor(SVC)模式
    10110 Monitor(MON)模式
    10111 Abort(ABT)模式
    11010 Hyp(HYP)模式
    11011 Undef(UND)模式
    11111 System(SYS)模式

在用户模式下,无法改变处理器模式的M位[4:0]来切换模式和A,I和F位来使能或者禁止异步中止、IRQ和FIQ。

大小端模式

  • 大端模式(Big-endian),是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。

  • 小端模式(Little-endian),是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

相关推荐
legend_jz1 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
Komorebi.py2 分钟前
【Linux】-学习笔记04
linux·笔记·学习
weiabc1 小时前
学习electron
javascript·学习·electron
HackKong2 小时前
小白怎样入门网络安全?
网络·学习·安全·web安全·网络安全·黑客
Bald Baby2 小时前
JWT的使用
java·笔记·学习·servlet
心怀梦想的咸鱼3 小时前
UE5 第一人称射击项目学习(四)
学习·ue5
AI完全体3 小时前
【AI日记】24.11.22 学习谷歌数据分析初级课程-第2/3课
学习·数据分析
Mephisto.java3 小时前
【大数据学习 | Spark-Core】Spark提交及运行流程
大数据·学习·spark
PandaCave4 小时前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
yuwinter4 小时前
鸿蒙HarmonyOS学习笔记(2)
笔记·学习·harmonyos