ARM指令中的"8位图"立即数格式

本文详细解析了ARM指令体系中,使用立即数寻址方式进行运算时,有效立即数如何通过8位常数循环右移偶数位间接得到,以及合法立即数的范围限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

书中在介绍ARM指令格式的时候, 指出:"ARM MOV指令中, 第二个操作数 (operand2) 如果是常数表达式的话, 该常数须对应8位位图 (Pattern), 即常数是由一个8位的常数循环移位偶数位得到的. 如 0x3FC, 0, 200 等是合法常量, 0x1FE, 511 等就是非法常量."(也就是这个数除以4一直除, 直到在0-255 的范围内它是整数就说明是可以的!

一条典型的 ARM 指令的基本格式是 <opcode> {<cond>} {S} <Rd> ,<Rn> {,<operand2>} 共32位. 其中<operand2> 占12位. 而在使用立即数寻址方式的时候, 数据就包含在指令的32位编码之中, 取出指令就是取出了可以立即使用的操作数. 现在考虑如下情况: 我们要使用立即数寻址的方式进行运算, 如果一个32位的立即数直接用在32位指令编码中, 就有可能完全占据32位编码空间, 使指令的操作码等无法在编码中得到体现. 而如果使用12位的 operand2 直接表示数据, 能够表示的数的范围又略显小了些. 因此, 在 ARM 指令编码中, 32位有效立即数是通过循环移偶数位而间接得到的. 具体的设计方法如下:

在 ARM 数据处理指令中, 当参与操作的第二操作数为立即数时, 每个立即数都是采用一个8位的常数循环右移偶数位而间接得到, 其中循环右移的位数有一个4位二进制的2倍表示. 则有效立即数可表示为: <immediate> := immed_8; 循环右移(2×rotate_imm). 其中: <immediate> 代表立即数, immed_8 代表8位常数, 即所谓的"8位图", rotate_imm 代表4位的循环右移值. 这样一来出现了一个问题: 尽管表示的范围变大了, 但是12位所能表现的数字的个数是一定的. 因此, ARM 规定并不是所有的32位常数都是合法的立即数, 只有通过上面的构造方法得到的才是合法的立即数, 编译的时候才不会报错.

举个例子吧.
0x3FC(0000 0000 0000 0000 0000 0011 1111 1100) 是由 0xff 循环右移 2 位得到的;
200(0000 0000 0000 0000 0000 0000 1100 1000) 是由 0xc8 循环右移 2 位得到的, 它们都是合法的.
而 0x1FE(0000 0000 0000 0000 0000 0001 1111 1110) 和
511(0000 0000 0000 0000 0000 0001 1111 1111) 无法看成是8位的常数循环右移偶数位而得到的, 因此是非法的.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值