https://blog.csdn.net/a99778800/article/details/6759825
ARM 汇编的立即数
大多数的数据处理指令和部分状态寄存器访问指令用到立即数,在 ARM 中不是所有数都能用作立即数;
ARM 汇编语法格式
<
o
p
c
o
d
e
>
{
c
o
n
d
}
{
S
}
<
R
d
>
,
<
R
n
>
,
<
s
h
i
f
t
e
r
_
o
p
e
r
a
n
d
>
<opcode>\{cond\}\{S\} <Rd>, <Rn>, <shifter\_operand>
<opcode>{cond}{S}<Rd>,<Rn>,<shifter_operand>
其中
- opcode:指令助记符,如ADD、SUB、MOV等;
- cond:条件码助记符,如EQ(0000)、NE(0001)、AL(1110)等;
- S:如果指令有S后缀,则该指令的操作会影响CPSR的值;
- Rd:目标寄存器;
- Rn:包含第一个源操作数的寄存器;
- shifter_operand:表示第二个源操作数,可以为寄存器或立即数。
操作数的语法格式
当 shifter_operand 为立即数时:
<
o
p
c
o
d
e
>
{
c
o
n
d
}
{
S
}
<
R
d
>
,
<
R
n
>
,
#
<
i
m
m
e
d
i
a
t
e
>
<opcode>\{cond\}\{S\} <Rd>,\ <Rn>,\ \#<immediate>
<opcode>{cond}{S}<Rd>, <Rn>, #<immediate>
其中:
<
i
m
m
e
d
i
a
t
e
>
=
i
m
m
e
d
_
8
循
环
右
移
(
2
∗
r
o
t
a
t
e
_
i
m
m
)
<immediate>=immed\_8\ 循环右移(2*rotate\_imm)
<immediate>=immed_8 循环右移(2∗rotate_imm)
- immediate:立即数
- immed_8:8 位的常数
- rotate_imm:4 位的循环右移值
意思是每个立即数都是由一个 8 位的常循环右移偶数位得到。
ROR 循环右移:即将操作数循环按指定的数量向右循环移位,左边用右边移出的位来填充;
例
一般情况
有效的立即数:0x104
- immediate:0x104
0001 0000 0100 - immed_8:0x41
0100 0001 - 左边补0:0x00000041
0000 0000 0000 0000 0000 0000 0100 0001 - rotate_imm:15
循环右移(2*15)位
0000 0000 0000 0000 0000 0001 0000 0100
0x0000 0104
有效的立即数:0xff0
-
immediate:0xff0
1111 1111 0000 -
immed_8:0xff
1111 1111 -
左边补0:0x000000ff
0000 0000 0000 0000 0000 0000 1111 1111 -
rotate_imm:14
循环右移(2*14)位
0000 0000 0000 0000 0000 1111 1111 0000
0x0000 0ff0
无效的立即数不能通过上面的构造方法得到:
0x101、0x102、0xff1
- 0x101: 0001 0000 0001 (不能通过一个八位常数获得)
- 0x102: 0001 0000 0010 (不能通过移动偶数位获得)
- 0xff1: 1111 1111 0001 (不能通过一个八位常数获得)
特例
但是有时候用出现这种情况,如:
0x3f0
0011 1111 0000
可以为:
- #0x3f, ror (2*14)
0000 0011 1111
或:
- #0xfc, ror (2*15)
0000 1111 1100
面对这种情况,ARM有如下规则:
- 当立即数的值 0-0xFF 时, i m m e d _ 8 = < i m m e d i a t e > , r o t a t e _ i m m = 0 immed\_8=<immediate>,\ rotate\_imm=0 immed_8=<immediate>, rotate_imm=0;
- 其它情况下,汇编编译器选择使 rotate_imm 的数值最小的编码方式。
所以 0x3f0 是通过 0x3f>>(2*14) 的方式获得。
LDR 伪指令
装入 32 位立即数或地址到寄存器
语法:
L
D
R
{
<
c
o
n
d
>
}
<
r
e
g
i
s
t
e
r
>
,
=
[
<
e
x
p
r
>
∣
l
a
b
e
l
−
e
x
p
r
]
LDR\{<cond>\} <register>,=[<expr> | label-expr]
LDR{<cond>}<register>,=[<expr>∣label−expr]
expr 表示32位常数
eg:
ldr r3, =0xFFF
ldr r1, =12345678