版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
$ y) D( Z# F& B) A& w8 C
看优龙FS2410(s3c2410)的bootloader: vivi, 思考摸索了有段时间的问题,代码如何从cpu上的sram中跳到SDRAM中的,从而引发了一连串的问题,此文的目的就是问题之一。5 p: A( \ c1 A& O
代码里会看到如下的指令:
* j8 T9 c% D' F+ Kmov r1, #0x53000000
8 p# ~- ?! P/ |1 r0 m! z3 P而我们知道arm指令是4字节长,上面这个指令光立即数就已经4个字节了,所以,汇编器如何把这条汇编语句变成二进制指令的呢?3 P. ?0 c2 o( {9 q- W6 ~6 `
网络上答案很多,如下,不过原文有点小错误,已经高亮纠正
1 P: B! L" v% O& k- O" M7 `: t6 a, w6 A- Z
原文戳我
! ]" Y' D% R, Y( w! p转载Begin:
% T: m) W5 h! H# ZARM中的MOV指令格式是这样的" d6 ~! _7 g) L! t% Y/ n6 h% `; z
' a B y- z- l5 H+ i9 b3 A! ]
+ o7 d @; a. P
" A5 v; a( f. V1 \2 ^2 C2 I j op2是占了12位,其中bit11-bit8是移位数(rotate),bit7-0是一个8位的立即数(imm),MOV Rn, op2,执行之后,Rn=op2 >> (rotate * 2),这里的移位是循环右移,这就决定了MOV指令不是所有的立即数都能表示的,以下是几个例子:
4 w x4 ?! |/ N5 v! [ r d2 W8 Q7 z8 D
! P! R& H3 e8 h2 \* ~: q! H* U. z9 C% _& A# t0 u4 a7 f- K
1、mov r3, #0x560000005 \) Q# c. i+ i" ^5 i% I" j
( S9 B; s/ [0 z* s
虽然0x56000000是一个32位的数,但是可以找到这么一个8位立即数,通过右移得到,看下机器码e3a03456,展开成二进制,对照下格式
% _6 [* }; w, Q
9 ]* ?7 W1 b" A2 ?) U; u9 x1110 0011 1010 0000 0011 0100 0101 01100 z' ^& k" Y4 [- Y8 f' q5 n
. P7 g# y# V3 Z3 u3 y6 K
cond[31:28]=1110+ U7 j" \, E% r1 |
$ q3 }4 a6 {* \1 X9 n' ?[27:26]=00
9 S* Y$ F; M) D- ]% O4 [" M) `/ {0 \1 Q. N& _# u0 D
L[25]=1,代表op2是一个立即数
0 N/ w: N) ^) a
+ K6 t6 r3 q6 b6 I/ \- A$ p0 s- [OpCode[24:21]=11012 ?9 d! { ]' A
7 O/ N. ^7 _# R; j, c& M
S[20]=01 D; K$ _0 Q( U- L( ^
& G' @6 C8 \$ M' ORn[19:16]=0000
' i0 Z3 I0 B9 p* h! s' `- D) P- W8 S d3 J: W# S2 u5 U
Rd[15:12]=0011,R3/ t) K; x: D a
7 f2 ?* k7 x$ D1 q& \
Op2[11:8]=0100,右移4 * 2位" |; y& v* k% X5 U
* Y8 t1 O, v7 v. {5 EOp2[7:0]=0101 0110,8位立即数,0x561 y$ B% k& l" R! t. X
* K- N. G' _) P4 o# {" J: u ) H5 t* N7 O& {$ Z
- E- f+ u/ ?7 @6 R( o* c2 f+ r首先要将0x56扩展成32位的无符号数,0x00000056,然后循环右移8位,就得到了0x56000000
5 K) a3 |7 o0 j2 c- m& k/ Y- A5 W% i7 F' @' _, B/ d/ d
2、mov r3, #0x560000143 x( `' _4 K) j v
7 P' o( y3 S% j4 V! x" b& v8 G
0x56000014是无法通过移位来得到的,这时汇编器会报错,C语言编写的程序,编译器会这样来处理:/ I" c; K' T, x! U7 ?9 ]" p
6 n8 Y7 {3 g1 W# W ?# E: H
mov r3, #0x56000000
. s) r! o% H q, j$ e. l; y6 X# J; F2 {' V. I' ]& ]& l* e" c2 b, b
add r3, r3, #0x14* m2 Z* V" s0 @+ F! T2 U
* i- q0 l1 {% r8 Y3 W( U
转载End
6 J1 t, \( I( k8 o+ s% w( k
9 n9 o2 b1 `$ j2 V" _9 \明白了这个,也就可以理解为啥会有下面的写法:
4 g; s' b+ B" g1 D9 N& g#define INT_CTL_BASE 0x4A0000006 l l/ ]/ O* P% b) d3 ?; X
#define oINTMSK 0x08
8 \' v8 h, v& R' G#define oINTSUBMSK 0x1C
h' r# r: A' s" B+ T- j* }9 I, e2 g( ~2 U3 |6 |) f
mov r1, #INT_CTL_BASE
% `# J1 D6 Q, N: J- p mov r2, #0xffffffff
, w& q/ N" r3 j+ U& {, Z5 x$ K str r2, [r1, #oINTMSK]
4 f" r! N' _! C; c" } ldr r2, =0x7ff
" i" P" z' t% x4 g str r2, [r1, #oINTSUBMSK]
3 N6 x8 l( L B' |& Y# r; l因为0x4A000008和0x4A00001C不能通过循环右移偶数个位来得到 |
|