一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 5727|回复: 2

ARM MOV指令详解

[复制链接]
发表于 2018-8-21 08:50 | 显示全部楼层 |阅读模式
2 ]* ~, F- M# G, O/ T0 t
看优龙FS2410(s3c2410)的bootloader: vivi, 思考摸索了有段时间的问题,代码如何从cpu上的sram中跳到SDRAM中的,从而引发了一连串的问题,此文的目的就是问题之一。
; E4 x* ]* B- h代码里会看到如下的指令:
" C4 ]! S; m: r, E6 p% lmov        r1, #0x53000000
/ s" _8 v7 H& [% H7 R" n而我们知道arm指令是4字节长,上面这个指令光立即数就已经4个字节了,所以,汇编器如何把这条汇编语句变成二进制指令的呢?
- C' @, D/ P" ]$ d. b网络上答案很多,如下,不过原文有点小错误,已经高亮纠正* b/ b; N- K' ?
' }$ L6 ~7 P+ T, ^: k
原文戳我
: {! p. `2 k, e$ e转载Begin:8 U3 m* m# U5 |! e; D- A5 M
ARM中的MOV指令格式是这样的
0 q! M6 x7 O" f1 N, F
7 u# m) D; P+ _8 [: a' ~* R  z- r  ~  C
: R# R" {  h. D) Z$ M" z5 H
        op2是占了12位,其中bit11-bit8是移位数(rotate),bit7-0是一个8位的立即数(imm),MOV Rn, op2,执行之后,Rn=op2 >> (rotate * 2),这里的移位是循环右移,这就决定了MOV指令不是所有的立即数都能表示的,以下是几个例子:: ]- |3 K5 _$ `, t

; u# M' q8 R: ? 5 e% @6 c! u! Y( ]# V0 P$ ^
! b( d2 ]* I% D4 E- Q3 r7 s
1、mov    r3, #0x56000000
1 M- T# V8 z8 A+ r& K" h5 H' B. m3 ?" i% E4 s
虽然0x56000000是一个32位的数,但是可以找到这么一个8位立即数,通过右移得到,看下机器码e3a03456,展开成二进制,对照下格式
, y- e" m& s* X( n5 q3 |0 J* a9 j) c( B  M; h1 G
1110  0011 1010  0000  0011  0100  0101  0110
; A8 I2 U7 I# X; v1 L3 R) C- \* O% w& L  n3 K6 R6 d
cond[31:28]=1110
( j5 {+ s4 Y6 ]. Y" ~& R; C3 _4 S! ^6 w7 f, B4 I
[27:26]=00  O! B* X# j( C  j# p* e1 W4 |  l: s
3 v; R3 F: J; m  V: ~# k
L[25]=1,代表op2是一个立即数
; l+ U% g6 l% @- P. i0 W; H
4 A/ C! R7 B* B0 JOpCode[24:21]=11013 e7 g' v/ X, e8 D9 _: l; X
& I* Z- B& P& r! C( J( }8 c6 i
S[20]=0
' n, e5 T& P( U1 P6 Q! M( a% ?5 |* m: @* r, d$ N1 G
Rn[19:16]=0000" z6 N; _- f* B; }& ~. T1 w$ ]
& |; P% W; x7 m) p4 ~8 P
Rd[15:12]=0011,R3
3 ]3 C* K; B% K; h0 ^, R& ^, m. d% _& E1 G0 J, X  M3 Y1 z
Op2[11:8]=0100,右移4 * 2位2 N1 \3 R2 ^6 d" {7 H2 a' |7 v/ K8 d

! t! Z$ g; ~+ {' L. s5 YOp2[7:0]=0101 0110,8位立即数,0x56
$ e4 s' r3 i3 ?/ m1 @4 p) n% N/ i
) f3 {1 l  l/ @
6 Q- ?  A$ a. O4 q1 N2 Q/ r0 }" F8 e" n& m
首先要将0x56扩展成32位的无符号数,0x00000056,然后循环右移8位,就得到了0x56000000
5 B0 R4 n; ~% h+ L0 T/ x$ ]& k. j" Z. Z5 A1 s0 _1 u
2、mov r3, #0x56000014
% l/ l# K9 y. E- w( g4 @: Y
6 t% C1 p6 z8 E8 v" z0x56000014是无法通过移位来得到的,这时汇编器会报错,C语言编写的程序,编译器会这样来处理:5 R. [7 ~: r- M" @* r
7 L5 k& {/ A1 t% F) R
mov r3, #0x56000000
, L& O# p# V" M. G8 a, l8 Z' n! |1 _: b5 V. W- G$ M
add r3, r3, #0x14/ [' E$ D& G( [0 w7 l; V% t
+ S$ ?- B" N9 q" U% ]% M$ U8 h
转载End: V- m5 P( I1 N+ D0 h
4 P" o, a5 V' C3 S. h' V
明白了这个,也就可以理解为啥会有下面的写法:
( ~5 S1 n; g; f) d5 @#define INT_CTL_BASE        0x4A000000
1 j4 M: e9 c3 O  t8 t  w#define oINTMSK                        0x08
1 u. e$ W+ E. ]8 H, e! a: }#define oINTSUBMSK                0x1C
* Y4 i! @9 G3 \) C  g6 E. t" f+ x5 R, U3 _* _+ V8 a$ f& N2 K
        mov        r1, #INT_CTL_BASE  v! T( f( X, X# t& \) z& p1 T, E
        mov        r2, #0xffffffff3 }: d, G  ]5 H; h/ s: s1 g  m& d, A2 Y
        str        r2, [r1, #oINTMSK]
) z% ]9 Z9 j, C        ldr        r2, =0x7ff5 ?3 c, |9 c8 g6 D+ d4 }
        str        r2, [r1, #oINTSUBMSK]
0 G# L5 r+ x: I' k+ C因为0x4A000008和0x4A00001C不能通过循环右移偶数个位来得到
 楼主| 发表于 2018-8-21 08:51 | 显示全部楼层
一值不明白MOV 为何能超越8位,这下就明白了
回复

使用道具 举报

发表于 2018-8-22 14:34 | 显示全部楼层
杜春雷《ARM体系结构与编程》,不谢
回复

使用道具 举报

本版积分规则

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

GMT+8, 2025-12-16 03:43 , Processed in 0.029307 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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