当前位置: 首页 > article >正文

C语言面试之旅:掌握基础,探索深度(面试实战之ARM架构二)

        读别人的代码,就像撕洋葱,每读一层,哭一遍。

引言        

        ARM 处理器冯诺依曼存储结构程序空间RAM 空间IO 映射空间统一编址,除对对RAM 操作以外,对外围IO、程序数据的访问均要通过加载/存储指令进行

ARM 的加载/存储指令是可以实现字、半字、无符/有符字节操作;批量加载/存储指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率。

 

一.ARM指令集

        ARM指令集是一种计算机ARM操作指令系统,可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类。

        其中,跳转指令包括B(不带返回)、BL(带返回跳转)、BLX(带返回和状态切换)、BX(带状态切换)等;数据处理指令包括MOV(数据传送)、MVN(数据取反传送)、CMP(比较指令)、CMN(反值比较)、TST(位测试)、TEQ(相等测试)、ADD(加)、ADC(带进位加)、SUB(减法指令)、SBC(带借位减法)、RSB(逆向减法指令)、RSC(带借位的逆向减法)、AND(逻辑与指令)、ORR(逻辑或指令)、EOR(逻辑异或)、BIC(位清楚指令)等;程序状态寄存器访问指令包括MRS(程序状态寄存器到通用寄存器的数据传送指令)。

 

1.加载/存储指令

        这些指令用于在内存中读取或写入数据。例如,LDR(加载寄存器)和STR(存储寄存器)是常用的加载/存储指令。

LDR指令用于从内存读取数据放入寄存器中;STR 指令用于将寄存器中的数据保存到内存。指令格式如下:

    LDR{cond}{T} Rd,<地址>;加载指定地址上的数据(字),放入Rd中

    STR{cond}{T} Rd,<地址>;存储数据(字)到指定地址的存储单元,要存储的数据在Rd中

    LDR{cond}B{T} Rd,<地址>;加载字节数据,放入Rd中,即Rd最低字节有效,高24位清零

    STR{cond}B{T} Rd,<地址>;存储字节数据,要存储的数据在Rd,最低字节有效

其中,T 为可选后缀,若指令有T,那么即使处理器是在特权模式下,存储系统也将访问看
成是处理器是在用户模式下。T在用户模式下无效,不能与前索引偏移一起使用T。

 

2.协处理器指令

        这些指令用于与协处理器进行通信,以执行某些特定的操作。例如,CPSID(禁用协处理器)和CPSIE(启用协处理器)是常用的协处理器指令。

1. CDP 协处理器数据操作指令
ARM 处理器通过CDP 指令通知ARM 协处理器执行特定的操作。该操作由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取决于协处理器。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。指令格式如下:
    CDP{cond}coproc,opcodel,CRd,CRn,CRm{,opcode2}

    其中: coproc 指令操作的协处理器名。标准名为pn,n 为0~15。

    opcodel 协处理器的特定操作码。

    CRd 作为目标寄存器的协处理器寄存器。

    CRN 存放第1 个操作数的协处理器寄存器。

    CRm 存放第2 个操作数的协处理器寄存器。

    Opcode2 可选的协处理器特定操作码。

    CDP 指令举例如下:

    CDP p7,0,c0,c2,c3,0 ;协处理器7 操作,操作码为0,可选操作码为0

    CDP p6,1,c3,c4,c5 ;协处理器操作,操作码为1

2. LDC 协处理器数据读取指令
LDC指令从某一连续的内存单元将数据读取到协处理器的寄存器中。协处理器数据的数据的传送,由协处理器来控传送的字数。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。指令格式如下:
    LDC{cond}{L} coproc,CRd,<地址>

    其中: L 可选后缀,指明是长整数传送。

    coproc 指令操作的协处理器名。标准名为pn,n 为0~15

    CRd 作为目标寄存的协处理器寄存器。

    <地址> 指定的内存地址

    LDC 指令举例如下:

    LDC p5,c2,[R2,#4];读取R2+4指向的内存单元的数据,传送到协处理器p5的c2寄存器中

    LDC p6,c2,[R1] ;读取是指向的内存单元的数据,传送到协处理器p6的c2 寄存器中
    
3. STC 协处理器数据写入指令
STC指令将协处理器的寄存器数据写入到某一连续的内存单元中。
进行协处理器数据的数据传送,由协处理器来控制传送的字数。
若协处理器不能成功地执行该操作,将产生未定义指令异常中断。指令格式如下:
    STC{cond}{L} coproc,CRd,<地址>

    其中: L 可选后缀,指明是长整数传送。

    coproc 指令操作的协处理器名。标准名为pn,n 为0~15

    CRd 作为目标寄存的协处理器寄存器。

    <地址> 指定的内存地址

    STC 指令举例如下:

    STC p5,c1,[R0]

    STC p5,c1,[Ro,#-0x04]
    
4. MCR  ARM寄存器到协处理器寄存器的数据传送指令
MCR 指令将ARM 处理器的寄存器中的数据传送到协处理器的寄存器中。
若协处理器不能成功地执行该操作,将产生未定义指令异常中断。指令格式如下:
    MCR{cond}coproc,opcodel,Rd,CRn,CRm{,opcode2}

    其中:coproc 指令操作的协处理器名。标准名为pn,n 为0~15。

    cpcodel 协处理器的特定操作码。

    RD 作为目标寄存器。

    CRn 存放第1 个操作数的协处理器寄存器

    CRm 存放第2 个操作数的协处理器寄存器。

    Opcode2 可选的协处理器特定操作码。

    MCR 指令举例如下:

    MCR p6,2,R7,c1,c2,

    MCR P7,0,R1,c3,c2,1,
    
5. MRC 协处理器寄存器到ARM寄存器到的数据传送指令
MRC 指令将协处理器寄存器中的数据传送到ARM 处理器的寄存器中。
若协处理器不能成功地执行该操作。将产生未定义异常中断。指令格式如下:
    MRC {cond}coproc,opcodel,Rd,CRn,CRm{,opcode2}

    其中:coproc 指令操作的协处理器名。标准名为pn,n为0~15。

    opcodel 协处理器的特定操作码。

    Rd 作为目标寄存器。

    CRn 存放第1 个操作数的协处理器寄存器。

    CRm 存放第2 个操作数的协处理器寄存器。

    opcode2 可选的协处理器特定操作码。

    MRC 指令举例如下:

    MRC p5,2,R2,c3,c2

    MRC p7,0,R0,c1,c2,1

 

3.异常产生指令    

        ARM指令集中提供了两条产生异常的指令,通过这两条指令可以用软件的方法实现异常。其中一条指令是SWI(Software Interrupt),用于产生软中断,从而实现从用户模式变换到管理模式。另一条指令是HVC(Half-word Virtual Control),用于产生半虚拟控制异常。

        SWI指令的语法格式为SWI{<cond>} <immed_24>,其中cond表示指令执行的条件,immed_24表示24位的立即数,指定了用户请求的类型。在执行SWI指令时,CPSR保存到管理模式的SPSR中,执行转移到SWI向量,在管理模式下执行相应的中断服务程序。

        HVC指令的语法格式为HVC imm8,其中imm8表示8位的立即数,用于选择要触发的异常类型。执行HVC指令时,处理器会切换到管理模式,并触发相应的异常。

        需要注意的是,使用异常产生指令需要谨慎处理异常的优先级、嵌套和异常返回等问题,以确保程序的正确性和稳定性。

//SWI指令产生软中断
MOV R0, #12 ; 设置12号软中断  
SVC 0      ; 产生软中断,中断号为0
在这个例子中,指令MOV R0, #12将寄存器R0的值设置为12,表示请求12号软中断。
指令SVC 0产生一个软中断,中断号为0,并将程序的控制流转移到相应的中断服务程序。

//SWI指令产生软中断并传递参数
MOV R0, #34 ; 设置功能号为34  
SWI 12      ; 产生软中断,中断号为12,传递功能号34给中断服务程序
在这个例子中,指令MOV R0, #34将寄存器R0的值设置为34,表示请求的服务
类型的功能号为34。指令SWI 12产生一个软中断,中断号为12,并将功能号34
传递给相应的中断服务程序。

4.跳转指令

两种方式可以实现程序的跳转:

(1)使用跳转指令直接跳转,跳转指令有跳转指令B,带链接的跳转指令BL ,带状态切换的跳转指令BX。

(2)直接向PC 寄存器赋值实现跳转。

1. B 跳转指令, 跳转到指定的地址执行程序。

   B{cond} label

   举例如下:
   B WAITA ;跳转到WAITA 标号处

   B 0x1234 ;跳转到绝对地址0x1234 处

  跳转到指令B 限制在当前指令的±32Mb 的范围内。
  
2. BL 带链接的跳转指令, 指令将下一条指令的地址拷贝到R14(即LR)链接寄存器中,然后跳转到指定地址运行程序。
   BL{cond} label

   举例如下:

   BL DELAY

   跳转指令B 限制在当前指令的±32MB 的范围内。BL 指令用于子程序调用。
   
3. BX 带状态切换的跳转指令, 跳转到Rm 指定的地址执行程序,若Rm 的位[0]为1,则跳转时自动将CPSR 中的标志T 置位,即把目标地址的代码解释为Thumb代码;若Rm 的位[0]为0,则跳转时自动将CPSR 中的标志T 复位,即把目标地址的代码解释为ARM代码。指令格式如下:
   BX{cond} Rm

   举例如下:

   ADRL R0,ThumbFun+1

   BX R0 ;跳转到R0 指定的地址,并根据R0 的最低位来切换处理器状态
   
4. BLX, BLX目标地址:跳转,改变状态及保存PC值

五.数据处理指令

        包括ADD(加法指令)、ADC(带进位加法指令)、SUB(减法指令)、SBC(带借位减法指令)、RSB(逆向减法指令)和RSC(带借位的逆向减法指令)等。这些指令用于对两个操作数进行算术运算,并将结果存储在目标寄存器中。

//ADD指令将两个寄存器相加,并将结果存储到目标寄存器中
ADD R1, R2, R3 ; 将R2和R3相加,结果存储到R1中

六.程序状态寄存器处理

        MRS(程序状态寄存器到通用寄存器的数据传送指令)和MSR(通用寄存器到程序状态寄存器的数据传送指令)。这些指令用于将程序状态寄存器的值读取到通用寄存器中或将通用寄存器的值写入到程序状态寄存器中。

//MSR指令将通用寄存器的值写入到程序状态寄存器中:

MSR PSR, R0      ; 将R0的值写入到PSR中

二.ARM指令集具有以下特点

  1. 32位指令集:ARM指令集使用32位的指令格式,每个指令通常由操作码和操作数组成。
  2. 支持条件执行:ARM指令集支持条件执行,即只有满足特定的条件时才会执行某些指令。
  3. 支持寄存器操作:ARM指令集支持对寄存器进行操作,包括对寄存器进行读取、写入、移位等操作。
  4. 支持内存访问:ARM指令集支持对内存进行访问,包括读取和写入操作。
  5. 支持协处理器操作:ARM指令集支持与协处理器进行通信,以执行某些特定的操作。
  6. 支持异常处理:ARM指令集支持触发异常并进行处理。

http://www.kler.cn/a/159846.html

相关文章:

  • 性能优化、安全
  • 随手记:简单实现纯前端文件导出(XLSX)
  • 《MYSQL45讲》误删数据怎么办
  • 万字长文分析函数式编程
  • LeetCode【0031】下一个排列
  • 使用Matlab建立随机森林
  • ZPLPrinter Emulator SDK for .NET 6.0.23.1123​ Crack
  • 数据科学:Scipy、Scikit-Learn笔记
  • 汽车内饰灯不亮问题修复
  • Redis滚动分页的使用
  • MySQL Binlog Digger 4.31
  • ubuntu上创建服务启动python脚本
  • visual Studio MFC 平台实现拉普拉斯和拉普拉斯与直方图均衡化与中值滤波相结合实现比较
  • Codeforces Round 913 (Div. 3) A~E
  • 通过docker安装人大金仓数据库并挂在数据卷
  • LeetCode860. Lemonade Change
  • crui_lvgl 一个LVGL的DSL辅助工具的设想
  • Gluster ubuntu安装
  • TCP报文解析
  • C# 图片下载工具类
  • 查收查引(通过文献检索开具论文收录或引用的检索证明)
  • pycharm上传代码至gitLab
  • 逻辑漏洞之越权漏洞
  • 每天一点python——day88
  • Ubuntu 环境安装 Kafka、配置运行测试 Kafka 流程笔记
  • 案例052:用于日语词汇学习的微信小程序