ARM 工作模式及寄存器 电脑版发表于:2024/6/17 0:11 ![](https://img.tnblog.net/arcimg/hb/6930d1439f4b43e785a433685b813262.png) >#ARM 工作模式及寄存器 [TOC] 简单的计算机工作原理 ------------ ![](https://img.tnblog.net/arcimg/hb/6a0f355e5f324b2085eb614c894f8d30.png) ### CPU tn2>CPU是计算机的核心部分,用于执行程序指令。它包含以下几个主要组件: | 组件名 | 描述 | | ------------ | ------------ | | 控制器 | 负责从内存中获取指令,解释指令,并控制其他几个部分执行指令。 | | ALU(算数逻辑单元) | 负责执行算数和逻辑运算,比如加法、减法、比较等。 | | 寄存器 | 用于临时存储数据和指令,图中显示了两个寄存器r0和r1 | ### FLASH(闪存) tn2>FLASH存储是一种非易失性存储器,用于存储固件、操作系统和应用程序。 在图中显示了几个指令存储在FLASH中:<br/> `mov r0,#1`:将数值1加载到r0寄存器中。 `add r1,r0,#1`:将r0中的值加1,并将结果存储到寄存器r1中。 `cmp r1,#0`:将寄存器r1中的值与0进行比较。<br/> 内存傍边记录了三条指令的 ### 内存 tn2>内存(RAM)是易失性存储器,用于临时存储正在运行的程序和数据。CPU从内存中读取数据和指令,并将计算结果写回内存。 ### 总线 tn2>总线是连接CPU、内存和FLASH存储器的通信通道。它们通过总线进行数据传输和指令传递。总线确保各个组件可以协调工作,进行数据交换。 ARM处理器的工作模式 ------------ ![](https://img.tnblog.net/arcimg/hb/512181c8eb2d46a485da3d655ad6dbcb.png) tn2>三角的是ARM下独有的空间,如果切换模式同样会被改变。 | 模式 | 描述 | | ------------ | ------------ | | `User(用户模式)` | 非特权模式,大部分普通任务在这个模式下执行。 | | `FIQ(快速中断模式)` | 处理高优先级的快速中断。| | `IRQ(普通中断模式)` | 处理一般优先级的中断。 | | `Supervisor(监控模式)` | 系统启动或发生软中断时进入的模式。 | | `Abort(异常中止模式)` | 当发生异常中止时进入这个模式。 | | `Undefined(未定义指令模式)` | 当执行未定义指令时进入这个模式。 | | `System(系统模式)` | 与用户模式类似,但有更高的权限。 | ### 硬件中断 tn2>硬件中断由硬件设备(如键盘、鼠标、网络卡等)发出,用于通知处理器需要立即处理的事件。 举例:键盘中断、定时器中断、网络中断 ### 软件中断 tn2>软件中断是由软件程序发出的,用于请求操作系统提供的服务或处理某些异常情况。 举例:系统调用、异常处理 tn>FIQ(快速中断)在ARM处理器中具有比IRQ(普通中断)更高的优先级。 ### ARM寄存器结构 tn2>ARM有37个寄存器,包括: 1个程序计数器(PC,Program Counter) 1个当前程序状态寄存器(CPSR,Current Program Status Register) 5个保存的程序状态寄存器(SPSR,Saved Program Status Registers) 30个通用寄存器 ### 特殊的几个寄存器 tn2>R13(SP,Stack Pointer):堆栈指针寄存器,用于指向当前堆栈顶。 R14(LR,Link Register):连接寄存器,用于保存子程序返回地址。 R15(PC,Program Counter):程序计数器,指向当前执行的指令。 ### 简单实践 ```bash .text b main nop b back nop nop nop nop nop main: mov r0,#3 mov r4,#5 mov r0,#3 back: add r0,#7 mov r1,r0 swi 3 mov r3,#4 loop: b back .end ``` ![](https://img.tnblog.net/arcimg/hb/33f17ec1dfe14720a3915ec4cbc2f994.png) tn2>`0x00000000`是地址。 `EA000006`是机器码。 这里的`b main`表示跳转到`main`方法里面。 `0x00000020`就是`main`的位置。 ![](https://img.tnblog.net/arcimg/hb/ca8754324bab43f4b792e070c31c731f.png) tn2>`R15(PC)`记录的是下一条执行指令的位置。 ![](https://img.tnblog.net/arcimg/hb/adeef5b3194e47f9904469f7577c28f8.png) tn2>`mov r0,#3`表示将3的值赋给`r0`寄存器,下面的几条指令是相同的操作。 ![](https://img.tnblog.net/arcimg/hb/82458907b5684b32a88833cdfed5669d.png) tn2>`add r0,#7`然后`add`指令表示加法加上7结果值也就是10,16进制也就是A。 `mov r1,r0`将`r0`的值复制给`r1` ![](https://img.tnblog.net/arcimg/hb/81b11de4bef84e3c8f7e8cb5a4db3325.png) ![](https://img.tnblog.net/arcimg/hb/1f76185bf87e4e8fb461efa74bdb04b7.png) tn2>`swi 3`触发一个软中断指令。 执行后发现`Supervisor`里面的值被触发了,切换到了`Supervisor`模式 ![](https://img.tnblog.net/arcimg/hb/09a02c2cea9c4d09b93972d9df97c498.png) CPSR寄存器 ------------ ![](https://img.tnblog.net/arcimg/hb/d1688e6e055849108ac0f78eb4d6a5c7.png) ![](https://img.tnblog.net/arcimg/hb/564405409e6147d4996ba22589d244ba.png) tn2>这两张图为我们呈现了CPSR寄存器字段。 ### 条件位 tn2>`N`(Negative result from ALU):表示最近一次ALU操作的结果是负数。 `Z`(Zero result from ALU):表示最近一次ALU操作的结果是零。 `C`(ALU operation Carried out or borrow):表示最近一次ALU操作有进位或借位。 `V`(ALU operation oVerflowed):表示最近一次ALU操作发生溢出。 ### T位和J位 tn2>`T`位(Thumb状态位):决定处理器是工作在ARM状态(T=0)还是Thumb状态(T=1)。 Thumb状态是ARM处理器的一种工作模式,使用更紧凑的指令集。 `J`位(Jazelle状态位):通常与Java字节码执行有关,在普通应用中很少用到。 ### 中断禁止位 tn2>`I`(IRQ禁止位):当I=1时,禁止普通中断(IRQ)。 `F`(FIQ禁止位):当F=1时,禁止快速中断(FIQ)。 ### M模式位(处理器模式位) tn2>处理器可以工作在不同的模式下,不同的模式有不同的特权级和用途。 模式位用5位二进制数表示,如下:<br/> `10000`(User mode)[10]:用户模式,普通应用程序运行的模式。 `10010`(IRQ mode)[12]:中断请求模式,用于处理中断。 `10011`(SVC mode)[13]:超级用户模式,用于操作系统服务。 `10111`(Abort mode)[17]:数据访问中止模式,用于处理存储器访问错误。 `11011`(Undefined mode)[1B]:未定义指令模式,用于处理未定义指令。 `11111`(System mode)[1F]:系统模式,高特权级,用于操作系统。 ![](https://img.tnblog.net/arcimg/hb/7638c0327de4400180892d2f1e9adcdd.png) tn>SPSR与CPSR相同,不同在于SPSR用于处理异常的状态,CPSR记录的是当前的状态 tn2>那么我们刚刚执行的`swi 3`就很好解释了。 由于`I = 1,F = 1`禁止普通中断和快速中断。 `M = 0x13`也就是`10111`切换为Supervisor模式。 `R14`指向了一个地址,用于保存子程序返回地址。 ![](https://img.tnblog.net/arcimg/hb/3604e8f3ec9e495693a9f1e5aaed4d48.png) tn2>在`Internal`下面的`Mode`同样显示出当前的模式。 ### 操作指令 tn2>`msr`指令:将CPSR寄存器的值读到一个通用寄存器中,例如`mrs r0, CPSR`表示将CPSR的值读到寄存器r0中。 `mrs`指令:将一个通用寄存器的值写到CPSR寄存器中,例如`msr CPSR, r0`表示将寄存器r0的值写到CPSR中。 tn>`mov`指令不能直接操作CPSR。 tn2>接下来我们通过`msr`指令将其切换为`User`模式。 并将读取到`R0`寄存器中。 ```bash .text b main nop nop nop nop nop nop nop main: msr CPSR,#0x10 mrs r0,CPSR ``` ![](https://img.tnblog.net/arcimg/hb/5743e25456774d818a4c311e26376ad0.png) tn2>可以看到我们操作成功,但是如果想切回`Supervisor`是不行的,因为权限不够。