一乐电子

一乐电子百科

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

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

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

GNU ARM汇编快速入门

[复制链接]
发表于 2016-12-18 16:23 | 显示全部楼层 |阅读模式
GNU ARM汇编快速入门
" {& C: S' ]& S8 ]' K# I以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一点GNU ARM汇编的不同之处。其实非常的简单,浏览一下文档然后再看看程序就完全可以搞定了,或者你硬着头皮看GNU ARM的汇编程序,用不了多少时间你就就可以无师自通了。& m4 `- D5 S# `# E) ]

1 u! ?) n/ C  Q: R# _ARM汇编语言源程序语句 ,一般由指令、伪操作、宏指令和伪指令作成。ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令。
$ H, L% w. Q- o3 ]; n* {, Q5 s, y8 {$ O; q
目前常用的ARM编译环境有2种:
) y) q, T6 s( L% F5 A) n% x( mARMASM: ARM公司的IDE中使用了CodeWarrior的编译器,绝大多数windows下的开发者都在使用这一环境,完全按照ARM的规定;
" d4 w0 l- G4 m0 kGNU ARM ASM:GNU工具的ARM版本,与ARMASM略有不同;
! K, H- X! A0 O6 A9 w5 D0 \% j2 |) ^. D0 f% V8 S
关于CodeWarriror ARM汇编的书和文章很多,本文假定你已经完全了解ARMASM,这里只说明GNU ARM汇编,并针对ARMASM给出说明。本文翻译自:GNU ARM Assembler Quick Reference, 本人水平有限,错误难免,转载随意,请注明出处。英文原文地址不详。
7 Q; R5 A. j( j
7 T: h5 ^4 m5 {& c: D4 V2 {8 n8 M( x8 |/ ~( a5 q' m4 }# N
GNU ARM 汇编快速入门3 X& O, ^- y1 o' B2 V3 }# D
任何汇编行都是如下结构:: Z* @* Y& [- _2 g* g/ m" F
[<label>:] [<instruction or directive>} @ comment
( T% x. ^1 L, ?: ^* G, k9 C( t[<标签>:] [<指令>} @ 注释" P9 \% u9 A- r+ Q  j* s
GNU ARM 汇编中,任何以冒号结尾的都被认为是一个标签,而不一定非要在一行的开始。下面是一个简单的例子,这段汇编程序定义了一个"add"的函数,该函数返回两个参数的和:0 X# z' D5 y/ d* _$ U' s+ I
.section .text, “x”
: ^; V* S/ w3 U& c! D  S5 m.global add @ give the symbol add external linkage7 i. S" w' Z+ O/ h! K
add:  m4 _0 X# V0 F% N9 V6 o
ADD r0, r0, r1 @ add input arguments; ~* y+ d6 E9 ^$ q0 I6 n
MOV pc, lr @ return from subroutine
. r) l) [" O+ A2 }+ l3 m- Z2 ?$ s@ end of program5 e/ C- ~* @7 @& E) r
GNU ARM汇编伪指令: i1 u% y' h/ \* v  e

0 A! Q6 X, D! V" W$ p% A# L" `下面列出了一些GNU ARM汇编伪指令,并给出了相应说明。6 u( K' J; Q+ q  S
! q1 O- b3 o/ o2 s2 i7 e5 ^
.ascii “<string>” 在汇编中定义字符串并为之分配存储空间(与armasm中的DCB功能类似)。
9 X7 M/ I+ `; \4 x.asciz “<string>” 和.ascii类似, 但不分配存储空间。, R% [# \4 R" p; F# m% c
.balign <power_of_2> {,<fill_value> {,<max_padding>} }
5 ?1 o% ~" ^( f以某种排列方式在内存中填充数值。 (该指令与armasm中的ALIGN类似)。
! S) p& N; ^( U) H; v, e6 g! u* M8 kpower_of_2表示排列方式,其值可为4,8,16或32,单位是byte; 0 |  H# [3 \+ y7 _8 u
fill_value是要填充的值;
0 \, c3 p# M( L! |max_padding最大的填充界限,请求填充的bytes数超过该值,将被忽略。6 p: R7 \/ Y8 h& C4 s. ]4 b
.byte <byte1> {,<byte2>} … 定义一个或多个Byte,并为之分配空间(与armasm的DCB类似)。  ( w+ {! x3 c! h4 I1 j
.code <number_of_bits> 设定指令宽度,16表示Thumb,32表示ARM assembly & j) V* p( u" d8 N. ~# y& Q+ f- ^
(和armasm中的CODE16,CODE32相同)。  }8 G# _& S7 ?" s- }
.if  3 D5 M! E/ V# r4 [
.else
' q' O5 O4 Q$ X2 T/ O6 J.endif ' U8 _& S; Q8 ]4 o' f( \6 Z1 m
预编译宏(与armasm中的IF ELSE ENDIF相同)。
1 Y1 E( B) E9 Z& @2 C- r.end 汇编文件结束标志,常常省略不用。( z+ \6 R4 ?. |7 ?7 Y* q
& d& F( e5 ]8 u+ w0 [
.endm 宏结束标志。
8 d; w/ P, D  j3 e+ _% Z: P6 ?.exitm 宏跳出。
! d) {, P  ~' n' ].macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>} ; m1 n9 l6 \3 @, K. U
定义一段名为name的宏,arg_xxx为参数。7 M$ H: `3 k+ R' U+ i& u8 I
必须有对应的.endm结尾。
, f( s* N0 `7 Y/ A可以使用.exitm从中间跳出宏。(与armasm中的MACRO, MEND, MEXIT相同)。 & P7 v' t" q- [- {: ]
在使用宏参数时必须这样使用:“\<arg>”。! s6 v' J2 K4 a5 y3 D
例如:
4 _7 X  J) @4 \; b9 {0 j5 U[CODE].macro SHIFTLEFT a, b; h1 @  f/ s- n$ q1 p8 u' L
.if \b < 0
- I3 B0 P, K: c: e& NMOV \a, \a, ASR #-\b. T% D; H8 \1 {' [
.exitm
& S" c, k: F4 n1 T! y8 N3 w.endif
7 D8 t+ o* P# ]! Q+ {# x) p! GMOV \a, \a, LSL #\b* M: _( o- E5 K/ \% G
.endm
  @' |4 ?+ N2 c! C/ K! Y
( l% E0 j# \9 }" M6 J' G.rept <number_of_times> 循环执行.endr前的代码段number_of_times次。
5 g" j. w" _+ ]. C  y2 {# ^: B5 c(与armasm中的WEN相似)  g; p& l# e$ m7 H3 ]. Y7 e$ {2 r

$ c  d8 K& z& W9 ]2 |9 V; p( c  v* i, c.irp <param> {,<val_1>} {,<val_2>} …
/ t9 J  `) l9 h1 e0 W7 [& l循环执行.endr前的代码段,param依次取后面给出的值。
" n( \" ]8 c% T, J3 q! U在循环执行的代码段中必须以“\<param> ”表示参数。
! y/ U  b, R9 U
/ M4 n% e* P$ i$ U7 G3 L.endr 结束循环(与armasm中的WEND相似).( T3 S2 S, J/ k) b8 |2 p# S
.equ <symbol name>, <value> 为一个标号赋值,类似C中的#define。(与armasm中的EQU相同)2 r, ^3 g9 `4 W0 d& I0 h
.err 编译错误报告,将引起编译的终止。* u9 A* A8 o& N. b( K2 W
.global <symbol> 全局声明标志,这样声明的标号将可以被外部使用。(与armasm中的EXPORT相同)。5 }( C( ^$ i% M# E
.hword <short1> {,<short2>} …% ~6 i7 E( g5 G! Z. A7 c
插入一个16-bit的数据队列。(与armasm中的DCW相同)
0 e: g2 r$ Q  H. T0 |0 e.ifdef <symbol> 如果 <symbol>被定义,该快代码将被编译。以 .endif结束。
' d* N/ L+ e& Z; `.ifndef <symbol> 如果 <symbol>未被定义,该快代码将被编译。以 .endif结束。
! ?8 m; \! G0 t$ U# t+ q.include “<filename>” 包含文件。(与armasm中的INCLUDE 或者C中的#i nclude一样)) L( m8 g: m, k' V* v" z$ e
<register_name> .req <register_name>9 d9 {4 Q- p/ Q# l& @5 V
定义一个寄存器,.req的左边是定义的寄存器名,右边是使用的真正使用的寄存器。' \. {$ w" O% ~2 b# H
(与armasm中的RN类似)
0 J2 \5 W: G! N/ Z: n' U9 b: X' y$ W例如:acc .req r09 Q6 \" ^! J3 U2 T# L( F. B
[CODE].section <section_name> {,”<flags>”}
  p7 c% ~7 O  M" V1 Z- f2 C0 B开始一个新的代码或数据段。.text, 代码段;.data, 初始化数据段;.bss, 未初始化数据段。 ( V/ D0 u& W$ |+ s3 Q6 I& a
这些段都有缺省的标志(flags),联接器可以识别这些标志。(与armasm中的AREA相同)。! g8 {& T8 h0 Z/ t. A
下面是ELF格式允许的段标志
+ Q& f4 J  O! T! I9 H" V* S<标志> 含义/ h: S; F  q3 d: N+ X: m
a 允许段
- u0 ]4 p# A7 A# rw 可写段
0 S! B$ o3 ^3 R% q1 F1 K4 [6 @x 执行段
& d* V& Z9 Z3 o& C/ M.set <variable_name>, <variable_value> 变量赋值。(与armasm中的SETA相同)
* A, Q) ?, |0 m$ C4 H% S$ K% V6 e  C+ @.space <number_of_bytes> {,<fill_byte>}
/ B3 \% W" X- ?, i1 j0 w分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。
& O, v9 W( @, N- P(与armasm中的SPACE功能相同)( i$ d  N+ n4 i$ D9 K; }( g* J( a
.word <word1> {,<word2>} … 8 r5 i  m! P8 S6 N
插入一个32-bit的数据队列。(与armasm中的DCD功能相同)
1 J! \! s3 [  U1 I9 n( [! }- ?; w4 T) V
, E# j6 s$ ~, [4 n1 Y9 ~- cGNU ARM汇编特殊字符和语法7 s/ B+ @# s( K0 D/ t
/ _! F/ n$ N2 M; m, h
代码行中的注释符号: ‘@’" \1 f: I* H9 {3 l: o! a) N" V
整行注释符号: ‘#’9 D5 e" _4 @7 {7 {0 ]" X
语句分离符号: ‘;’' V. E0 Y, y. q( n- Y
直接操作数前缀: ‘#’ 或 ‘$’
8 F/ o/ I7 J8 r.arm 以arm格式编译,同code32
- D/ g+ {# P1 c, b! m) e% |" A.thumb 以thumb格式编译,同code16. n& R! H1 c- Q2 p0 W
.code16 以thumb格式编译& M5 w+ U9 n7 {( O
.code32 以arm格式编译: `0 ]4 F: U+ y) j# l# b1 ^
篇后语:
& Q) a9 g0 S3 y
" {. G' m" p, c* H# o( p7 l8 T更详细的使用说明请参照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1  o4 c/ N# g  a  t: r1 R
补充:1 a/ T. Z0 _, @) L7 {( u& {0 O( d) r
' h0 J" G' Y; y# @# r
4 ARM GNU常用汇编语言介绍
. O2 T+ k% D. S: L) {9 g4.1 ARM GNU常用汇编伪指令介绍( i) ~7 H6 I3 }& ^8 e: d
1. abort
* u! L  B& Z* a.abort: 停止汇编. K8 e$ W! L4 P+ j4 j' v
.align abs-expr1, abs-expr2: 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或32. 第+ F* k+ K9 E$ U. V4 J* x- E
二个表达式值表示填充的值.
: S/ u& d* q+ y; j9 C" t8 `2. if...else...endif
. T+ P3 ^5 k" ]! h0 D1 f3 n.if. T% P9 e: R4 }: a/ ^
.else, d' K4 R5 Z0 A3 b( H5 t' G& c& l$ i- l
.endif: 支持条件预编译
+ h( l/ U$ K5 z2 p* h( [3. include : X$ g. t+ u- I2 k2 `
.include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中.
7 B# E5 C! k4 ^3 I" v0 B2 x4. comm
+ B4 J" U0 G; X# Z2 {! r1 w& t& ~* z.comm symbol, length:在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length.      Ld连接器在连接会/ M8 ~/ f* q% N) h) h9 a. O% v9 K
为它留出空间.
- |0 f: p8 S& _1 s% w5. data
: l9 v  l5 M0 g# I8 ^5 i.data subsection: 说明接下来的定义归属于subsection数据段.
) V* ?5 Y6 T& y7 g2 t0 ^* J4 q* P# G6 @6.      equ
' R7 ^: r# Z0 T2 {) y' W.equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间.: Y, p; B/ I% P# Y6 c! ~  |3 I. _# t
7. global
6 d& X3 |0 W3 J+ d& B.global symbol: 定义一个全局符号, 通常是为ld使用.
" X& A% m( ~9 }+ L8. ascii% x) V% l# s& S# m4 Q
.ascii "string": 定义一个字符串并为之分配空间.
/ j9 `6 ]  x. w1 h" X" o9. byte3 G+ ]( H) ^; @, v- N) o
.byte expressions: 定义一个字节, 并为之分配空间.
& ]6 y' x& [! w7 {  C! @/ Z10. short$ t+ A- B6 E% ^" n9 X0 W8 {
.short expressions: 定义一个短整型,      并为之分配空间.
( G5 l! S2 N9 }8 H11. int
! E; R2 G& O# a.int expressions: 定义一个整型,并为之分配空间.
! j1 m. y& W0 f0 q( m0 s% h$ H' g12 long
. m- ]6 Y( L* |# v& k.long expressions: 定义一个长整型, 并为之分配空间.
( U% l6 i: f+ |+ Z) |13 word/ W) T; q8 D/ m' v. n
.word expressions: 定义一个字,并为之分配空间, 4bytes.9 u" y7 b$ s' T
14. macro/endm5 P' }- e7 n7 t; S, e
.macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束.
& j/ w- R: W% E15. req
. q' x" {# C6 ^% N3 l4 }8 T6 M+ T9 Uname .req register name:      为寄存器定义一个别名.
9 l# x; @5 p$ n( R5 e16. code
$ P  ^: ^3 m5 {; O) |.code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令.: T6 a1 i: I8 D) I3 E
17. ltorg$ ?# E3 {' T4 I& M/ o9 o7 ]5 a" p% c
.ltorg: 表示当前往下的定义在归于当前段,并为之分配空间.
6 X' q& P' ?1 I# k' P7 m6 `) x- J4.2 ARM GNU专有符号
4 F+ ~- ?0 E1 G1 E1. @! y; P. X7 g# N4 L8 e
表示注释从当前位置到行尾的字符.
7 w' U, q0 r, J2. #5 m7 C: J- D' ]3 z1 u
注释掉一整行." g: L# n" t2 W7 F; _- x
3. ;& L2 j: [$ I& D( ?3 k1 v
新行分隔符.# j% {+ L9 b. K+ |4 l2 O: N
4.3 操作码
; s! O' L  E! Z( n5 s: V4 q  y1. NOP
7 S( D- a" F" N       nop6 \1 C* x: Y( b, x3 Z: g; c4 S
       空操作, 相当于MOV r0, r0
. u/ U7 q7 ?, R8 @7 }1 o2. LDR
; u  W; K4 p8 K- A* O  U# g          ldr <register> , = <expression>+ `6 A) f# i) Z5 ^( t
       相当于PC寄存器或其它寄存器的长转移.6 x* _0 e+ m# m0 U
3.ADR; f4 s' S: X2 f: C
          adr <register> <label>" e% |8 F2 H( B+ s  x( C
       相于PC寄存器或其它寄存器的小范围转移.
# L) J4 u. I! P* y# M       ADRL: w7 [* K9 E1 K
          adrl <register> <label>, T! a4 N2 H4 }6 D! H) ]5 P4 P- U
       相于PC寄存器或其寄存器的中范围转移., C, j% |/ r  c- z" _  J

4 }$ b% Q* n' T- J原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx: }0 [+ R2 b* T  i. R' P

4 e5 v1 E" O& N( ?& f
# _9 G( K! ~( |( D. k

% G' a: Q9 e- ^

本版积分规则

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

GMT+8, 2024-5-2 09:12 , Processed in 0.072996 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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