标题:
ARM 8位图立即数研究
[打印本页]
作者:
look_w
时间:
2017-9-24 19:03
标题:
ARM 8位图立即数研究
在
ARM
处理器的汇编语言中,对指令语法格式中的
<shifter_operand>
的常数表达式有这样的规定:
“
该常数必须对应
8
位位图,即常数是由一个
8
位的常数循环移位偶数位得到的。
”
首先从
ARM
指令系统的语法格式说起。
一条
ARM
指令语法格式分为如下几个部分:
<opcode>{<cond>}{S} <Rd>,<Rn>{,<shifter_operand>}
其中,
<>
内的项是必须的,
{}
内的项是可选的,如
<opcode>
是指令助记符,是必须的,而
{<cond>}
为指令执行条件,是可选的,如果不写则使用默认条件
AL(
无条件执行
)
。
Opcode
指令助记符,如
LDR
,
STR
等
Cond
执行条件,如
EQ
,
NE
等
S
是否影响
CPSR
寄存器的值,书写时影响
CPSR
,否则不影响
Rd
目标寄存器
Rn
第一个操作数的寄存器
shifter_operand
第二个操作数
其指令编码格式如下:
31-28
27-25
24-21
20
19-16
15-12
11-0
(
12
位)
cond
001
opcode
S
Rn
Rd
shifter_operand
当第
2
个操作数的形式为:#
immed_8r
常数表达式时
“
该常数必须对应
8
位位图,即常数是由一个
8
位的常数循环移位偶数位得到的。
”
其意思是这样:#
immed_8r
在芯片处理时表示一个
32
位数,但是它是由一个
8
位数(比如:
01011010
,即
0x5A
)通过循环移位偶数位得到(
1000 0000 0000 0000 0000 0000 0001 0110
,就是
0x5A
通过循环右移
2
位(偶数位)的到的)。
而
1010 0000 0000 0000 0000 0000 0001 0110
,就不符合这样的规定,编译时一定出错。因为你可能通过将
1011 0101
循环右移位得到它,但是不可能通过循环移位偶数位得到。
1011 0000 0000 0000 0000 0000 0001 0110
,也不符合这样的规定,很明显:
1 0110 1011
有
9
位。
为什么要有这样的规定?
那位大哥的理解是(小呆:这个的确是很有道理):
要从指令编码格式来解释(这就是我为什么一开始讲的是指令编码格式),仔细看表格中的
shifter_operand
所占的位数:
12
位。要用一个
12
位的编码来表示任意的
32
位数是绝对不可能的(
12
位数有
2^12
种可能,而
32
位数有
2^32
种)。
但是又要用
12
位的编码来表示
32
位数,怎么办?
只有在表示数的数量上做限制。通过编码来实现用
12
位的编码来表示
32
位数。
在
12
位的
shifter_operand
中:
8
位存数据,
4
位存移位的次数。
8
位存数据:解释了
“
该常数必须对应
8
位位图
”
。
4
位存移位的次数:解释了为什么只能移偶数位。
4
位只有
16
种可能值,而
32
位数可以循环移位
32
次(
32
种可能),那就只好限制:只能移偶数位(两位两位地移,好像一个
16
位数在移位,
16
种移位可能)。这样就解决了能表示的情况是实际情况一半的矛盾。
所以对#
immed_8r
常数表达式的限制是解决指令编码的第二个操作数位数不足以表示
32
位操作数的无奈之举,但在我看来:这个可以说是聪明的做法。因为如果直接用
12
位数来表示
32
位操作数,只能表示
0
到(
2^12-1
)。大于
(2^12-1)
的数就没办法表示了。而且细细想来
“8
位存数据,
4
位存移位的次数
”
,应该是最好的组合了(我并未想过所有的组合,只是顺便试了几个)。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0