一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2616|回复: 0
收起左侧

GNU ARM汇编快速入门

[复制链接]
发表于 2016-12-18 16:23 | 显示全部楼层 |阅读模式
GNU ARM汇编快速入门5 ]; _: p5 F5 L, L
以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。
9 n2 l* T& m% p5 ?7 F! w# b5 M! c
ARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。
0 p$ c- s9 @+ ^( U% Q% A; {! G& n- |& w7 h# l8 H3 h- `8 f
目前常用的ARM编译环境有2种:
3 g; K# e& b# m$ Q: P+ z# D/ [% ^- WARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定; . u% k- ^$ s( n! z. N
GNU ARM ASM:GNU工具的ARM版本,与ARMASM略有不同; ! o: j3 ]6 A1 b6 Q, Q- D- A
( }3 o( v4 d2 l
关于CodeWarriror ARM汇编的书和文章很多,本文假定你已经完全了解ARMASM,这里只说明GNU ARM汇编,并针对ARMASM给出说明。本文翻译自:GNU ARM Assembler Quick Reference, 本人水平有限,错误难免,转载随意,请注明出处。英文原文地址不详。 ) B2 [/ ~. L7 K1 T8 C, ~* i( z9 s

# a5 B. U) [2 @* ]" r- G+ N& B; n. B2 p9 @4 ]% w& ^
GNU ARM 汇编快速入门
" @2 D/ {7 k6 u$ K: L任何汇编行都是如下结构:7 e/ b2 V! k3 m# t. R
[<label>:] [<instruction or directive>} @ comment0 y" k5 w: {7 r- |- P! ?+ b
[<标签>:] [<指令>} @ 注释) A1 }: P7 `% F" ^% D" d2 x
GNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段汇编程序定义了一个"add"的函数,该函数返回两个参数的和:* F$ r3 E# C! I9 S
.section .text, “x”
; Q  w5 b% d' X9 Z& n: x# ?.global add @ give the symbol add external linkage
: d; V* B5 L- C3 p3 G1 Madd:
; g' q/ u7 F8 k4 w; m: \ADD r0, r0, r1 @ add input arguments
) f9 h! N8 b  ]; @$ `4 ?- N0 g7 hMOV pc, lr @ return from subroutine
$ l! e5 J6 U  b$ B@ end of program0 V. S' E  Y5 ~: |
GNU ARM汇编伪指令
4 `! {5 [( M6 a7 ~: L  w$ c3 R4 O6 q+ l7 v2 q
下面列出了一些GNU ARM汇编伪指令,并给出了相应说明。1 ]: R; K9 y# R* h5 E
2 _" k  {8 j" e
.ascii “<string>” 在汇编中定义字符串并为之分配存储空间(与armasm中的DCB功能类似)。 8 S. g' }3 a8 Y& {9 S
.asciz “<string>” 和.ascii类似, 但不分配存储空间。
* h; F8 g0 y( o' W/ v.balign <power_of_2> {,<fill_value> {,<max_padding>} }
8 p: E* g$ B% j0 C+ f5 }以某种排列方式在内存中填充数值。 (该指令与armasm中的ALIGN类似)。
  `; s$ e. m: b2 [) ^* X. E- X2 ^% M9 ]9 Jpower_of_2表示排列方式,其值可为4,8,16或32,单位是byte;
+ x0 J$ v& {2 }! e- q$ _) Jfill_value是要填充的值;
9 c7 t) {  |0 }+ y/ G, O+ Umax_padding最大的填充界限,请求填充的bytes数超过该值,将被忽略。
* Z/ v8 H' d9 y/ ~5 u.byte <byte1> {,<byte2>} … 定义一个或多个Byte,并为之分配空间(与armasm的DCB类似)。  
( m9 N- u; R2 ~  ^+ @" M4 N( h* P.code <number_of_bits> 设定指令宽度,16表示Thumb,32表示ARM assembly - P+ {- Q5 @; ?: b1 V
(和armasm中的CODE16,CODE32相同)。
1 ?1 L+ W3 H  N.if  
3 o  T( b$ e) \* |.else
# b) L2 C9 [! o1 b$ e  S  P; A.endif ( b8 r3 m5 v' n" E6 |9 T
预编译宏(与armasm中的IF ELSE ENDIF相同)。
: J( J$ R+ l. f) s& d2 c.end 汇编文件结束标志,常常省略不用。
: T0 I. ^. f2 _( d% d
" ^. q2 r6 k1 h) S) j- J! p0 e.endm 宏结束标志。 ' z& w/ ^6 B5 ?$ p: ^; d
.exitm 宏跳出。 - Y7 B5 d6 }* b& F4 g6 D
.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>} % i0 V' y7 v6 S' i7 o
定义一段名为name的宏,arg_xxx为参数。
0 ^' h. `4 A, y+ v9 e必须有对应的.endm结尾。$ q* \. L) V0 ^4 Q" }7 w* G
可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。
# S4 x8 V9 A, d; j* f! X( a在使用宏参数时必须这样使用:“\<arg>”。- r  L2 u5 q2 c: p0 t% f/ m
例如: 5 g* S. s4 N- D/ T( K# ~& e7 ~
[CODE].macro SHIFTLEFT a, b
2 G4 S$ [, J4 j9 T.if \b < 0
. Z, E; u3 O" ?9 i7 HMOV \a, \a, ASR #-\b' J( l8 y% ]& B' w' F% b
.exitm
0 o+ C' P  p: T7 X: S: j4 ?.endif/ n# P3 G* @1 ~' n. ~6 X2 {) Y3 B+ b) u
MOV \a, \a, LSL #\b
+ ^! I* q& p4 Z8 _.endm' L- [: i; J7 g! j  t- Y' f

$ o' T$ g$ c; k/ R& ?9 H1 ].rept <number_of_times> 循环执行.endr前的代码段number_of_times次。
) Z1 S6 a7 c# H5 ~- A) p- h- _(与armasm中的WEN相似)& i( y4 m! C1 p

7 w( b5 B3 `$ }5 |.irp <param> {,<val_1>} {,<val_2>} …
1 T: m4 Z, x; M, r7 e* u5 q1 {循环执行.endr前的代码段,param依次取后面给出的值。1 I! E$ F0 b3 z- D9 U
在循环执行的代码段中必须以“\<param> ”表示参数。
' c( Z- a1 k4 _* b
* W4 I5 B2 L6 M.endr 结束循环(与armasm中的WEND相似).* u& o$ ~) Y; u2 _
.equ <symbol name>, <value> 为一个标号赋值,类似C中的#define。(与armasm中的EQU相同)
% W& E% I4 ]8 P.err 编译错误报告,将引起编译的终止。
. f% b& {2 a9 t" R: u5 h.global <symbol> 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。. f, G5 P5 @1 A4 J# n1 e# Y
.hword <short1> {,<short2>} …! o: `3 f1 U' m
插入一个16-bit的数据队列。(与armasm中的DCW相同)
3 e) b  O5 b; G# ].ifdef <symbol> 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。
6 K3 }2 }7 Z% W& }8 N& G.ifndef <symbol> 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。
7 P) A$ a, V# f$ z  _/ W( P$ n.include “<filename>” 包含文件。(与armasm中的INCLUDE 或者C中的#i nclude一样)
" ], {) a( [5 B" F- R<register_name> .req <register_name>( n" t, ?  ]7 R' T  T$ h
定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。
( z2 {, g/ S# l(与armasm中的RN类似)# ^& |2 [. ]* j" V2 M
例如:acc .req r0
" c2 W* s8 u, n[CODE].section <section_name> {,”<flags>”}
. P' t) v/ W) `+ Q( W1 q开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。
% c( R9 K6 `4 e这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。
: Y/ M* x! a2 e" i- ^- @下面是ELF格式允许的段标志% [  D% X5 L% ~/ D! F2 i5 \6 i
<标志> 含义  f6 {! A1 s( N6 g6 W4 I% @0 `) u
a 允许段9 m! H" p1 B9 @; x+ T0 W
w 可写段& d3 Z7 X1 r& U2 }+ s- l5 e. f
x 执行段
# `& C9 E! h7 A1 ~$ B! w. ?.set <variable_name>, <variable_value> 变量赋值。(与armasm中的SETA相同)
5 d9 k! \. E* y* e) N.space <number_of_bytes> {,<fill_byte>}
* D$ [- M& C; |4 E9 o分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。
" w- Z+ B; \- \' k9 [(与armasm中的SPACE功能相同)" r* z* h* X  B; u# d, N  I
.word <word1> {,<word2>} …
9 `8 D( K7 z; _8 H4 N插入一个32-bit的数据队列。(与armasm中的DCD功能相同)
1 R5 q" x. Y* L7 ]
8 g' T0 b4 ~( V8 @GNU ARM汇编特殊字符和语法: `/ z  \/ Z5 C  I1 P$ l+ R1 M3 p% k

4 f: Z- ~' ~# w/ ]/ [! j9 M代码行中的注释符号: ‘@’0 O8 n# M3 z$ c" D) L9 C
整行注释符号: ‘#’; Y0 t+ f5 f9 z2 `+ o6 X
语句分离符号: ‘;’; y6 G' T' c; l' x# J7 P3 z! m
直接操作数前缀: ‘#’ 或 ‘$’
2 e2 {4 f0 Y1 N& L5 n.arm 以arm格式编译,同code32
$ K8 h0 W6 [, l. f% d' ~.thumb 以thumb格式编译,同code16
% @0 i. k# P; J& H: N.code16 以thumb格式编译+ I: w1 [% O" |+ u% o7 D
.code32 以arm格式编译
5 m9 p! o& j  W8 @: N, s6 j2 R/ Q篇后语:
) f, _; F$ W0 Z4 }0 X# j6 E" c6 P: q+ j1 I3 g3 m! ^2 d
更详细的使用说明请参照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1+ c. f7 u7 |" H* K" |1 D; X
补充:
) s2 o8 b- `4 V4 d! T& g7 F, _; B* W/ T# O
4 ARM GNU常用汇编语言介绍
. c+ F! d+ o0 j4 ~" y4.1 ARM GNU常用汇编伪指令介绍
3 }+ e, l1 I+ k; `$ K- W8 g1. abort, k% s% g$ a$ G1 Q- P7 q
.abort: 停止汇编
- T- V+ k2 Q1 y/ `" ~% N9 y8 R.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第! U/ v" \  m+ X% e) P$ M- I
二个表达式值表示填充的值.7 t* L; z' \9 }# I3 k& r) e
2. if...else...endif9 a/ U& g* Y  B7 c8 K
.if! `& W+ D3 u& F/ H
.else0 Q; ^' u! |  A9 k% C& q& Q
.endif: 支持条件预编译5 O9 |; O" M7 i0 @
3. include
, y" W6 j& Z" q$ L6 F) ~+ w.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.
* t9 U# |3 e# _9 ?  A4. comm
4 m& a. J( H' |.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length.      Ld连接器在连接会
0 Y& V% [! C' M% l为它留出空间.
. o) L5 `$ [6 {0 i. H5 I5. data
' f" ~, C  P& z6 |; q. n8 ^( l* ].data subsection: 说明接下来的定义归属于subsection数据段.
1 g8 J4 C1 N9 E  @6 v5 L6.      equ
8 e9 n/ ?# M- b0 d9 g.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.
6 i9 w7 f$ h7 k' b) N! ?# G7. global1 q" O6 ^, c' e0 k
.global symbol: 定义一个全局符号, 通常是为ld使用.; A' [( b  O2 I& S
8. ascii3 b( ?$ {! c; r* ]+ S) i
.ascii "string": 定义一个字符串并为之分配空间.
! Q- w( ?+ O$ R7 r9. byte: E# `+ m8 ~, L  A! Z6 O
.byte expressions: 定义一个字节, 并为之分配空间.6 Q8 C4 n$ l3 a5 j. H0 y' V) q; }5 k
10. short7 ^- a' t  F5 i) G
.short expressions: 定义一个短整型,      并为之分配空间./ P& k+ l; a: _0 Y6 K2 [) z
11. int
8 r& r/ q% `6 g5 z3 x2 ^, e.int expressions: 定义一个整型,并为之分配空间.
. O$ P  R1 d& E8 G  z1 w12 long8 H/ I. x$ k+ B4 Y! `2 Z& g- x. P1 M
.long expressions: 定义一个长整型, 并为之分配空间.& T- S1 r( H0 L& v" N9 n+ u
13 word  i/ Z8 J; c* ^% T0 ^
.word expressions: 定义一个字,并为之分配空间, 4bytes.
! }6 w9 j; P& H" a14. macro/endm
* F/ B9 F( v9 j2 k% N.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.6 W, `) k& f: J
15. req
2 Z* H: U. y0 q8 u; X& K( l4 v$ h8 [name .req register name:      为寄存器定义一个别名.
! h3 }6 C0 U& t: v0 y16. code
. R  |# v5 I3 {, ~; g8 h* R.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.
. e8 V/ l: x/ P1 W- ~* v1 B- m* e: M17. ltorg' G- _; s9 U( H. R# R9 ^
.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.
3 I4 d7 b! C3 @) z4.2 ARM GNU专有符号
; t0 e. w3 L. \( N1. @
5 I- ?! n6 b1 |8 \8 r6 Q7 f表示注释从当前位置到行尾的字符.
! x* I/ S2 e; ~. a) w- H2. #
% @4 J( }# Y7 R( o) X注释掉一整行.! S6 e: K; p4 ]' [5 X7 t* r) o1 }
3. ;) E+ f8 o; [$ Z/ O, @) _  m
新行分隔符.
# h/ E  h% \! T4.3 操作码6 @4 @2 ^( m: J3 s
1. NOP8 h% U$ X0 n: D0 @& N( l3 K
       nop  U* L- H6 D$ ]1 [' v" }8 r
       空操作, 相当于MOV r0, r0
( y7 K" e5 r! \* H9 _4 t( `; k  i% y2. LDR2 l7 ~/ H( e! i
          ldr <register> , = <expression>4 }" P- l" D8 |: U  g) I& e3 r
       相当于PC寄存器或其它寄存器的长转移.
$ q) b$ `4 a( M( @* E2 b3.ADR1 u. A" o. b" [9 o
          adr <register> <label>
) I/ u6 p! j; r: a       相于PC寄存器或其它寄存器的小范围转移.
9 R- k) z# x! b. L6 r1 K! n0 f' Q       ADRL) W! V$ u( y2 u9 ~1 a- _( ^3 {) t
          adrl <register> <label>
" B6 k0 C7 O0 ?9 z! [) `       相于PC寄存器或其寄存器的中范围转移.+ u: q" I( }% r
/ ?3 D! X2 h# n7 o" U
原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx" G7 P9 y$ i* G6 {, q; a+ Y9 w
; l: V( \" E6 s- R1 H' U

# d2 E& M  U8 K% R; B) D. P. u% v6 f3 x/ u4 s! F4 P& n4 C

本版积分规则

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

GMT+8, 2024-4-26 15:57 , Processed in 0.065371 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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