一乐电子

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

QQ登录

只需一步,快速开始

微信扫码登录

手机号码,快捷登录

手机号码,快捷登录

搜索
查看: 3643|回复: 0

GNU ARM汇编快速入门

[复制链接]
发表于 2016-12-18 16:23 | 显示全部楼层 |阅读模式
GNU ARM汇编快速入门
$ ?, q* `" _6 _' \* x) d! {! Q: [以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。
8 |- j8 A+ x8 ?* G6 w, |( J& V- v% a; k' I8 p
ARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。 & Z( u; E: R7 K: @3 Y$ s

; u& f/ B4 F. x, \: t) c' f目前常用的ARM编译环境有2种:
4 O  f1 i* w/ e* M, r0 d8 rARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定; ( b) y, u9 @' m. x3 A, w0 I# p
GNU ARM ASM:GNU工具的ARM版本,与ARMASM略有不同; $ ]' n# b% }( n6 V7 Z4 u# H6 K

1 g" h5 M+ p! Y) `2 `+ |1 P关于CodeWarriror ARM汇编的书和文章很多,本文假定你已经完全了解ARMASM,这里只说明GNU ARM汇编,并针对ARMASM给出说明。本文翻译自:GNU ARM Assembler Quick Reference, 本人水平有限,错误难免,转载随意,请注明出处。英文原文地址不详。 ; x5 V6 A2 R5 Y; U; V

9 b6 w( W6 [4 W) W3 ?: I+ _# V8 o; ~: L
GNU ARM 汇编快速入门
5 u0 ]  Q2 \, b# `2 `! ^6 R* Y任何汇编行都是如下结构:) l, [% P: p" d4 b. y9 e( h
[<label>:] [<instruction or directive>} @ comment7 K) ~+ N% ^2 e5 w
[<标签>:] [<指令>} @ 注释
; K7 `4 J  y* d$ v' X" oGNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段汇编程序定义了一个"add"的函数,该函数返回两个参数的和:$ N( N/ B8 O1 Q6 b
.section .text, “x”
# s' L! f& S/ j/ y.global add @ give the symbol add external linkage/ g# a* k5 t7 Z3 u* ]
add:1 R' E5 p7 h, b' y
ADD r0, r0, r1 @ add input arguments
, T) Z+ @5 S. K. ?MOV pc, lr @ return from subroutine- s) a" l, j) m$ c5 e" x
@ end of program
9 ?! B1 j. ^5 H; UGNU ARM汇编伪指令% a+ L, z# H. e) K

, v9 l- {. Y, {" `3 P下面列出了一些GNU ARM汇编伪指令,并给出了相应说明。. X, R# g& T, E- G2 d; y6 s
6 d! d& {; f7 @& D  q/ U& d
.ascii “<string>” 在汇编中定义字符串并为之分配存储空间(与armasm中的DCB功能类似)。
# B  x, V+ [  _# ^6 q: X% i.asciz “<string>” 和.ascii类似, 但不分配存储空间。) H% s7 o2 r  `' \
.balign <power_of_2> {,<fill_value> {,<max_padding>} }
/ o: V5 `7 }; d; ?% I, N9 s以某种排列方式在内存中填充数值。 (该指令与armasm中的ALIGN类似)。
+ _4 ~& ^6 w- \  R" Dpower_of_2表示排列方式,其值可为4,8,16或32,单位是byte;
: P" f- n, A* Zfill_value是要填充的值;   Y; {$ X8 i2 O* X1 z( j
max_padding最大的填充界限,请求填充的bytes数超过该值,将被忽略。5 _( u9 ?' }! a0 i2 n
.byte <byte1> {,<byte2>} … 定义一个或多个Byte,并为之分配空间(与armasm的DCB类似)。  6 c+ l: h2 r0 ?4 o" ?0 |$ O( ?2 d2 H% K
.code <number_of_bits> 设定指令宽度,16表示Thumb,32表示ARM assembly 3 e2 j' y- c- U2 i6 F! w
(和armasm中的CODE16,CODE32相同)。
. z* V. s$ }/ W.if  9 G! B; y/ Q4 W9 w( t
.else 9 `7 ~, s4 ^; a1 |; p( `
.endif
/ M5 K0 B+ {0 j预编译宏(与armasm中的IF ELSE ENDIF相同)。) [3 w& x5 ]4 l0 i) c
.end 汇编文件结束标志,常常省略不用。' ?; c  x( ^( n$ n

3 V( [$ O: o6 t+ I; M6 @  k! b! M.endm 宏结束标志。
0 P, A- N( l9 D. s( h1 c/ l% p.exitm 宏跳出。 ( }6 c: s+ L! i3 X* [
.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>} 6 l  |3 ~' _3 b9 l' J0 B
定义一段名为name的宏,arg_xxx为参数。
# t# s4 M( `% A, v( d# Y必须有对应的.endm结尾。
; ]: [1 i$ y- y6 M) _0 y/ R/ ^可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。 ! t8 O# R; j1 B8 G- b
在使用宏参数时必须这样使用:“\<arg>”。
6 Y$ a# M8 [% G5 b" \+ W例如:
2 L, e4 v6 U, c[CODE].macro SHIFTLEFT a, b
3 m* a! y/ o9 ].if \b < 0# Y( [" I, n2 u0 U
MOV \a, \a, ASR #-\b" `8 G4 y8 h( R) y; T8 f9 Z
.exitm/ W- J% Z5 q% u. D4 i6 F
.endif
! U0 C; ?; p: T+ c" cMOV \a, \a, LSL #\b
  P: ?6 f, y5 x0 b# b+ t& e.endm
, Q5 Y4 k( Q' e) p2 ]9 r. p! r5 `0 ]) N. p
.rept <number_of_times> 循环执行.endr前的代码段number_of_times次。
& j1 z6 ~  a8 e6 u8 m. u& a(与armasm中的WEN相似)8 N1 r, l  U% I. e) ]9 I: v

8 A; L$ a. F2 N( D0 B0 B5 r9 |( Q.irp <param> {,<val_1>} {,<val_2>} … ; R1 l, u( I- z, Y+ J
循环执行.endr前的代码段,param依次取后面给出的值。
7 w2 b0 p6 d. E! C0 d在循环执行的代码段中必须以“\<param> ”表示参数。
1 I: _& ]# b+ t7 v, Q& P2 b4 S3 \  Z) U
.endr 结束循环(与armasm中的WEND相似)." Q0 s2 }7 E) q/ F
.equ <symbol name>, <value> 为一个标号赋值,类似C中的#define。(与armasm中的EQU相同)' I5 u' n- F7 o
.err 编译错误报告,将引起编译的终止。( A3 E: d: q; D7 Y6 I
.global <symbol> 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。
3 x" u& Q- y1 V9 D5 i! |8 T.hword <short1> {,<short2>} …3 q- i/ F! z- T8 m& D4 O3 b
插入一个16-bit的数据队列。(与armasm中的DCW相同)5 }+ t$ i4 F* f$ H. @4 F3 B; P
.ifdef <symbol> 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。
2 C* T1 e: F! `4 Z: g.ifndef <symbol> 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。$ |+ [) a1 S- w8 c' h
.include “<filename>” 包含文件。(与armasm中的INCLUDE 或者C中的#i nclude一样)
  A4 m6 E+ C  j2 a/ K; Z8 O6 q<register_name> .req <register_name>- ^- z# y5 z* d( o$ l  X1 t8 q
定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。
' [! I' x2 C8 D(与armasm中的RN类似)  G5 W6 n9 y, D
例如:acc .req r01 n3 p' n- Q, _* H$ y
[CODE].section <section_name> {,”<flags>”}
  H% K5 j/ i9 Z5 q: T开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。
  x* b* M# d5 z; x这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。! T& u; |/ e7 ?) e6 n3 n
下面是ELF格式允许的段标志
1 P! U8 f! E; X0 K1 p  M<标志> 含义* A( J& O* m6 e" `5 k' L' ?
a 允许段
* C/ |; d7 Q6 n* a' ]+ m6 B$ L: Xw 可写段
0 N) _, w& M7 ?: d( K1 Tx 执行段
) `" ~/ k( ]# T7 w, t+ G3 T.set <variable_name>, <variable_value> 变量赋值。(与armasm中的SETA相同)
" X. O  M0 W/ r) C( S( R5 ^" J.space <number_of_bytes> {,<fill_byte>}
# R. Y8 c" l# W; c1 c% P分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。
0 ?# H7 E  p6 `+ t(与armasm中的SPACE功能相同)
' e1 t1 d" g5 H.word <word1> {,<word2>} …
- @1 f- d7 }# c+ P+ a' E插入一个32-bit的数据队列。(与armasm中的DCD功能相同)
. I; `; k/ k: X7 o& _, E4 e& H: m) w
, v8 F4 \' T- T, [1 O8 O0 dGNU ARM汇编特殊字符和语法6 r9 e% A) S' \  T2 Q! ^' Z

: j! Q6 L# R* e/ k, Y. O/ {, B代码行中的注释符号: ‘@’
+ R! X7 O% g0 E  m& G整行注释符号: ‘#’4 @% K3 }. F* O/ d) T2 ]/ E
语句分离符号: ‘;’9 J1 G/ f5 e# O! y0 r3 E
直接操作数前缀: ‘#’ 或 ‘$’6 b# }) B: y( j/ ^
.arm 以arm格式编译,同code32 + P0 y$ C6 l( M; w; y: t
.thumb 以thumb格式编译,同code16
* C% }" f: E" Z# e) M+ D& y. v.code16 以thumb格式编译
" T- |9 K3 J5 H.code32 以arm格式编译
  m1 I5 r8 V9 z& `5 r篇后语:
* x4 l- e( ?+ ~6 |
1 G) n+ w, V$ K" h更详细的使用说明请参照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1
, o. {. [# J. e- v! _9 V补充:0 d3 _  \9 x& r. U  G

: Y0 E) {( a$ E4 ARM GNU常用汇编语言介绍& i2 m2 A/ X1 x" T0 e
4.1 ARM GNU常用汇编伪指令介绍; s5 Q3 \8 W) [; n# v5 {' ^
1. abort
$ L3 t% n. B: ]3 E.abort: 停止汇编2 c/ c. j  J/ d1 u) g/ R( [& e9 @
.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第" W( w' L: [5 B# e
二个表达式值表示填充的值.3 ]8 ~, o) j2 j
2. if...else...endif5 f( _/ _" x/ f+ }% I0 I
.if
  E* t8 e+ r7 X) d.else$ b3 n$ @9 x( b( X/ \
.endif: 支持条件预编译" P: B+ k# D. z1 J! m, {4 ~
3. include
3 m% R, b* @3 I5 Y4 x- s; _7 U( K.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.2 o, S+ l3 e9 o# ~% e0 K
4. comm+ Z8 f/ \' {& d& N  ]  Y, Q
.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length.      Ld连接器在连接会
3 J( ^3 S1 |5 Z4 s( q& }为它留出空间." c2 J: ~3 q$ Z. w# M5 I
5. data2 a0 @/ B5 r. K3 r  A) u
.data subsection: 说明接下来的定义归属于subsection数据段.
, p5 t3 q' g/ }0 R1 v5 }6.      equ
2 n6 \/ Q+ V, n; Q.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.& p+ @7 x# {( ^( E
7. global
2 N1 I5 S# W( B4 \: m- Y# {.global symbol: 定义一个全局符号, 通常是为ld使用.( N, ^& |% Z& a& D  q# h) A, J' A
8. ascii
# W2 @% Z/ u! H7 A$ r2 O- G+ ].ascii "string": 定义一个字符串并为之分配空间.
9 S  `* G4 a, }9. byte: @8 t; z$ B' k6 f9 D
.byte expressions: 定义一个字节, 并为之分配空间.  ], \+ t# h( I
10. short* `; x- ?5 f8 S( j( ~, s; L
.short expressions: 定义一个短整型,      并为之分配空间.
5 l( @, I9 y& @8 ?- W11. int
; B$ c, z# G' M9 q1 j: ^' A.int expressions: 定义一个整型,并为之分配空间.
# [& c( M% y' R2 @8 q, ~( q" X/ C12 long
* C) Y7 u, ]! s4 m) L.long expressions: 定义一个长整型, 并为之分配空间.# W0 ~  `% u' i6 j. d4 Z
13 word1 S7 A4 J- K) |; ]
.word expressions: 定义一个字,并为之分配空间, 4bytes.
( [, U2 o' t) ^& a+ ?+ K3 p' w0 Y14. macro/endm- f# _. s3 ^% S5 W+ H. L- _
.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.
4 f4 k% \% d+ J6 I+ `15. req
8 j( W" X6 f# U% O# Yname .req register name:      为寄存器定义一个别名.# Y5 z* n; _; U. U! O3 _: J1 T2 |. u
16. code
9 L5 X1 m; R$ p+ \. I, X.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.
& {2 E$ g- I0 I3 J+ |" T17. ltorg
" A1 c9 |$ D+ U4 U! ]+ w' V.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.
  ]9 p. F) F( W+ T, E$ u4.2 ARM GNU专有符号
$ R6 w) V( _8 B( m) e, r1. @
8 e5 e6 u9 @' B# W表示注释从当前位置到行尾的字符.
/ E* _3 P  o. ^3 y( V2. #
! j) n$ {+ p" [  `2 D注释掉一整行.3 h2 {5 r3 q* O8 A3 K
3. ;
1 Q1 \$ K) s" N新行分隔符.
8 g$ ]! o, H$ @# ]/ R+ Y4.3 操作码8 W# h! `6 b  ]( Q
1. NOP
8 @7 e5 }, \% I$ N' i" E       nop1 G' a8 r: P1 ~; w; b! Z1 ^7 w6 S( [
       空操作, 相当于MOV r0, r0
) F7 }% x1 `3 M) \7 @" M0 C2. LDR( j8 s/ C) U8 w0 q! t4 N+ W
          ldr <register> , = <expression>
) y4 G5 {- f3 s! @# r. K       相当于PC寄存器或其它寄存器的长转移.# t) I5 D2 s& A6 S9 j  B
3.ADR' H. w$ e) N9 G* V( o
          adr <register> <label>
' V' b5 h( ~" e% Q2 R       相于PC寄存器或其它寄存器的小范围转移.
/ \8 e  w0 d! }7 C& x       ADRL
! B* `* V3 j2 u- B* Z          adrl <register> <label>
" c, ]  u* v0 ^4 c       相于PC寄存器或其寄存器的中范围转移.
: V1 \  l, j! H2 @1 g. n$ _: u" y
原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx+ c, k; S/ `$ i
- l+ C, L5 X. A: j8 M6 \

2 R2 V$ _: D2 N* N+ Z# Y8 h# m' L# \0 Q. ^, m. _( o7 U  X" ~' j+ O

本版积分规则

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

GMT+8, 2026-1-11 16:54 , Processed in 0.030735 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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