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

指令集、立即数和伪指令

文章目录

  • 一、介绍
  • 二、指令格式转换
    • 2.1.ARM 与 Thumb
    • 2.2.Thumb-2
  • 三、立即数和伪指令
    • 3.1.立即数
    • 3.2.伪指令

一、介绍

ARM 公司发布两类指令集:

  • ARM 指令集:32位,高效但占据空间
  • Thumb 指令集:16位,节省空间

在 RISC 中对于内存只有读写操作,计算是在 ALU 里面的,因此汇编可以分为下面几类:

  • 内存的读写操作
  • 运算
  • 跳转 / 分支:调用函数等
  • 比较:if 语句等

这些就是所谓的指令集。

二、指令格式转换

2.1.ARM 与 Thumb

ARM 指令和 Thumb 指令之间的切换,取决于地址的 bit 0 位, 因为地址本身是对齐的(字对齐或半字对齐),所以 bit 0 在计算实际地址时会被硬件忽略。它纯粹用于状态控制。举个例子,假设 thumb_routine 的物理地址是 0x00002000。这是一个半字(16位)对齐的地址,其 bit 0 是 0。:

;这是由ARM状态切换到Thumb状态
LDR R0, =0x00002001  ; 将地址 0x2000 + 1 加载到 R0,bit 0 被显式设置为 1
BX R0                ; 处理器看到 bit 0 = 1,会切换到Thumb状态,并跳转到 0x2000 执行。

同理,由 Thumb 状态切换到 ARM 状态,假设 arm_routine 的物理地址是 0x00003000,这是一个字对齐的地址,其 bit 0 是 0。

LDR R1, =arm_routine  ; 直接加载ARM例程的地址 0x00003000,bit 0 = 0
BX R1                 ; 处理器看到 bit 0 = 0,会切换到ARM状态,并跳转到 0x3000 执行。

2.2.Thumb-2

为了提高 32 位和 16 位切换的效率,ARM 公司又提出了 Thumb-2 指令集,使得两种不同格式的指令混合使用。举例:要将寄存器 R1 的值左移 2 位:

  • 在传统 Thumb 中: 可能需要多条 16 位指令才能完成(比如先用一条指令将移位值 2 放入另一个寄存器,再用一条指令进行移位)
  • 在 ARM 中: 一条指令搞定:MOV R0, R1, LSL #2 (32位指令)
  • 在 Thumb-2 中: 同样一条指令搞定:LSLS R0, R1, #2。关键是,这条指令在 Thumb-2 中是一条 32 位指令,但它可以在 Thumb 状态下直接执行,无需切换到 ARM 状态

Thumb-2 的指令会影响程序状态寄存器的 EPSR 寄存器,该寄存器里的 T 就是说明了该指令是 ARM 指令还是 Thumb 指令,置 1 就是 Thumb 指令,置 0 就是 ARM 指令,如下图所示:

在这里插入图片描述

三、立即数和伪指令

3.1.立即数

MOV R0, #VAL   ;将VAL值存放到R0寄存器里,这个值可以是任意数吗?	

不可以,VAL 里面的数必须是立即数,立即数就是一个数值通过一个指令直接放在寄存器里面,CPU 访问的时候直接可以知道这个数值,不需要再去访问其他地址。如下图所示,在一条 32 位的 ARM 指令中,不可能用一个完整的 32 位来存放一个任意的 32 位立即数,因为还需要空间来编码操作码目标寄存器条件码等。

在这里插入图片描述

解释一下以上图片:

  • cond:条件执行字段,它决定这条指令在什么条件下执行,例如:两数相比,相等 EQ,不相等 NE
  • opcode:操作码字段,用于区分数据处理指令,并指定具体操作,例如:MOV、ADD、AND 等
  • Rd:目标寄存器,指令结果存放的地方,例如:R0 ~ R15 寄存器
  • 0 ~ 11 位:这里的 12 位被进一步划分为两个部分:Immed_8:一个 8 位的基础数(0 ~ 255);Rotate_imm:一个 4 位的循环右移值(0 ~ 15)

判断一个数是否是立即数,下面有一条公式:实际立即数 = Immed_8 循环右移 (2 × Rotate_imm) 位:取 Immed_8(一个 8 位的数);将它扩展为一个 32 位的数(高 24 位用 0 填充);将这个 32 位数循环右移。右移的位数是 Rotate_imm 字段的值 乘以 2;因为 Rotate_imm 是 4 位,所以范围是 0 ~ 15;乘以2后,可能的移位位数是 0, 2, 4, 6, …, 30(所有偶数);最终得到的结果,就是指令可以使用的 32 位立即数。
例如:假设指令中的立即数字段编码是:Rotate_imm = 4, Immed_8 = 0b00000010 (即十进制2):

取出基础值: Immed_8 = 232位表示为 0x00000002。计算移位位数: 2 × Rotate_imm = 2 × 4 = 8 位。执行循环右移8位:将 0x00000002 (二进制 0000 0000 ... 0000 0010) 循环右移8位。结果是 0x02000000 (二进制 0000 0010 0000 0000 ... 0000 0000)。所以,这条指令使用的实际立即数是 0x02000000

3.2.伪指令

LDR R0, =VAL	;使用等于号就说明了这是一条伪指令

伪指令就是假的指令,一条不存在的指令,编译器会将这个伪指令替换成真实的指令,如果 VAL 的值是立即数 0x12,编译器就会将该指令变成:

MOV R0, #0x12

如果这个值不是立即数,而是没有遵循立即数规律的数:0x12345678,编译器会将其替换为:

Label DCD 0x12345678	;先在某个地方保存这个值
LDR R0, [pc,#offset]	;再使用Load Register读内存指令读出这个值,offset是链接程序时确定的
http://www.dtcms.com/a/419322.html

相关文章:

  • 危机领导力:突发事件中的决策与沟通策略
  • Unity学习之垃圾回收GC
  • 五次样条速度规划方法介绍
  • 找人做网站被骗怎么办wordpress 评论 姓名
  • 如何建立公司企业网站社区网站建设方案ppt
  • 解密C++多态:一篇文章掌握精髓
  • Git 进阶指南:深入掌握 git log 查看提交历史
  • C++ 引用协程
  • 淄博企业网站设计公司网页无法打开怎么办
  • 添加测试设备到苹果开发者平台
  • 填坑:VC++ 采用OpenSSL 3.0接口方式生成RSA密钥
  • 郑州做网站的网站再就业技能培训班
  • Vscode 连接服务时候一直出现setting ssh Host server
  • 全面解析数据库审批平台:主流工具对比与选型指南
  • 【Docker项目实战】使用Docker部署IT运维管理平台CAT
  • spring事务传播级别的实操案例2
  • 泰州专一做淘宝网站如何用html做网站头像
  • 电子商务网站设计与实现个人网站做捐赠发布违法吗
  • Java滑动窗口算法题目练习
  • 介绍一下HTTP和WebSocket的头部信息
  • Linux系统学习之---库的理解和加载(毛坯初版...)
  • 南山模板网站建设公司怎么看网站的外链
  • 企业网站策划大纲模板文山住房和城乡建设局网站
  • Linux 基础IO与系统IO
  • 【IEDA】已解决:IDEA中jdk的版本切换
  • idea推荐springboot+mybatis+分页查询插件之PageHelper
  • 南非网站域名做网站微信支付多少钱
  • 网站开发 图形验证码网站建设衤金手指下拉10
  • OPenssh6代码移植的依赖库 OpenSSL双库连接问题的解决方案
  • 商务网站建设组成包括网站优化wordpress 换行