ARM 立即寻址之立即数的形成 —— 如何判断有效立即数
依据指令中给出的操作数的不同格式,ARM 指令系统具有 8 种常见的寻址方式。我们这次就来讨论一下立即寻址。
文章目录
- 立即寻址的特点
- 立即数形式
- 合法立即数
- 立即寻址机器指令格式
- 指令解析
- 判断方法
- 例子 #0x0000f200
- 例子 0x234
- 例子 0x132
- 判断小技巧
- 加载不合法立即数
- 相关资料
立即寻址的特点
在立即寻址,操作数本身直接在指令中给出,取出指令也就获得了操作数,这个操作数也称为立即数。例子如下:
ADD R0, R1, #5 ;R0=R1+5
MOV R0, #0x55 ;R0=0x55
在这两个例子中,操作数 5 和 0x55 就是立即数。
注意:立即数在指令中要以 “#”为前缀,后面跟实际数值。
立即数形式
我们看到上面两个立即数一个是十进制一个是十六进制,那么这个立即数有哪些形式呢?
#后的立即数形式:
- 0x 或 & 表示十六进制数
- 0b 表示二进制数
- 0d 或缺省表示十进制数
合法立即数
现在又有一个问题,我们怎么判断这个立即数是不是合法的,也就是计算机能够准确表示出来的呢?
立即寻址机器指令格式
这里首先涉及到数据编码的知识。我们知道我们写出的是汇编指令,而汇编指令不是计算机能够理解的,计算机所能理解的只是 0 1 这两种数字。所以,我们写出的汇编指令还要经过译码器译码成机器指令才能被计算机所理解。
在 ARM 中,机器指令的格式大致有如下这么多种,还有一些更具体的这里不提(图片来自 ARM Architecture reference Manual
):
我们此次讨论的立即数寻址的指令格式应该是:
指令解析
我们可以从图片中看出:一条指令的后 12 位(bit 11~0),是指令中立即数占用的位数。其中这 12 位又分为两部分:前 7~0 位是数值部分;后 11~8 位是前 7~0 位要进行移位操作的移位数。
我们注意到其中 immed_8 有 8 位,也就是我们的立即数部分占 8 位,因此有如下结论:
- 如果一个立即数小于 0xFF(255)那么直接用前 7~0 位表示即可,此时不用移位,11~8 位的 Rotate_imm 等于 0。
- 如果前八位 immed_8 的数值大于 255,那么就看这个数是否能有 immed_8 中的某个数移位 2*Rotate_imm 位形成的。如果能,那么就是合法立即数;否则非法。
判断方法
一个 32 位数用 12 位编码表示,符合以下规则才是合法立即数。
立即数 = immed_8 循环右移 (2 * Rotate_imm)
解读:如果存在一个 Rotate_imm 能够让该立即数由 immed_8 循环右移 2*Rotate_imm 位(偶数位)表示,那么这个立即数就是合法的。
PS. 这个为什么是 32 位我姑且不知道,抄 PPT 的。12 位编码就是 指令解析
这一小节里面说的那 12 位。
例子 #0x0000f200
我们来举个例子看看
汇编指令:mov R0, #0x0000f200
经过译码器转化为汇编后的机器指令如下:
机器指令:0xe3a00cf2
,其中 0xcf2
就是我们的立即数。
下面我们讨论译码器是如何计算出这个 cf2
的:
我们先来解剖一下转换后的 cf2
。其中的 c
就是 Rotate_imm 部分,而 f2
则是 Immed_8 部分。
译码器看到 #0x0000f200
也就是二进制的 0000 | 0000 | 0000 | 0000 | 1111 | 0010 | 0000 | 0000 |
。然后计算出将其中的 1111 | 0010
部分循环右移 24 位刚好就是那个二进制。(看下面的图会更清楚)
即 0x0000f200=0xf2 循环右移 (2×0x0c)
因此我们可以得出此时的 Rotate_imm 的值就是 12,十六进制就是 c; Immed_8 的值则是 1111 | 0010 即 f2。
到此为止 cf2
的计算已经完毕。
PS. 这里的 | 并没有实际的含义,我这样做只是为了看得清楚。
最后有一个译码器寻找的伪代码,感兴趣的可以看看。
例子 0x234
0x234 是不是一个合法的立即数?
我们把 0x234 表示成 0000 | 0000 | 0000 | 0000 | 0000 | 0010 | 0011 | 0100
,发现将其中的 1000 | 1101
部分循环右移 30 位可以和这个二进制数相同。因此 Rotate_imm 的值是 15,而 Immed_8 的值是 1000 | 1101 即 8D。
例子 0x132
0x132 是不是一个合法的立即数?
我们把 0x132 表示成 0000 | 0000 | 0000 | 0000 | 0000 | 0001 | 0011 | 0010
,发现没有任何部分循环右移偶数次可以成为该数本身,因此它不是一个合法的立即数。
判断小技巧
快速判断一个数是不是有效立即数的方法是看最低几位为 0 的个数是不是偶数个(表述的有点问题)。
我来解释一下:比如上面那个 #0x0000f200
,其中我们猜测 Immed_8 为 1111 | 0010
,这个数右边还有 0000 | 0000 |
,是偶数个 0,因此是有效立即数。而我们看 0x132
,我们猜测 Immed_8 为 1001 | 1001
,右边只有一个 0,因此不是有效立即数。
加载不合法立即数
如果我们想要加载一个不合法的立即数该怎么办呢?
此时我们可以使用 LDR 伪指令代替,比如下面代码中的 0x20026 就不是有效立即数,因此我们不能使用 MOV R1, #0x20026
MOV R0, #0x18 ; 传送到软件中断的参数
LDR R1, =0x20026 ; 传送到软件中断的参数
SWI 0x123456 ; 通过软件中断指令返回
相关资料
下面是 ARM Architecture reference Manual 这本书上的相关章节
ARM 立即寻址之立即数的形成 —— 如何判断有效立即数相关推荐
- 回文数java_回文数及JAVA编程判断回文数
自然数中还有一类数被称为回文数.回文数就是一个数的两边对称,如11,121,1221,9339,30203等等.回文数本身倒也没有什么奇特.不过人们发现大多数的自然数,如果把它各位数字的顺序倒置,再与 ...
- 如何判断一个立即数是否合法
判断一个立即数是否合法,首先要知道什么是立即数 立即数通常是指在立即寻址方式指令中给出的数.可以是8位.16位或32位,该数值紧跟在操作码之后.如果立即数为16位或32位,那么,它将按"高高 ...
- python判断回文_用python判断回文数
信息举报 时间:2020-11-23 本页为您甄选多篇描写用python判断回文数,用python判断回文数精选,用python判断回文数大全,有议论,叙事 ,想象等形式.文章字数有400字.600字 ...
- ARM立即寻址中有效立即数的计算
前言 感觉这方面的计算参考书上也讲的比较模糊,在这里分享一下计算的方法 立即数寻址有效数的计算 (一)ARM立即数寻址的指令格式 (二)例1 汇编指令:mov R0, #0x00110000 转为机器 ...
- 嵌入式:ARM立即寻址与寄存器寻址
文章目录 立即寻址 立即数的表示 有效立即数问题 寄存器寻址 寄存器为第2操作数的移位操作 第2操作数的移位方式 立即寻址 立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只 ...
- ARM指令中如何判断一个立即数是有效立即数
ARM指令中如何判断一个立即数是有效立数 在ARM处理器的汇编语言中,对指令语法格式中的<shifter_operand>的常数表达式有这样的规定:"该常数必须对应8位位图,即常 ...
- ARM指令中如何判断一个立即数是 有效立即数
ARM指令中如何判断一个立即数是有效立数 在ARM处理器的汇编语言中,对指令语法格式中的<shifter_operand>的常数表达式有这样的规定:"该常数必须对应8位位图,即常 ...
- 如何判断合法的立即数
立即数的定义: 每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数由一个4位二进制的两倍表示.如果立即数记为<immediate>, 8位常数记为immed_8, 4位的循环 ...
- python判断质数的函数并输出_【python基础】|| 用python判断输入的数是否为素数
微信公众号:龙跃十二 我是小玉,一个平平无奇的小天才!持续更新,欢迎关注! 用心分享,共同成长 没有什么比你每天进步一点点更实在了 本文已经收录至我的GitHub,欢迎大家踊跃star . https ...
最新文章
- NVIDIA数据中心深度学习产品性能
- 记忆的天空:智能进化三部曲
- MySQL删除表数据
- 获取周/月的第一天最后一天
- Android Gatekeeper流程深度解剖
- 微信 weui 初体验
- MySQL 数据表备份导出,恢复导入操作实践
- 使用Spring容器最简单的代码姿势
- bash配置文件的修改
- This scheduler instance is still active but was recovered by another instance in the cluster
- PentaLogix ViewMate Pro v11.16.16破解版
- premiere cc2014破解版|premiere cc2014绿色破解版下载
- 爱数私有云盘 AnyShare 部署(二)
- android shn1 获取_华为光猫获得Root Shell(shell的root权限)详细说明,接力sdgaojian发帖。...
- C# 设置开机启动启动
- pe服务器注册表,注册表修复方法
- 用米粒填充国际棋盘python
- 锐捷密码忘了!-锐捷密码查看器
- 阿里云域名配置和https证书(ssl证书)配置内容
- 关于layer.open()弹出页面与”父页面“之间获取数据赋值给页面Element的问题