一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 4351|回复: 2
收起左侧

ARM MOV指令详解

[复制链接]
发表于 2018-8-21 08:50 | 显示全部楼层 |阅读模式
2 U+ |: |! P: Z
看优龙FS2410(s3c2410)的bootloader: vivi, 思考摸索了有段时间的问题,代码如何从cpu上的sram中跳到SDRAM中的,从而引发了一连串的问题,此文的目的就是问题之一。
1 Z9 T/ Q3 S- {3 P  E7 Z: y8 ]  N代码里会看到如下的指令:
  B6 u0 L% S* @1 @- _& c0 Nmov        r1, #0x53000000  K" @- K% J# Q. ?; n6 ?
而我们知道ARM指令是4字节长,上面这个指令光立即数就已经4个字节了,所以,汇编器如何把这条汇编语句变成二进制指令的呢?
. {( T2 T' M  w3 q$ R网络上答案很多,如下,不过原文有点小错误,已经高亮纠正! N- Z% b. e. o. L7 _; L

/ ~/ H1 `- e3 ?+ f+ D) N4 Q. B原文戳我
9 Y) ]0 \8 c6 B8 u1 o转载Begin:" t$ u5 S; A. {1 W6 M2 p
ARM中的MOV指令格式是这样的4 Y" [* M: S9 R( }2 H% h  _

+ w( Z( H9 h3 C" n- c, i' ?0 O0 N' @$ t

3 R% G$ ?/ A" l        op2是占了12位,其中bit11-bit8是移位数(rotate),bit7-0是一个8位的立即数(imm),MOV Rn, op2,执行之后,Rn=op2 >> (rotate * 2),这里的移位是循环右移,这就决定了MOV指令不是所有的立即数都能表示的,以下是几个例子:9 P1 Y5 d- K" z& W! B# v
8 ?5 g' T1 _8 w( x6 i, ]

4 E. F1 e' b3 f
& P. ]3 \  w$ J: I1、mov    r3, #0x56000000
/ p) g3 @) K1 ?+ J( c# C) G3 L0 @2 T# P, \4 W* Q
虽然0x56000000是一个32位的数,但是可以找到这么一个8位立即数,通过右移得到,看下机器码e3a03456,展开成二进制,对照下格式
- V( C! T/ P4 B7 D& R1 J6 V! F3 S7 v
1110  0011 1010  0000  0011  0100  0101  0110
0 ]5 _% S, `3 i0 n
" v. u2 f/ D* K8 ~3 m4 ^cond[31:28]=1110
) @8 B/ }- U8 U6 o5 G3 y" I
) y5 U. g& {: r7 m( e' S- s[27:26]=00
! z' x( R! I7 k4 c# O
# D1 }! k5 ]& T* j7 ^! }- g4 q: PL[25]=1,代表op2是一个立即数
6 S3 e$ ]. P5 W% e! a' I% @% S( L4 E0 ?& e% U! A" h
OpCode[24:21]=1101
! w& @+ v1 [8 c, _( o" }
6 F2 J* W5 G$ x8 X: {3 ^/ z( \S[20]=0  X/ U( x# s5 j1 s/ c* ]

: H) T  a! d7 A0 |$ T6 iRn[19:16]=0000% U6 l1 N  R* M2 u
* l- w2 l: O3 r. G
Rd[15:12]=0011,R36 r  u* \4 o: ?. y* |* m
+ x# _+ q- D7 b  p, U
Op2[11:8]=0100,右移4 * 2位
  I) S0 ?( o6 e! l. ]# J0 v0 A/ X5 V9 r0 V/ W% E
Op2[7:0]=0101 0110,8位立即数,0x56
8 q0 ?. G$ H0 H7 G' X0 k
4 M) D& b; E- G  Q9 i& K+ o4 |& W
5 p3 c2 b$ l+ D0 @  p4 D  o! y4 V# F5 m5 M# V3 [! B% q
首先要将0x56扩展成32位的无符号数,0x00000056,然后循环右移8位,就得到了0x560000003 ]# U0 C% V% F7 X

2 w" J: T2 Q& [5 T: [0 k2、mov r3, #0x56000014: Y" b* H! B  s
3 b7 O* Y" a5 T
0x56000014是无法通过移位来得到的,这时汇编器会报错,C语言编写的程序,编译器会这样来处理:
, v% ?& E5 T) ]& V- M  j9 }' M0 p
mov r3, #0x56000000
3 x; w$ K& f+ g0 j- j2 l9 j6 x  L# w! a3 i) |6 y0 P
add r3, r3, #0x14/ t) q9 ^0 Z" G3 z

" I8 B( @# m2 Z. w, l转载End
+ N1 I8 {, @+ P" q5 j0 Q
6 G% @9 D6 F) W- @( N+ Z& p; ?5 n明白了这个,也就可以理解为啥会有下面的写法:
4 ~- S' z& G6 i! P- f; k9 c#define INT_CTL_BASE        0x4A000000/ a$ B; |# |0 `# p* ?4 k
#define oINTMSK                        0x086 j; r4 i4 v( \) X) v6 I, `/ b5 }. W
#define oINTSUBMSK                0x1C* }# l9 `/ h8 U6 V; U& x: g
: o3 z& ?% ~+ ]# w; f! H% S
        mov        r1, #INT_CTL_BASE3 d1 G- A! i1 ~, Z
        mov        r2, #0xffffffff9 i8 a5 R% J, I: G
        str        r2, [r1, #oINTMSK]
! G" ]* M& M% L# \        ldr        r2, =0x7ff& x! X! |( e8 M5 q8 O
        str        r2, [r1, #oINTSUBMSK]
, @; ?- ]* L- ^* B$ S/ g0 f9 n( l因为0x4A000008和0x4A00001C不能通过循环右移偶数个位来得到
 楼主| 发表于 2018-8-21 08:51 | 显示全部楼层
一值不明白MOV 为何能超越8位,这下就明白了
发表于 2018-8-22 14:34 | 显示全部楼层
杜春雷《ARM体系结构与编程》,不谢

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2025-4-28 04:12 , Processed in 0.058292 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表