汇编语言笔记-ARM架构基本寄存器

2023-11-13

寄存器组

       Cortex-M3和Cortex-M4处理器(ARM架构)用于数据处理与控制的寄存器组中有16个寄存器,其中13个(R0 ~ R12)为通用目的寄存器,另外三个具有特殊用途:
在这里插入图片描述

1.R0 ~ R12

       寄存器R0 ~ R12为通用目的寄存器,其中前8个(R0 ~ R7)也被称作低寄存器,由于指令中可用的空间有限,许多16位指令只能访问低寄存器。而其它寄存器(R8 ~ R12)被称为高寄存器,可用于32位指令和部分16位指令,如MOV。

R0 ~ R12的初始值是未定义的。

2.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的初始值则需要在复位流程中从存储器的第一个字中取出。

3.R14

       R14为链接寄存器(LR),用于保存函数或子程序调用时返回地址。
       在函数或子程序结束时,程序将LR的数值加载至程序计数器(PC)中返回调用程序处并继续执行(也就是跳转回上层函数)。
       当执行了函数或子程序调用后,LR的数值会自动更新。若某函数调用另外一个函数或子程序,则需要将LR的数值保存在栈中,否则,函数执行后,LR的当前值会丢失(函数嵌套必须将对应的上层函数地址保存在栈中)。
       在异常处理期间,LR自动更新为特殊的EXC_RETURN(异常返回)数值,以在异常处理结束时触发异常返回。

4.R15

       R15为程序计数器(PC),可读写寄存器,读操作返回当前指令地址加4(由于设计的流水线特性及同ARM7TDMI处理器兼容的需要)。写操作(例如,使用数据传输/处理指令)产生程序跳转。
       由于指令必须对齐到长度(半字或字),PC的最低位(LSB)为0。但使用部分跳转/读存储器指令更新PC时,需要将PC值的LSB置1表示 Thumb状态,否则就会由于试图使用不支持的ARM指令(如ARM7TDMI中的32位ARM指令)而触发错误异常。高级编程语言(包括C和C+)编译器会自动将跳转目标的LSB置位。
       多数情况下,跳转和调用由专门的指令实现。访问位于程序存储器中的字符数据时,PC的数值非常有用,因此存储器读操作经常将PC作为基地址寄存器,并通过指令中的立即数生成偏移地址。

多数汇编工访问寄存器组中的寄存器时可以使用多种名称。一些汇编工具如ARM汇编(被DS5 Professional和 Keil MDK-ARM支持)可以使用大写、小写或者大小写混合,如下表所示:
在这里插入图片描述

特殊寄存器

       特殊寄存器未经过存储器映射,可以使用MSR和MRS等特殊寄存器访问指令来进行访问:

MRS <reg>,<special_reg>    ;将特殊寄存器读入寄存器
MSR <special_reg>,<reg>    ;写入特殊寄存器

       CMSIS-Core(为Cortex-M处理器核和外设定义的应用程序接口API)提供了几个用于访问特殊寄存器的函数。

不要混淆特殊寄存器和其他微控制器架构中的“特殊功能寄存器(SFR)”,SFR一般指的是用于I/O控制的寄存器

程序状态寄存器(xPSR)

       程序状态寄存器包括以下三个状态寄存器:

  • 应用PSR(APSR)
  • 执行PSR(EPSR)
  • 中断PSR(IPSR)

       三个寄存器各个功能位为:
在这里插入图片描述
       各个位的作用如下表所示:
在这里插入图片描述

注意,APSR和EPSR的一些位域在ARMv6-M架构(如 Cortex-M0)中不可用,且与ARM7TDMI等经典ARM处理器之间存在很大的差异。

       这三个寄存器可以通过一个组合寄存器访问,该寄存器在有些文献中被称作xPSR,ARM汇编器访问xPSR时通过“PSR”访问:

MRS R0, PSR   ;读组合程序状态字
MSR PSR, R0   ;写组合程序状态字

注意,此时组合寄存器为三个寄存器的有效位叠合,如下图所示:
在这里插入图片描述

       同时,也可以单独访问某个PSR:

MRS R0, APSR   ;将标志状态读入R0
MRS R0, IPSR   ;读取异常/中断状态
MSR APSR, R0   ;写标志状态

无法使用MRS(读出为0)或MSR直接访问EPSR。
IPSR为只读寄存器。

中断/异常屏蔽寄存器

名 字 功能描述
PRIMASK 1位宽寄存器。置位后关闭NMI(不可屏蔽中断和HardFault外的所有可屏蔽异常/中断。
FAULTMASK 1位宽寄存器。置位后只有NMI可以响应(相比于PRIMASK,可屏蔽的中断/异常多了HardFault)。
BASEPRI 根据优先级屏蔽中断/异常,该寄存器最多有9位(由设计实现的优先级位数决定)。该寄存器定义了被屏蔽优先级的阈值。当它被设置为某个值后,所有优先级号大于等于此值的中断都被关(注意:优先级号越大,优先级越低);若设置成0,则不关断任何中断。

注意:FAULTMASK和BASEPRI寄存器在ARMv6-M中不存在(如Cortex-M0)。

只有特权状态才可以操作三个寄存器(非特权状态下的写操作会被忽略,读操作返回0)。三个寄存器默认值为0,即屏蔽(禁止异常/中断)不起作用。

       使用MRS/MSR指令访问这三个寄存器,比如:

  MRS    R0, BASEPRI            ;将BASEPRI寄存器的值写入R0
  MSR    BASEPRI, R0            ;将R0的值写入BASEPRI寄存器

       可通过CSP(修改处理器状态)指令快速设置中断/异常的开关:

  CPSID    I    ;PRIMASK=1,关中断
  CPSIE    I    ;PRIMASK=0,开中断
  CPSID    F    ;FAULTMASK=1,关异常    
  CPSIE    F    ;FAULTMASK=0,开异常

CONTROL寄存器

       Cortex-M3、M4及的CONTROL寄存器如下,其中:

  • nPRIV在Cortex-M0中不存在,在 Cortex-M0+中可选
  • 具有浮点单元的Cortex-M4处理器的CONTROL寄存器中有1位表示当前是否使用浮点单元。
    在这里插入图片描述

       各个位的解释如下:

描述
nPRIV 用于定义线程模式中的特权等级:
0(默认):处于线程模式模式中的特权等级
1:处于线程模式模式中的非特权等级
SPSEL 用于定义栈指针的选择:
0(默认):线程模式使用主栈指针(MSP)
1:线程模式使用进程栈指针
处理模式下该位始终为0,且无法写入
FPCA 只存在于具有浮点单元的Cortex-M4中。异常处理机制通过该位确定异常产生时浮点单元相应寄存器是否需要保存。
0:当前的上下文不使用浮点指令
1:当前的上下文使用浮点指令(此时产生异常自动保存相应浮点寄存器)。

该寄存器复位后默认为0

只有特权状态才能修改(写操作)CONTROI寄存器。(读操作则不需要特权状态)

       同样的,使用MRS/MSR指令访问该寄存器:

  MRS    R0, CONTROL            ;将CONTROL寄存器的值写入R0
  MSR    CONTROL, R0            ;将R0的值写入CONTROL寄存器

浮点寄存器

1.S0 ~ S31和D0 ~ D15

       S0 ~ S31(S)都为32位寄存器,可通过浮点指令或利用符号D0 ~ D15(D代表双字/双精度)成对访问。
       例如,S0和S1成对组成D0,而S2和S3则成对组成D1。

浮点状态和控制寄存器(FPSCR)

       FPSCR寄存器用于定义浮点运算动作并提供浮点运算结果的状态信息,其位域及各个位的描述如下所示:
在这里插入图片描述

描述
N 负标志(由浮点比较运算更新)
Z 零标志(由浮点比较运算更新)
C 进位/借位标志(由浮点比较运算更新)
V 溢出标志(由浮点比较运算更新)
AHP 交替半精度控制位:
0:IEEE半精度格式(默认)
1:交替半精度格式
DN 默认NaN(非数值)模式控制位:
0:NaN操作数会变为浮点运算的输出(默认)
1:任何涉及一个或多个NaN的运算会返回默认的NaN
FZ 清零模式控制位:
0:清零模式禁止(默认)(符合IEE754标准)
1:清零模式使能
RMode 舍入模式控制位,表示的舍入模式基本上适用于所有的浮点指令:
00:最近舍入(RN)模式(默认)
01:正无穷舍入(RP)模式
10:负无穷舍入(RM)模式
11:向零舍入(RZ)模式
IDC 输入非正常累积异常位(结果未在正常数值范围内)
IXC 不精确的累积异常位
UFC 下溢累积异常位
OFC 溢出累积异常位
DZC 被零除累积异常位
IOC 非法操作累积异常位

上述的6个异常位在浮点异常产生时置位,写0则将其清除

浮点单元控制寄存器(经存储器映射)

       暂略…

注意

       ARM架构具有两种状态:ARM状态和Thumb状态,其中Cortex-M3和M4只能使用Thumb状态,而在该状态下部分寄存器的访问是有限制的:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汇编语言笔记-ARM架构基本寄存器 的相关文章

  • armv8 NEON if 条件

    我想了解armv8 NEON内联汇编代码中的if条件 在armv7中 这可以通过检查溢出位来实现 如下所示 VMRS r4 FPSCR BIC r4 r4 1 lt lt 27 VMSR FPSCR r4 vtst 16 d30 d30 d
  • 为什么 ARM 使用两条指令来屏蔽一个值?

    对于以下功能 uint16 t swap const uint16 t value return value lt lt 8 value gt gt 8 为什么带 O2 的 ARM gcc 6 3 0 会产生以下程序集 swap unsig
  • 使用 GCC 编译器为代码的特定部分保留寄存器

    是否可以为 C 代码的特定部分保留寄存器 ffixed reg 选项或声明全局寄存器变量不是我正在寻找的答案 我想保留特定范围 比如说特定函数 的寄存器值 使用局部寄存器变量是不可能的 因为它不能保证在整个范围内保留寄存器的值 我正在寻找类
  • 嵌入式 C++ (ARM9) 单元测试

    我来自 Java 和 JUnit 的世界 我演示了 Hudson 以及我使用 JUnit 取得的所有成果 我想在嵌入式设备上对 C 代码执行相同的操作 但找不到从哪里开始 该项目使用 iccarm exe IAR 编译器 进行编译 现在使用
  • 如何修改内核DTB文件

    Summary 我目前正在为定制板编译 Linux 内核 内核 模块和 DTB 以及一些定制驱动程序 有时 我会编译内核并意识到 DTB 文件中的兼容性字符串不是自定义驱动程序正在寻找的内容 现在 我可以解决此问题的唯一方法是修改 DTS
  • ARM Neon:如何从 uint8x16_t 转换为 uint8x8x2_t?

    我最近发现了关于vreinterpret q dsttype src类型转换运算符 https stackoverflow com a 43519190 2436175 但是 这似乎不支持所描述的数据类型的转换这个链接 http infoc
  • ARM 汇编分支到寄存器或内存内部的地址

    我想知道在 ARM 汇编中我可以使用哪条指令分支到存储在某个内存地址中的地址或标签 例如 我们可以使用B LABEL来跳转到LABEL 但现在目的地只能在运行时知道 并且它存储在某个已知的内存位置 是否有类似 B 地址 的东西 Thanks
  • 使用 ARM NEON 内在函数添加 alpha 和排列

    我正在开发一个 iOS 应用程序 需要相当快地将图像从 RGB gt BGRA 转换 如果可能的话 我想使用 NEON 内在函数 有没有比简单分配组件更快的方法 void neonPermuteRGBtoBGRA unsigned char
  • 手臂“版本”之间的差异? (仅限 ARMv7)

    基本上我想知道ARMv7l和ARMv7之间的区别hl 我有一个带有armv7l的arm处理器 并且有很多armv7的rpmhl 我完全不知道我必须搜索什么才能获得相关信息 这个 后缀 叫什么 还有其他类型吗 他们的做法有何不同 我假设它指示
  • 如何使用 gcc 编译代码和 ARM Cortex A8 目标进行调用图分析?

    我对这个已经咬牙切齿了 我需要在 ARM 板上进行分析并需要查看调用图 我尝试使用 OProfile Kernel perf 和 Google 性能工具 一切正常 但不输出任何调用图信息 这使我得出结论 我没有正确编译代码 我在编译 C 代
  • RAM 存储二进制数和汇编语言的冒泡排序

    我必须使用 ARM v7 执行一个例程 在 RAM 内存中存储 10 个二进制数 然后使用冒泡排序对这些数字从高到低进行排序 我应该如何开始 func bubbleSortAscendingU32 ldr r3 r0 4 mov r1 9
  • DSP 库 - RFFT - 奇怪的结果

    最近我一直在尝试在我的STM32F4 Discovery评估板上进行FFT计算 然后将其发送到PC 我已经调查了我的问题 我认为我对制造商提供的 FFT 函数做错了 我正在使用 CMSIS DSP 库 现在我一直在用代码生成样本 如果工作正
  • 交叉编译 Qt 4.7 时出现“非法指令”

    我已经在这个问题上苦苦挣扎了一个多星期了 但仍然找不到解决方案 我正在尝试为 ARM 设备交叉编译 Qt 4 7 嵌入式开源版本 构建过程本身可以顺利完成 但生成的二进制文件似乎包含处理器无法理解的指令 构建主机是 i386 上的 Debi
  • ARM + gcc:不要使用一大块 .rodata 部分

    我想使用 gcc 编译一个程序 并针对 ARM 处理器进行链接时间优化 当我在没有 LTO 的情况下编译时 系统会被编译 当我启用 LTO 时 使用 flto 我收到以下汇编错误 错误 无效的文字常量 池需要更近 环顾网络 我发现这与我系统
  • 如何使用 Neon SIMD 将无符号字符转换为有符号整数

    如何转换变量的数据类型uint8 t to int32 t使用霓虹灯 我找不到执行此操作的任何内在因素 假设您想要将 16 x 8 位整数的向量转换为 4 个 4 x 32 位整数的向量 您可以通过首先解压缩为 16 位 然后再次解压缩为
  • ARM 系统调用的接口是什么?它在 Linux 内核中的何处定义?

    我读过有关 Linux 中的系统调用的内容 并且到处都给出了有关 x86 架构的描述 0x80中断和SYSENTER 但我无法追踪 ARM 架构中系统调用的文件和进程 任何人都可以帮忙吗 我知道的几个相关文件是 arch arm kerne
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • DS-5:什么是 FVP、RTSM、基础模型、AEM 模型、快速模型、CADI?

    DS 5 模拟器使用了很多术语 如 FVP RTSM 快速模型 基础模型 AEM 模型 CADI Arm的文档中提供的解释不是很清楚 这些术语的含义是什么 作为 DS 5 的最终用户我应该关心哪些术语 Model 软件模拟的行业术语 就 A
  • 了解 U-Boot 内存占用

    我不明白加载 U Boot 时 RAM 中发生了什么 我正在开发 Xilinx Zynq ZC702 评估套件 并尝试使用 U Boot 在其上加载 Linux 内核 于是我使用Xilinx工具Vivado和SDK生成了一个BOOT bin
  • 为什么 GCC 交叉编译不构建“crti.o”?

    在尝试为arm构建gcc 4 x x交叉编译器时 我陷入了缺失的困境crti o文件在 BUILD DIR gcc子目录 An strace在顶层Makefile表明编译后的xgcc正在调用交联器ld with crti o 作为一个论点

随机推荐

  • Python数据分析——上海市二手房价格分析

    自学数据分析与机器学习已有两月 近期房价问题引人深思 即兴做个上海市房价的数据分析小项目 上网一查上海市新楼盘价格 高的不忍直视 索性退而求其次 分析上海二手房的价格 一 数据收集 常规做法是编写网络爬虫程序 爬取相关网站的数据信息 捷径是
  • 如何把glb格式模型gltf格式模型导入3dmax和C4D,U3D,UE4这些主流软件中

    咱有时候去glbxz com添加链接描述 官网下载免费glb格式模型 gltf模型下载时候是没有通用格式 例如fbx obj 这个时候3dmax和C4D直接打开导入是不行的 也可以制作glb模型 扣扣 424081801 这个时候 咱们用
  • AI工具汇总

    大家好 我是可夫小子 关注AIGC 读书和自媒体 ChatGPT已经火了这么久 我也写不了少玩ChatGPT的方法 昨天OpenAI又推出了苹果手机的APP 我也介绍下载和安装的攻略 但根据读者反馈 仍然还是有许多同学没能用上 今天我就把我
  • VS2015远程编译Linux项目

    用VS2015开发Linux程序详细教程 配置篇 crazytea的博客 CSDN博客 linux 程序开发VS2015推出了跨平台开发 其中包括了对Linux程序开发的支持 最近刚好需要开发Linux程序 对其进行了一些研究 首先介绍下涉
  • redis的安装与配置

    第一章 redis 1 1redis的概述 1 2关系型数据库与非关系数据库 1 3关系型数据库和非关系型数据库区别 1 4redis优点与缺点 第二章redis的安装 2 1 YUM安装 2 2下载编译安装 2 2 1关闭防火墙 2 2
  • element左侧导航栏el-menu,菜单栏文字超出不折行问题

    在CSS样式中加上这些样式就可以了 el submenu title display flex align items center el submenu title span white space normal word break b
  • C# 面向对象05 StringBuilder的用法

    好处 相比普通的 string处理 提高了字符串的处理速度 注意点 使用时需要使用对象的方式 StringBuilder world new StringBuilder using System using System Diagnosti
  • SimpleDateFormat模式字符串格式

    SimpleDateFormat模式字符串 new SimpleDateFormat String parm parm为一个字符串 表示格式 时间模式 字母 时间元素 表示 示例 y 年 Year 1996 96 M 年中的月份 Month
  • PyTorch基础之模型保存与重载模块、可视化模块讲解(附源码)

    训练模型时 在众多训练好的模型中会有几个较好的模型 我们希望储存这些模型对应的参数值 避免后续难以训练出更好的结果 同时也方便我们复现这些模型 用于之后的研究 PyTorch提供了模型的保存与重载模块 包括torch save 和torch
  • jvm内存模型与垃圾回收(下)

    上篇地址 jvm内存模型与垃圾回收 上 1 垃圾回收相关算法 标记清除 标记整理 复制 这三个看上面的文章 1 1 分代收集算法 将不同生命周期的对象采用不同的收集方式 以便提高回收效率 一般是将Java堆分为新生代和老年代 这样可以根据各
  • 接口与实现

    public interface Computable 接口体包含常量和抽象方法 没有普通方法 int MAX 46 常量 int f int x 抽象方法 默认权限friendly public class China implement
  • 【C++】使用Windows操作系统的API在控制台输出绿色的文本

    2023年8月21日 周一下午 include
  • linux桌面远程控制,在LINUX下远程控制WIN桌面

    rdesktop 是个在veket下访问视窗系统 远程桌面的客户端程式 当前 rdesktop 所支持的 视窗系统 系列版本包括 NT 2000 XP 和2003 通过使用 rdesktop 所实现的远程桌面协议 RDP 你能在veket系
  • 企业微信群机器人开发

    准备工作 已经注册了有效的企业微信账号 并且在客户端上已经登录 现有或者新建有效的包含多名企业微信成员的群聊 创建群聊机器人 右键群聊 gt 管理聊天信息 gt 添加群机器人 使用群机器人 在终端某个群组添加机器人之后 创建者可以在机器人详
  • 【单片机笔记】STM32+ESP8266通过AT指令WIFI连接阿里云MQTT服务器

    上一篇使用USB转串口的方式通过ESP8266wifi模块的方式成功连接上了阿里云 现在就要通过单片机来替换电脑上位机了 这样单片机自动的去调用并发送串口数据更加方便 也更加符合一个产品的开发 板载的传感器有NTC温度 光强 这两个主要用来
  • 音频采样率、采样深度、占用字节数浅析

    1 从一个问题来看 16K采样率 16bit采样深度 20ms的数据共占用多少字节 想要解这个问题 首先就要明白采样率是什么 它的单位是什么 采样率 就是指音频在每秒的采样次数 采样多少个点 单位是赫兹 hz 在这里 尤其不要与比特率 bp
  • wxc-icon使用

  • Vue3中的computed函数详解

    计算属性是Vue中常用的一种方式 主要用于在模板中放置逻辑计算 方便开发者进行数据操作和展示 在Vue3中 计算属性依然是非常重要的一种功能 而computed函数则更加的方便计算属性的使用 本文将对Vue3中的computed函数进行详细
  • 修改约束(注意是否存在字段名的情况)

    添加字段名时添加约束 语法 alter table 表名 add 字段名 数据类型 约束名 注意 这个方法会让表中让所有address都变成 中国 表达有点不清晰 自己去试试此方法和其他方法就知道了 例如 alter table emp a
  • 汇编语言笔记-ARM架构基本寄存器

    文章目录 寄存器组 1 R0 R12 2 R13 3 R14 4 R15 特殊寄存器 程序状态寄存器 xPSR 中断 异常屏蔽寄存器 CONTROL寄存器 浮点寄存器 1 S0 S31和D0 D15 浮点状态和控制寄存器 FPSCR 浮点单