思路
先将一个要存入r0的立即数的高半字(16bits)装入r0寄存器,将立即数的低半字装入r1寄存器,然后对r0进行向左移位,使得高半字到到r0的高半字位置,然后将r0与r1进行或,并将或的结果存在r0.
具体方法
伪指令:
Ldr r0,=0XE0200280
翻译(编译):
MOVW r0,0XE020
MOVW r1,0x0280
LSL r0,#0F 把高16位移到r0的高16位
ORR r0,r0,r1 合成32位的数
如何看参考手册里的指令说明
A8.8.102 MOV (immediate)
……
Encoding A2 ARMv6T2, ARMv7
MOVW<c> <Rd>, #<imm16>
d =
UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
if d == 15 then UNPREDICTABLE;
ZeroExtend的解释(Page 2655)
Zero-extension and
sign-extension of
bitstrings
If x is a
bitstring
and i is an integer, then ZeroExtend(x, i) is x
extended to a length of i bits, by adding sufficient zero bits to its left. That
is, if i == Len(x), then ZeroExtend(x, i) = x, and if
i > Len(x), then:
ZeroExtend(x, i) = Replicate('0', i-Len(x)) : x
注意:在参考手册中,为了对指令功能进行描述,采用的是伪代码的方法,比自然语言简洁、准确,但是在格式上又没有严格的要求。
练习的伪代码:
假如对代码扫描分词后,指令分解为{"ldr","r0",",","=0XE0200280"}
如果第一个词是ldr
如果第四个词的第一个字符是"="
#构造第一个MOVW
将第四个词去掉"=0x",取高四个字符作为十六进制数op1
bit31~bit28=1111
bit27~bit20=00110000
bit19~bit16= op[15:12] ;1110
bit15~bit12=0000
bit11~bit0=op[11:0];0000 0010 0000
#构造第二个MOVW
......
练习的C语言实现
asmldr(char syntaxlist[4][20], int 4)
{
int imm16;
if(strcmp(syntaxlist[0],"ldr")==0)
{
if(strcmp(syntaxlist[3][0],"=")==0)
{
imm16=chartoint(syntaxlist[3][3])
}
}
}
int chartoint(char conchar)
{
int result;
if(57>=int(conchar)>=48)
result=int(conchar)-48;
else if(70>=int(conchar)>=65)
result=int(conchar)-55;
return result;
}