版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
/ }+ M: M P! M9 U
看优龙FS2410(s3c2410)的bootloader: vivi, 思考摸索了有段时间的问题,代码如何从cpu上的sram中跳到SDRAM中的,从而引发了一连串的问题,此文的目的就是问题之一。 x+ }. i0 @" Q+ h% w, H, u8 |
代码里会看到如下的指令:
9 {9 h3 O' J& ^2 h: _8 Rmov r1, #0x53000000
# T$ Q' s( R; w0 U. O而我们知道arm指令是4字节长,上面这个指令光立即数就已经4个字节了,所以,汇编器如何把这条汇编语句变成二进制指令的呢?. s. B( C1 {& _- q/ d
网络上答案很多,如下,不过原文有点小错误,已经高亮纠正
, W- o5 u' s8 E6 r, P C* f, J0 Y9 M3 q, Z! n& @/ H0 Q
原文戳我, y0 a; D. N2 `
转载Begin:: n4 j+ m1 ^- m) N2 r. v- A
ARM中的MOV指令格式是这样的4 N5 w- u# o" o9 A
. E. _7 m) x. S$ f g8 k& ]% M4 d1 I0 u: P4 D
) o# t2 \- s6 g* B op2是占了12位,其中bit11-bit8是移位数(rotate),bit7-0是一个8位的立即数(imm),MOV Rn, op2,执行之后,Rn=op2 >> (rotate * 2),这里的移位是循环右移,这就决定了MOV指令不是所有的立即数都能表示的,以下是几个例子:2 I" |- X1 H$ l! I) w$ G- U' K# A8 t
+ {' c `- F) g4 f
% w% D& c/ e6 O9 @, @; z1 D# ~3 p6 x0 z3 @2 X
1、mov r3, #0x56000000
" Q% P# P( M1 l2 ]5 p/ [5 D* D& V$ Z2 O; A6 A& J; }
虽然0x56000000是一个32位的数,但是可以找到这么一个8位立即数,通过右移得到,看下机器码e3a03456,展开成二进制,对照下格式" G- g) C& L$ c2 o
+ G% S. D/ ~$ F, c6 D
1110 0011 1010 0000 0011 0100 0101 0110
4 Y' f! `7 _: E9 m% V: ?7 C6 t# J5 f& c) S. S- f
cond[31:28]=11108 |) l3 z6 H0 |4 w
- n( n' `$ a' f, D[27:26]=009 C; p3 [% }8 N ~
, e4 }& q5 p% l7 o, |& O+ [
L[25]=1,代表op2是一个立即数
8 S% `- P5 E' L2 }! d! p7 m/ ^0 r6 q3 c+ v' c$ S, j, X0 C- r) i
OpCode[24:21]=1101
" z& n8 C2 i5 @+ ~
/ [# \" V/ e: KS[20]=0
# o) q* ~3 T) n8 a9 b. E; `0 N6 V' `2 `
0 i e! z; B& T2 S* \Rn[19:16]=0000
) ~; D0 l! V/ C, T0 D+ W' a$ ^3 h: j$ Q4 X1 B7 A0 j5 a, E6 U
Rd[15:12]=0011,R3
* p9 d* J7 v, T. @5 f' X8 Z
- j' d5 n0 t" ]' [Op2[11:8]=0100,右移4 * 2位
7 R# X, |' H+ \/ ~9 p8 W" z' W! l$ T' |+ u+ i
Op2[7:0]=0101 0110,8位立即数,0x568 m! w) a4 a7 W* u
! g p$ L0 f1 K! g* P0 `
$ T2 j7 c4 X8 k6 S* X% |4 e4 ~8 D" B- w0 b5 U8 ^; F8 e9 J
首先要将0x56扩展成32位的无符号数,0x00000056,然后循环右移8位,就得到了0x560000006 O8 x. ~* I, Y' x" t
- T* i& K8 X: S" I0 b2、mov r3, #0x56000014
7 k7 o8 S, }7 m( T8 ~! o" K& } T2 z& R% ~
0x56000014是无法通过移位来得到的,这时汇编器会报错,C语言编写的程序,编译器会这样来处理:
/ O6 X# _2 V4 r, E! g/ Z9 F* r
0 h6 w3 j" M5 P" J% imov r3, #0x56000000
2 J$ `+ o1 p0 K7 R7 [6 r0 _$ {. y( O B( S7 t% _
add r3, r3, #0x14
0 T, \: A1 L0 Z' G* W" F$ ~/ {0 W4 w2 c. ~- i6 p
转载End
4 B$ s: t4 A: G6 C# u/ k4 X3 A$ y- Q5 r' @
明白了这个,也就可以理解为啥会有下面的写法:
+ C9 e' A8 N4 }: {% K& ]# S# x#define INT_CTL_BASE 0x4A000000* u+ b, h" r9 S6 S9 L$ C
#define oINTMSK 0x08. s7 r8 r5 j9 _6 q' b' o
#define oINTSUBMSK 0x1C
% X4 P& U! O2 v
. w$ @- _# n( @# l# e- S8 [1 m mov r1, #INT_CTL_BASE
0 D0 K. a3 B+ t# T5 i! z; O mov r2, #0xffffffff
0 U' X f( {6 i. u) d) K str r2, [r1, #oINTMSK]
1 ^4 ]% N9 {1 u9 ~: e ldr r2, =0x7ff
3 q% b) Q2 V6 c) O* A* ]# p% P str r2, [r1, #oINTSUBMSK]
7 f ]9 i* K1 H: l3 u) N/ t: Z因为0x4A000008和0x4A00001C不能通过循环右移偶数个位来得到 |
|