版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
GNU ARM汇编快速入门- T; _5 Z9 J. W M4 f, F, |
以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。
' |$ W4 u) U+ r
; u5 H, c$ H* ~/ zARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。 , s3 K1 A* A4 A& H# @
. f# L* f3 `- n3 O
目前常用的ARM编译环境有2种:
5 l7 _. B0 r: g8 |! ?9 IARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定; # A0 E/ t1 f9 ^% u3 a
GNU ARM ASM:GNU工具的ARM版本,与ARMASM略有不同; 6 |) }% l& K8 H0 K1 S* b/ p, l
: ~& Z J* R# i, P: G# T/ v9 P
关于CodeWarriror ARM汇编的书和文章很多,本文假定你已经完全了解ARMASM,这里只说明GNU ARM汇编,并针对ARMASM给出说明。本文翻译自:GNU ARM Assembler Quick Reference, 本人水平有限,错误难免,转载随意,请注明出处。英文原文地址不详。
8 g0 W* ]2 e+ ~4 u0 P( X6 [; X8 m ~- Q8 @
6 w1 D8 Q5 v& l1 ^: C9 gGNU ARM 汇编快速入门
. X5 ?8 g( Q7 M. c. Z9 M; N" c# l任何汇编行都是如下结构:. `3 I; p' L7 {% Y& I
[<label>:] [<instruction or directive>} @ comment
9 L" k& {' V( T- L- z[<标签>:] [<指令>} @ 注释
n9 j. s5 p; o8 QGNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段汇编程序定义了一个"add"的函数,该函数返回两个参数的和:3 |7 W7 V* m4 C: ~$ t3 B1 I
.section .text, “x”
: _. a0 } T2 F# R. s$ @8 ]& Q.global add @ give the symbol add external linkage
2 D5 ^6 H Z, \add:, h& [; f6 N& I& _7 n$ t4 G# g* W
ADD r0, r0, r1 @ add input arguments
; G3 z1 R+ G: v( I% \' r7 eMOV pc, lr @ return from subroutine
9 J2 H$ @# e/ K@ end of program+ M% o( v- [7 a3 q
GNU ARM汇编伪指令. b5 X5 g- |$ s5 p! U
# x1 a" p& |. t. W+ a5 t
下面列出了一些GNU ARM汇编伪指令,并给出了相应说明。0 M9 D! i4 y% @
* L5 d$ v+ \4 G9 ?2 `.ascii “<string>” 在汇编中定义字符串并为之分配存储空间(与armasm中的DCB功能类似)。
' E" [! d. M2 T* ?4 q8 m5 i.asciz “<string>” 和.ascii类似, 但不分配存储空间。
0 ?% S! d) m/ I.balign <power_of_2> {,<fill_value> {,<max_padding>} } , u& F, G# B/ v) {) t$ ~& S6 N
以某种排列方式在内存中填充数值。 (该指令与armasm中的ALIGN类似)。7 A, G. P6 p/ G
power_of_2表示排列方式,其值可为4,8,16或32,单位是byte; $ k* r$ H7 s( t( Y: B/ f
fill_value是要填充的值;
7 ^* U9 N) z% e9 ?: pmax_padding最大的填充界限,请求填充的bytes数超过该值,将被忽略。
. [; r' g6 Q* a9 U! a1 q+ V.byte <byte1> {,<byte2>} … 定义一个或多个Byte,并为之分配空间(与armasm的DCB类似)。 : A& J3 G/ j% j- j; T3 E4 T
.code <number_of_bits> 设定指令宽度,16表示Thumb,32表示ARM assembly
8 w x8 Y' l8 w& h6 J: ?* k {(和armasm中的CODE16,CODE32相同)。
/ d7 ^% B% l! Q.if $ l' p" c2 g7 _8 b% l# j
.else 5 ^( e% P! U3 n' g7 M
.endif * L# I8 }6 Q3 f6 Q7 d
预编译宏(与armasm中的IF ELSE ENDIF相同)。; y2 V+ g/ q6 z1 }( o8 b
.end 汇编文件结束标志,常常省略不用。
* }# r( }" j ?3 n0 F+ Z4 `0 a! p' |% x( N
.endm 宏结束标志。
5 T) n& t5 v) G.exitm 宏跳出。 0 b' @, C; \/ S: _
.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>} 1 t; g, {8 V2 P$ u& i. \
定义一段名为name的宏,arg_xxx为参数。
# _1 Z# j( B- X( l4 c7 R& e+ B# V) W必须有对应的.endm结尾。6 H- Z, d2 D4 X% ?4 ]+ X
可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。
" U1 w5 K* N4 @- c3 `& P在使用宏参数时必须这样使用:“\<arg>”。: H8 S4 q \8 c3 j5 ?
例如:
, F+ I9 U7 i: h2 T$ h% T! P7 Z) n6 H D+ G[CODE].macro SHIFTLEFT a, b
: I3 O- N" T; i8 d/ W$ g.if \b < 0
" }/ V5 H0 r. Q3 P% I8 qMOV \a, \a, ASR #-\b
: M& z- Y' z, K7 c$ I5 }0 I- ?7 D.exitm
# P' K! [, I( n0 Q.endif
. @) U( u4 i% R% p9 ^MOV \a, \a, LSL #\b" d- w, o5 b8 \1 f) s+ O
.endm* a/ A3 L, O8 i$ D" h4 C8 l+ l3 c- C1 j
$ N' `' S) Q% H
.rept <number_of_times> 循环执行.endr前的代码段number_of_times次。8 W$ J5 s$ C- e" T; q
(与armasm中的WEN相似)
/ z4 t- ]. g' ]6 O& b
" i4 \! v M: k* Y.irp <param> {,<val_1>} {,<val_2>} …
* n, h) T |2 m. ^" N循环执行.endr前的代码段,param依次取后面给出的值。/ s5 D0 w7 K4 F* V
在循环执行的代码段中必须以“\<param> ”表示参数。 Q' S+ G- g6 v0 h: t8 l" S
; s, i6 t" O, u0 O' ^.endr 结束循环(与armasm中的WEND相似).9 f3 Y$ \6 E2 U6 X3 W
.equ <symbol name>, <value> 为一个标号赋值,类似C中的#define。(与armasm中的EQU相同)
; }- u- I; y( U/ u% {- R! a, w$ ^.err 编译错误报告,将引起编译的终止。- ]0 _* \6 {9 I0 c
.global <symbol> 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。
+ r1 c9 k1 e: O6 N5 Y2 H.hword <short1> {,<short2>} …
* `: y5 q. l2 F3 ]* j插入一个16-bit的数据队列。(与armasm中的DCW相同)
& @% E8 o1 O4 R! f2 O2 H9 L.ifdef <symbol> 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。9 ^! Q% a+ L. D) r5 _
.ifndef <symbol> 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。
1 n& H) K. O: R" h, h5 {3 S.include “<filename>” 包含文件。(与armasm中的INCLUDE 或者C中的#i nclude一样)
: n; J9 k1 z7 `( ]! E<register_name> .req <register_name>4 U l! x. l7 A2 m7 ?. ^
定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。$ P w- |7 t, [; a1 T
(与armasm中的RN类似)
9 c1 G3 J8 K% [+ u% _7 g# f& D) ~0 W+ H例如:acc .req r01 j7 W9 S2 t. h, `, n
[CODE].section <section_name> {,”<flags>”}* ]8 T! b2 i+ M
开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。
! K2 K- w/ N( Y8 i4 J7 g+ [这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。- `& w! R" v9 A3 C# P& B
下面是ELF格式允许的段标志5 s" n- q; W# N
<标志> 含义" n8 j$ f- c+ g& ~* X
a 允许段' J4 ~3 T$ U6 J2 l9 A
w 可写段/ _9 V! d8 @) u. n1 Y
x 执行段" k d9 [' `8 }# I# q% b
.set <variable_name>, <variable_value> 变量赋值。(与armasm中的SETA相同)
1 F0 v2 v& ]8 r) b; D% f( z.space <number_of_bytes> {,<fill_byte>}: s3 y4 V8 f* o/ T" X
分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。
# ^4 X0 ?5 y6 i; c; |5 v( ^8 L" ~/ }(与armasm中的SPACE功能相同)
3 d* S, |2 X0 ]7 _" f5 K9 @+ N.word <word1> {,<word2>} … 2 B: H# H: c4 y7 Z
插入一个32-bit的数据队列。(与armasm中的DCD功能相同)! l& i x9 M! D4 H* t
5 }) r8 z5 w$ c+ Y& ~" F
GNU ARM汇编特殊字符和语法6 Y4 ^% e# H" f' ^4 E$ Q- h
$ O% u+ V7 x; H2 K代码行中的注释符号: ‘@’) H: a* v( y- @8 {) F8 y
整行注释符号: ‘#’
9 u$ z+ k7 d* e# `语句分离符号: ‘;’$ Q. O* [0 f2 e
直接操作数前缀: ‘#’ 或 ‘$’/ g, @% ?' \: O2 X, n
.arm 以arm格式编译,同code32
- |& t; ?' i+ v1 m, g0 n/ B.thumb 以thumb格式编译,同code16! | \$ W: x6 q4 p
.code16 以thumb格式编译
& m* v7 d7 |; O1 i5 r$ s* l.code32 以arm格式编译& `' S6 B- R2 D/ u
篇后语:! X. s5 [+ h3 ]; a
2 ^& \+ W5 Y0 l; f r9 I更详细的使用说明请参照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1, ]% ]/ U% {$ m S
补充:1 k% ?: l4 Z) n' e/ h
8 h& I6 U- n, K: n7 J1 ?
4 ARM GNU常用汇编语言介绍 O; Y" [' a z) q/ C
4.1 ARM GNU常用汇编伪指令介绍
& z: ]9 X& Z) s8 J2 m# R N/ l1. abort
+ M4 [/ N$ R2 z* }8 }.abort: 停止汇编
" p3 }& Q1 g, A.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第9 G) d* `6 ]/ L# @- @" y4 k
二个表达式值表示填充的值.% `. m! _/ C _- X# O4 G5 f
2. if...else...endif: D/ U6 T6 W* }* Y p2 c- l
.if5 H/ @0 T! A+ ]5 S6 U
.else
+ Z+ i) N0 p( A) n.endif: 支持条件预编译/ _; M) Z8 j3 P& z
3. include
, z5 ^2 P6 U5 I% f/ q1 N/ k.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.
6 f: X V# ?4 x, ]6 Z: H4. comm
- y: c8 ^! V* d! b' i.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length. Ld连接器在连接会1 |5 y" ~2 P7 o& \) I9 F
为它留出空间.
1 T" \+ b1 f: ]2 ]5. data0 [2 Z& C& H* @8 y; ?- n2 R$ q
.data subsection: 说明接下来的定义归属于subsection数据段.* u' |' i8 _- l1 ^9 W- m8 G
6. equ, S; h: F6 W/ E9 k9 ?
.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.
/ S7 Q- ?# `; l0 Y8 h7. global/ [" ]- M# K D1 [5 u3 Q& Q# i+ D
.global symbol: 定义一个全局符号, 通常是为ld使用.
, w$ _; k$ r. p2 X8. ascii
: r5 M) g z6 Y" Z) x* {1 e2 I.ascii "string": 定义一个字符串并为之分配空间.
& G, o& r2 V0 Y5 t3 f: h5 o9. byte
' a1 h6 ?% Y6 m3 Z.byte expressions: 定义一个字节, 并为之分配空间.
4 v R: e( C% U- y3 y10. short8 K, C" C& H/ T7 g6 _
.short expressions: 定义一个短整型, 并为之分配空间.- g( M$ w2 n8 M& b& ?/ P; n
11. int6 o! `% Q3 u; V5 p. ^/ a/ ]; A
.int expressions: 定义一个整型,并为之分配空间.3 J- x% X! \9 g, K
12 long. d: ~/ j) ] J( `- s' c4 X$ T6 Z
.long expressions: 定义一个长整型, 并为之分配空间.
& H4 v9 u9 } o& K- [' Y13 word
5 l' E2 K! n/ i1 S" d.word expressions: 定义一个字,并为之分配空间, 4bytes." r7 u$ t, }; ]& G
14. macro/endm
. w7 V2 S% E' _5 e7 ?6 X+ X* d$ U.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.
) w g; E8 T! k. o4 }15. req# I% h! F" s R: j3 w% I
name .req register name: 为寄存器定义一个别名.
! t. I( E( j3 H& ^! t$ S16. code
; G3 d9 c: R; ^( u+ Z% |3 A.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.
" }* |7 c- K2 p4 ^0 |2 L+ b% F17. ltorg
$ m' M" T, I5 r$ A.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.
+ `( H$ J, s) ?. ]; y6 ]4.2 ARM GNU专有符号
# _( `: [" N/ Q8 ]5 y/ `1. @
, s1 [4 |; R8 s4 Y T2 p* E表示注释从当前位置到行尾的字符.
# b- T/ @- w- {2. #2 @% G& H8 S3 B9 Q( ^* R N' v
注释掉一整行.3 @( }# Q# t# g- T) [
3. ;
0 K5 [/ o n4 F$ O' O: Z" M6 ~新行分隔符.
- I+ P( _6 a* r4 W/ L4.3 操作码
4 y1 B/ D0 u8 U% i1. NOP, n5 _) k1 W+ F% x/ L0 A0 U
nop
q; p& P, p1 ]) t U8 N. h 空操作, 相当于MOV r0, r0
/ C/ ?( r( r% P2. LDR+ A8 N! I0 O6 q
ldr <register> , = <expression>
. S8 I. }4 @4 |& p 相当于PC寄存器或其它寄存器的长转移.
% W1 n% Q2 P7 ?2 I1 Z; |3.ADR
- C( z2 ^3 d4 Y4 ^! @5 [' @ adr <register> <label>4 y# F, g3 M) X# r+ l
相于PC寄存器或其它寄存器的小范围转移.; o3 {* \1 R# `. h6 R
ADRL7 x0 d0 g- X4 ]
adrl <register> <label>* U2 W, S: t" U6 T: v0 \
相于PC寄存器或其寄存器的中范围转移.3 @+ y. R# G& a& I/ Z0 I3 n
H/ x$ ]" ^# \" ^1 H7 q* o+ g原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx
, t6 K/ M, S9 Z5 \: F' k- K
& w% U$ {2 M- y# |( H: y% q3 x, c( W; _+ F4 O
: W1 Q# l7 N4 A4 o, b# r
|
|