一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

搜索
查看: 3376|回复: 0

GNU ARM汇编快速入门

[复制链接]
发表于 2016-12-18 16:23 | 显示全部楼层 |阅读模式
GNU ARM汇编快速入门, d, i; k7 \& }4 n$ M. U
以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。8 C, x$ C, z( E  t# D$ F

' k) D& ?/ m! Y& y% J8 o8 ]* h- YARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。 8 I  d0 M: {+ k8 Y

/ T) R: B5 S) S0 v目前常用的ARM编译环境有2种:5 u9 ^: k  A2 k) ~* |4 z' Q. m% Y
ARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定;
' K9 ~& U( X+ O+ y! T/ d5 lGNU ARM ASM:GNU工具的ARM版本,与ARMASM略有不同;   X# Z- a# k" G2 P
; B0 b, y* w6 ]0 \2 b' H; Z
关于CodeWarriror ARM汇编的书和文章很多,本文假定你已经完全了解ARMASM,这里只说明GNU ARM汇编,并针对ARMASM给出说明。本文翻译自:GNU ARM Assembler Quick Reference, 本人水平有限,错误难免,转载随意,请注明出处。英文原文地址不详。
& a6 z" R3 W$ J5 ?2 J/ Z6 n7 e( d9 R5 V2 }# h8 F, V" B+ s
' P0 i/ F( A- L
GNU ARM 汇编快速入门- K. F+ G4 s" {. d
任何汇编行都是如下结构:
3 y4 V+ q- F1 x7 d. `# W[<label>:] [<instruction or directive>} @ comment
- x; z; @9 k7 ~- i. k& k[<标签>:] [<指令>} @ 注释% U; A% j( O' t* f$ b( @
GNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段汇编程序定义了一个"add"的函数,该函数返回两个参数的和:5 Z6 z5 @. I! A3 D
.section .text, “x”
& L) R' S: P, F- b1 |0 K.global add @ give the symbol add external linkage' j; Y- X* a4 F) D# C
add:
5 U: c8 a( ^4 q9 H4 S8 }- qADD r0, r0, r1 @ add input arguments5 H3 V& W) R& {( S  B" o# Y+ {& T
MOV pc, lr @ return from subroutine
/ Z1 E( U/ l7 V@ end of program
, b2 f2 P/ `1 eGNU ARM汇编伪指令6 m) x8 W/ h! _/ g

' H" a) y- z2 \$ l5 k下面列出了一些GNU ARM汇编伪指令,并给出了相应说明。# D5 t- r2 \7 L7 L" i

1 [- _2 W8 s2 t* U3 a3 W.ascii “<string>” 在汇编中定义字符串并为之分配存储空间(与armasm中的DCB功能类似)。
% a6 D8 K- N' c.asciz “<string>” 和.ascii类似, 但不分配存储空间。$ o0 ]- q3 o% |
.balign <power_of_2> {,<fill_value> {,<max_padding>} } & O' z) _% z0 N! d7 b
以某种排列方式在内存中填充数值。 (该指令与armasm中的ALIGN类似)。
# @5 d9 O1 e" g0 x# M! @power_of_2表示排列方式,其值可为4,8,16或32,单位是byte; , f( o3 z; z2 f$ X7 w
fill_value是要填充的值; 5 D5 s1 N6 N% \- W8 S$ x9 Q
max_padding最大的填充界限,请求填充的bytes数超过该值,将被忽略。
& O" Q# W9 V6 I% C% u* ]! d, w.byte <byte1> {,<byte2>} … 定义一个或多个Byte,并为之分配空间(与armasm的DCB类似)。  
2 y* h# F; \( I, {.code <number_of_bits> 设定指令宽度,16表示Thumb,32表示ARM assembly
$ g7 G  C( ]' i0 ]% d/ g2 \4 q(和armasm中的CODE16,CODE32相同)。
' C, d: n, P" V' r. U6 N.if  # z* `1 v$ E% e% N1 d8 u' r1 l
.else
* F  v; \+ |& h! l.endif 5 U( l) _" m0 w  C# h% S
预编译宏(与armasm中的IF ELSE ENDIF相同)。
/ a4 u/ H8 h+ v" d. [.end 汇编文件结束标志,常常省略不用。
  F+ l' H4 M2 I" ~$ ]
- k4 ?" q( a/ }$ `4 b.endm 宏结束标志。 & M2 k! s. T# l& o' H; d1 K# q; H
.exitm 宏跳出。
$ z; }4 ]+ Q; K$ ?: `2 p/ w8 Z.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>}
# G/ M' ~/ v1 u+ d0 K% J定义一段名为name的宏,arg_xxx为参数。
- P+ L  C, G& h  M必须有对应的.endm结尾。# X) o& F* a7 |: ?! r3 b5 c9 F6 v
可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。
+ z% {- K: |" j  @3 S在使用宏参数时必须这样使用:“\<arg>”。
* h) K& {0 l$ E$ W8 C例如:
" b4 ^9 b  L- a6 F2 b& r[CODE].macro SHIFTLEFT a, b8 Z1 y1 V. h4 a1 L6 h4 T% s0 e4 q
.if \b < 0* p  ~; u0 [9 M# |7 m. S
MOV \a, \a, ASR #-\b' Z' O) t; Y  I- h5 N
.exitm
9 K4 V0 U% V! P" o0 w.endif
4 ?* K  N+ r* U; i2 a  I. I" Y* ?MOV \a, \a, LSL #\b6 ~& m5 T3 e5 z
.endm- y% u! m; v  e3 }. T
, t1 c+ @; [- w2 ^) `/ ~% v
.rept <number_of_times> 循环执行.endr前的代码段number_of_times次。
# B9 h0 f- z, z3 I; K3 q(与armasm中的WEN相似)
' b5 X& f" _8 j: B% s9 d! I, Z9 H9 T) c. ^! g  q5 Y8 ^
.irp <param> {,<val_1>} {,<val_2>} … / d5 M+ G% p- U* s* ?6 M3 Y' g% N
循环执行.endr前的代码段,param依次取后面给出的值。% _  d  u& Q1 e* h+ c: I* W& c
在循环执行的代码段中必须以“\<param> ”表示参数。3 g8 N8 W% Q7 B* D4 p$ t, n( F

" X% h1 U& d: q' {2 |0 g" t.endr 结束循环(与armasm中的WEND相似).
! q& J7 F5 C# ]5 F2 C% b, C.equ <symbol name>, <value> 为一个标号赋值,类似C中的#define。(与armasm中的EQU相同)
) f  q, p' h* p' e/ Q& `; Z  q.err 编译错误报告,将引起编译的终止。
9 H) X0 ?' @8 w% A.global <symbol> 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。6 v! O) B" R# \
.hword <short1> {,<short2>} …
9 f1 @! C- l* T1 K+ \& ~, G( L插入一个16-bit的数据队列。(与armasm中的DCW相同)
9 ]' H: S( e9 M  ^4 t. m# Y.ifdef <symbol> 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。
2 @8 t/ F2 U8 c8 P' G.ifndef <symbol> 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。
+ M3 M5 G( B* N0 q5 z.include “<filename>” 包含文件。(与armasm中的INCLUDE 或者C中的#i nclude一样)1 V3 g1 m7 p8 ^9 v* q4 }
<register_name> .req <register_name>, @& x: o9 ^. L% W$ V0 ^
定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。
* O. z' Z! w  V5 K' j$ x1 c" U(与armasm中的RN类似)
1 s5 M3 a9 R) v8 f3 s5 l- L例如:acc .req r01 y5 m4 k1 {3 t: V4 ]
[CODE].section <section_name> {,”<flags>”}; f$ j+ U* T% Z
开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。 ' H$ [/ W7 w& T' K; E/ i; q* ^
这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。
/ P3 \* l7 @: c' `+ F: d下面是ELF格式允许的段标志9 g& W5 m8 z4 P0 Q2 S" {+ ^+ q
<标志> 含义
5 C4 k4 z& [0 }" c* W/ R) ]a 允许段! P' `* j  U: u' Y% ^, o
w 可写段% J% ?4 i* K7 o1 d9 d
x 执行段# w: v( ^" N2 l6 M  a  o
.set <variable_name>, <variable_value> 变量赋值。(与armasm中的SETA相同)$ A& P& i. U" d
.space <number_of_bytes> {,<fill_byte>}3 O8 U: @, r/ y
分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。
& U. [$ T6 {& k0 X(与armasm中的SPACE功能相同)
  |* G  j$ `% N$ A+ E/ L.word <word1> {,<word2>} …
. }! ?& x7 s7 g* L- ~6 d插入一个32-bit的数据队列。(与armasm中的DCD功能相同)
: i; O" `: `. t# `! n5 t) R
1 f# N: s& |! n, `( Y' ]. R% xGNU ARM汇编特殊字符和语法% T/ ~- K- o- R- r+ ?8 K2 \% R

* U. K# {" T/ Y  G代码行中的注释符号: ‘@’
* n3 Z/ M0 x$ J0 O' x+ B; D) ^整行注释符号: ‘#’
4 g' E  H* O0 y  @# I语句分离符号: ‘;’+ P; b( b% z) ]( [# H  C$ k8 {" P4 a
直接操作数前缀: ‘#’ 或 ‘$’2 Z  u. q& \; `* ?
.arm 以arm格式编译,同code32
4 m1 q% M  _0 K$ I$ W7 M.thumb 以thumb格式编译,同code16
- J" T4 o) N# @" n# J.code16 以thumb格式编译
" T! O+ L% D2 |- V" Q.code32 以arm格式编译# T  X" K1 Q( U. T
篇后语:
- n9 ^6 K, e# Q( V  d& s+ r* A7 b- Q4 N; Z
更详细的使用说明请参照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-11 m% T& m7 L# C. D; S# [4 c  v" q
补充:
+ h6 L7 j9 R$ ~6 J4 B( o& }7 A. g7 V. Y5 K) v) X
4 ARM GNU常用汇编语言介绍
+ k6 e- T( y. T  M$ T4.1 ARM GNU常用汇编伪指令介绍
* F3 e# |6 C1 @, c& Q! i1. abort- C4 u/ u4 X+ J: w& d$ B
.abort: 停止汇编' `: X+ @. @5 x
.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第
8 o2 n" Q) m8 J' `9 B( k# [( k/ ?二个表达式值表示填充的值.
  n- n, e9 e  f2. if...else...endif
/ @% ?) j( ?. C: X9 P7 i2 Z: q: w.if! C+ ~; n  U# Y8 _7 U; s+ b/ c& ?
.else* i" ~/ n( Q. \. r) H- h8 f" a! P! K
.endif: 支持条件预编译
) O6 B- Q/ w7 J3. include
, D4 e& t4 g  o/ t6 U.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.% i2 ~2 C8 q% x* H( D0 n
4. comm
: T# X( S! `8 Z: H2 Q.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length.      Ld连接器在连接会3 N: P3 C0 S3 S/ ~7 E
为它留出空间.7 g0 F& q  H; ~1 U+ ^( B! e
5. data
/ k3 h9 X7 F  M5 o.data subsection: 说明接下来的定义归属于subsection数据段.) ~3 N4 a; y. H# n$ Y  h- z
6.      equ
3 r+ X# |. _8 j/ j.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.
. r  s* ~5 A( Y7 N( o7. global' A' }8 x9 Y! A! {# F
.global symbol: 定义一个全局符号, 通常是为ld使用.& i( w% \  [7 c7 ]6 I
8. ascii
9 m2 H$ B0 g' e+ |" K+ y2 J( h.ascii "string": 定义一个字符串并为之分配空间.  U. c* p) |; M' J* ^( V' |) v
9. byte( [5 E4 A5 F% v) p& p
.byte expressions: 定义一个字节, 并为之分配空间.  @! u8 v9 m& M; ?, r
10. short
& s0 W0 M$ u4 G( O.short expressions: 定义一个短整型,      并为之分配空间.8 M  J1 |. _7 C; D3 N% \9 ?+ C5 I
11. int
# ]( R; p2 u' \" Q.int expressions: 定义一个整型,并为之分配空间.) l6 ]1 {# C* i8 G  q/ i4 ^
12 long
% v" e3 l6 G2 |. f! N) c.long expressions: 定义一个长整型, 并为之分配空间.! E8 f9 Y7 O: r1 Q2 T- X; F3 g
13 word* ~: n9 p( j/ {" m: Y+ q/ Q
.word expressions: 定义一个字,并为之分配空间, 4bytes.- S) ]/ |4 L) r
14. macro/endm2 o  a, R0 j; j1 F5 Q2 \) \" c
.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.
+ ]. e9 K5 u6 ~! _9 H15. req! @1 a" l( J& N: n+ ?" T+ G
name .req register name:      为寄存器定义一个别名.
$ P! Y& p+ q* e$ ~3 G1 O4 D16. code
1 s7 K: Q/ W7 X1 O.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令." n- p1 P0 ^9 Z
17. ltorg# `0 z' d: P& L% _" ~. v3 X% @  {
.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.
4 {1 F& E2 f  v6 z6 l$ T4.2 ARM GNU专有符号( M/ A4 n8 }- X& e, j+ N  P
1. @9 [# A. a" H% A' x" |- M  Y( y. c
表示注释从当前位置到行尾的字符.9 B( r, c* R* B. z! |& t
2. #' L% K+ k# |3 r8 Z* d$ Y
注释掉一整行.5 Z8 U" D$ \* L. \6 }, T. ]
3. ;8 Z" \0 {( A% K, ]
新行分隔符.' l7 o& B7 {3 R5 n8 q' l3 A
4.3 操作码* U" u9 W- i0 G/ R1 k& I
1. NOP
* V/ `7 l( g0 ]$ x       nop
7 P7 ], q8 T! H6 j, Z. z* e( E       空操作, 相当于MOV r0, r0/ E( p; Y8 o8 D  c
2. LDR9 a" P+ k8 R, }& D! _
          ldr <register> , = <expression>$ H+ U. b2 Z9 D' T& n
       相当于PC寄存器或其它寄存器的长转移.
8 c% q2 [0 P% [/ e) S3.ADR
" w( A' i- n5 R4 B8 }1 w          adr <register> <label>
; n4 B: g8 Y1 G, D( K- E       相于PC寄存器或其它寄存器的小范围转移.
7 d% m, Q, r/ P7 S8 @1 Y       ADRL) G+ V6 K; o- K7 t0 ?; Y( j- `+ l
          adrl <register> <label>
: Q  u  v& c- y3 Y0 ?9 C       相于PC寄存器或其寄存器的中范围转移.
6 F% t4 n. |, t. Y' z1 b2 X) J& i
原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx
# |/ v0 g, G7 i  @. h& [" k8 ^* _: u# X: q

1 P( A6 D+ B2 o9 j: \$ c4 `& k6 W2 {5 B7 h0 o' a

本版积分规则

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

GMT+8, 2025-8-20 09:02 , Processed in 0.035232 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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