ARM汇编伪指令介绍(全集)
在ARM處理器匯編語言程序設計里,有一些特殊的指令助記符。這些助記符與指令系統(tǒng)的助記符不同,沒有相對應的操作碼,通常稱這些特殊的指令助記符為偽指令,它們所完成的操作稱為偽操作。
偽指令在源程序中的作用是為完成匯編程序做各種準備工作的,這些偽指令僅在匯編過程中起作用,一旦匯編結束,偽指令的使命就完成了。在ARM處理器的匯編程序中,大體有如下幾種偽指令:符號定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令、宏指令及其他偽指令。
偽操作符可以分為以下幾類。
1)數(shù)據(jù)定義偽操作符
數(shù)據(jù)定義偽操作符主要包括LTORG、MAP、DCB、FIELD、SPACE、DCQ、DCW等,主要用于數(shù)據(jù)表定義、文字池定義、數(shù)據(jù)空間分配等。常用的有DCB/DCQ/DCW分配一段字節(jié)/雙字/字內(nèi)存單元,并且將它們初始化。
2)符號定義偽操作符
符號定義偽操作符包括GBLA、GBLL、GBLS、LCLA、CN、CP、DN、FN、RLIST、SETA等,用于定義ARM匯編程序的變量,對變量進行賦值,以及定義寄存器名稱等。其中用于全局變量聲明的GBLA、GBLL、GBLS和局部變量聲明的LCAL、LCLL、LCLS偽指令較為常用。
3)報告?zhèn)尾僮鞣?/strong>
報告?zhèn)尾僮鞣ˋSSERT、INFO、OPT等,主要用于匯編報告等。其中比較常用的有ASSERT,表示斷言錯誤。
4)條件匯編偽操作符
條件匯編偽操作符包括IF、ELSE、ENDIF、WHIL、WEND、MACRO、MEND等,主要用于條件匯編、宏定義、重復匯編控制等操作。
5)雜項偽操作符
雜項偽操作符包括AREA、ALIGN、ENTRY、EQU、EXPORT、GLOBAL、IMPORT、CODE16、CODE32等。這些偽指令在匯編程序設計中較為常用,如段定義、入口點設置等偽指令。常用的偽指令主要有以下幾條。
AREA:用來定義段;
ALIGN:用來設定邊界對齊;
CODE16/CODE32:用來指定指令集;
ENTRY:指定程序入口;
END:匯編結束。
?
?
在 ARM 匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統(tǒng)的助記符不同,沒有相對應的操作碼,通常稱這些特殊指令助記符為偽指令,他們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種準備工作的,這些偽指令僅在匯編過程中起作用,一旦匯編結束,偽指令的使命就完成。? ???www.cedn.cn1 V* ?: A2 c1 Lwww.cedn.cn% r' m' B??a" j% I9 U
? ? 在 ARM 的匯編程序中,有如下幾種偽指令:符號定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令、宏指令以及其他偽指令。www.cedn.cn2 v3 w5 X$ G4 E. L: a
1 r??B??n- J" j- J' Z??p
? ? 符號定義( Symbol Definition )偽指令? ??
? ? 符號定義偽指令用于定義 ARM 匯編程序中的變量、對變量賦值以及定義寄存器的別名等操作。? ????Y! |# q" F! /& x$ x
? ? 常見的符號定義偽指令有如下幾種:? ??
? ? — 用于定義全局變量的 GBLA 、 GBLL 和 GBLS 。? ??CEDN論壇& V) {7 M, d' S' _
? ? — 用于定義局部變量的 LCLA 、 LCLL 和 LCLS 。? ??
? ? — 用于對變量賦值的 SETA 、 SETL 、 SETS 。? ??CEDN論壇: Y1 ?5 v& u$ N+ I' E
? ? — 為通用寄存器列表定義名稱的 RLIST 。? ??www.cedn.cn???7 x; t; I4 h* `
? ? 1、 GBLA、GBLL 和GBLS? ??/ q: X* X- W' v5 [3 v2 {4 Q
? ? 語法格式:? ??www.cedn.cn6 K, E9 M, s9 i5 U
? ? GBLA ( GBLL 或 GBLS ) 全局變量名? ??
? ? GBLA 、 GBLL 和 GBLS 偽指令用于定義一個 ARM 程序中的全局變量,并將其初始化。其中:? ??
? ? GBLA 偽指令用于定義一個全局的數(shù)字變量,并初始化為 0 ;? ??www.cedn.cn% /6 M+ b/ U% W+ b" U3 F
? ? GBLL 偽指令用于定義一個全局的邏輯變量,并初始化為 F (假);? ??www.cedn.cn: E! r/ ~0 /??o) ]
? ? GBLS 偽指令用于定義一個全局的字符串變量,并初始化為空;? ??
? ? 由于以上三條偽指令用于定義全局變量,因此在整個程序范圍內(nèi)變量名必須唯一。? ??
? ? 使用示例:? ??
? ? GBLA Test1 ;定義一個全局的數(shù)字變量,變量名為 Test1? ??0 _: m2 v& L4 G3 b; L??C
? ? Test1 SETA 0xaa ;將該變量賦值為 0xaa? ??
? ? GBLL Test2 ;定義一個全局的邏輯變量,變量名為 Test2? ????s% ^3 /8 U& R% G
? ? Test2 SETL {TRUE} ;將該變量賦值為真? ??
? ? GBLS Test3 ;定義一個全局的字符串變量,變量名為 Test3? ??- {( Q??a* c* S* P, z% B
? ? Test3 SETS “ Testing ” ;將該變量賦值為 “ Testing ”??
??
? ? 2、 LCLA、LCLL 和LCLS? ??
? ? 語法格式:? ??: e6 E2 F7 V! O* C0 H3 /
? ? LCLA ( LCLL 或 LCLS ) 局部變量名? ??www.cedn.cn$ p% F+ J! s( @, E$ @
? ? LCLA 、 LCLL 和 LCLS 偽指令用于定義一個 ARM 程序中的局部變量,并將其初始化。其中:? ??
? ? LCLA 偽指令用于定義一個局部的數(shù)字變量,并初始化為 0 ;? ??1 K3 ~* I. C4 F* I! ?7 L: f7 X, N
? ? LCLL 偽指令用于定義一個局部的邏輯變量,并初始化為 F (假);? ??
? ? LCLS 偽指令用于定義一個局部的字符串變量,并初始化為空;? ??0 K5 v( |# f6 u
? ? 以上三條偽指令用于聲明局部變量,在其作用范圍內(nèi)變量名必須唯一。? ??
? ? 使用示例:? ??
? ? LCLA Test4 ;聲明一個局部的數(shù)字變量,變量名為 Test4? ??2 k3 K5 R4 w??|??k??h7 c) E! L
? ? Test3 SETA 0xaa ;將該變量賦值為 0xaa? ??
? ? LCLL Test5 ;聲明一個局部的邏輯變量,變量名為 Test5? ??% P9 /$ [/ y% t& f
? ? Test4 SETL {TRUE} ;將該變量賦值為真? ??. T! z) p# /. i5 ~
? ? LCLS Test6 ;定義一個局部的字符串變量,變量名為 Test6? ??+ n0 /1 n" X/ O$ @: [
? ? Test6 SETS “ Testing ” ;將該變量賦值為 “ Testing ”? ?
, }7 @% v2 s$ Z' C; H8 W
? ? 3、 SETA、SETL 和SETS? ??
? ? 語法格式:? ??5 T2 A/ M" F* A+ S. ~3 p4 /$ I8 n8 o
? ? 變量名 SETA ( SETL 或 SETS ) 表達式? ??1 U' L% w, B/ A+ R0 M' S: _
? ? 偽指令 SETA 、 SETL 、 SETS 用于給一個已經(jīng)定義的全局變量或局部變量賦值。? ??www.cedn.cn??X8 q$ C0 {7 n& N
? ? SETA 偽指令用于給一個數(shù)學變量賦值;? ??3 @6 y, Y' B5 t8 K9 M1 [) [6 /& U4 B
? ? SETL 偽指令用于給一個邏輯變量賦值;? ??6 o5 M. J6 Y2 y; l& Q( v
? ? SETS 偽指令用于給一個字符串變量賦值;? ??4 {) t" u0 ~0 N1 /7 Q2 k2 p
? ? 其中,變量名為已經(jīng)定義過的全局變量或局部變量,表達式為將要賦給變量的值。? ??
? ? 使用示例:? ??
? ? LCLA Test3 ;聲明一個局部的數(shù)字變量,變量名為 Test3? ??& z, s/ k7 C9 h/ f4 |
? ? Test3 SETA 0xaa ;將該變量賦值為 0xaa? ??' k, M" s# K, Q??~% t
? ? LCLL Test4 ;聲明一個局部的邏輯變量,變量名為 Test4? ??
? ? Test4 SETL {TRUE} ;將該變量賦值為真? ??CEDN論壇/ ~' @" E2 m* M( P
? ? 4 、 RLIST? ??
? ? 語法格式:? ??
? ? 名稱 RLIST { 寄存器列表 }? ??CEDN論壇% b??P2 a8 g7 i% ?
? ? RLIST 偽指令可用于對一個通用寄存器列表定義名稱,使用該偽指令定義的名稱可在 ARM 指令 LDM/STM 中使用。在 LDM/STM 指令中,列表中的寄存器訪問次序為根據(jù)寄存器的編號由低到高,而與列表中的寄存器排列次序無關。? ??CEDN論壇6 }+ W$ u* c& c7 o8 a
? ? 使用示例:? ??
? ? RegList RLIST {R0-R5 , R8 , R10} ;將寄存器列表名稱定義為 RegList ,可在 ARM 指令 LDM/STM中通過該名稱訪問寄存器列表。? ??
/ i6 `/ X: R+ w# s' F; A) L
? ? 數(shù)據(jù)定義( Data Definition )偽指令? ??
? ? 數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲單元,同時可完成已分配存儲單元的初始化。? ??
? ? 常見的數(shù)據(jù)定義偽指令有如下幾種:? ??
? ? — DCB 用于分配一片連續(xù)的字節(jié)存儲單元并用指定的數(shù)據(jù)初始化。? ??' B) Y??r6 A, W
? ? — DCW ( DCWU ) 用于分配一片連續(xù)的半字存儲單元并用指定的數(shù)據(jù)初始化。? ??1 V6 |1 L1 F' /: w
? ? — DCD ( DCDU ) 用于分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化。? ??
? ? — DCFD ( DCFDU )用于為雙精度的浮點數(shù)分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始? ?
? ? 化。? ??www.cedn.cn2 c! J/ f% z/ `
? ? — DCFS ( DCFSU ) 用于為單精度的浮點數(shù)分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初? ??www.cedn.cn- g' Z8 U, m# R/ q
? ? 始化。? ??www.cedn.cn- /! f" f6 M??A( M8 M) |
? ? — DCQ ( DCQU ) 用于分配一片以 8 字節(jié)為單位的連續(xù)的存儲單元并用指定的數(shù)據(jù)初始? ??
? ? 化。? ??
? ? — SPACE 用于分配一片連續(xù)的存儲單元? ??CEDN論壇* `+ a2 @8 y3 M! d3 c, b5 q- N+ j
? ? — MAP 用于定義一個結構化的內(nèi)存表首地址? ??
? ? — FIELD 用于定義一個結構化的內(nèi)存表的數(shù)據(jù)域? ??www.cedn.cn5 E2 ?3 q/ V: a$ R* J6 E% L$ [
? ? 1、 DCB? ??. B??`) _# i( i
? ? 語法格式:? ??www.cedn.cn3 G6 g0 z8 c. S; u% o
? ? 標號 DCB 表達式? ??
? ? DCB 偽指令用于分配一片連續(xù)的字節(jié)存儲單元并用偽指令中指定的表達式初始化。其中,表達式可以為 0 ~ 255 的數(shù)字或字符串。 DCB 也可用 “ = ” 代替。? ??
? ? 使用示例:? ??1 o+ x' Y) u, p. M' B; _
? ? Str DCB “ This is a test ! ” ;分配一片連續(xù)的字節(jié)存儲單元并初始化。?CEDN論壇. u: i7 e1 c- D1 ]
? ?
? ? 2、 DCW(或DCWU)? ??CEDN論壇4 R??c2 H% z2 K: n
? ? 語法格式:? ??
? ? 標號 DCW (或 DCWU ) 表達式? ??
? ? DCW (或 DCWU )偽指令用于分配一片連續(xù)的半字存儲單元并用偽指令中指定的表達式初始化。? ??
? ? 其中,表達式可以為程序標號或數(shù)字表達式。。? ??
? ? 用 DCW 分配的字存儲單元是半字對齊的,而用 DCWU 分配的字存儲單元并不嚴格半字對齊。? ??
? ? 使用示例:? ??
? ? DataTest DCW 1 , 2 , 3 ;分配一片連續(xù)的半字存儲單元并初始化。? ??
? ? 3、 DCD(或DCDU)? ??# d??q! /, _??T5 C- T0 J
? ? 語法格式:? ??" i- ?' [# R??N5 L
? ? 標號 DCD (或 DCDU ) 表達式? ??0 p' I( G# J8 m??]5 P
? ? DCD (或 DCDU )偽指令用于分配一片連續(xù)的字存儲單元并用偽指令中指定的表達式初始化。其中,表達式可以為程序標號或數(shù)字表達式。 DCD 也可用 “ & ” 代替。? ??9 G3 r2 F( c+ D& R??]. Q; q9 s$ Q
? ? 用 DCD 分配的字存儲單元是字對齊的,而用 DCDU 分配的字存儲單元并不嚴格字對齊。? ??, e+ g; W??/5 Q# I5 ?5 /??_0 n
? ? 使用示例:? ??
? ? DataTest DCD 4 , 5 , 6 ;分配一片連續(xù)的字存儲單元并初始化。?
? ?www.cedn.cn9 R1 E+ W. I) r: G# I$ C6 A4 m
? ? 4、 DCFD(或DCFDU)? ??
? ? 語法格式:? ??
? ? 標號 DCFD (或 DCFDU ) 表達式? ??
? ? DCFD (或 DCFDU )偽指令用于為雙精度的浮點數(shù)分配一片連續(xù)的字存儲單元并用偽指令中指定的表達式初始化。每個雙精度的浮點數(shù)占據(jù)兩個字單元。用 DCFD 分配的字存儲單元是字對齊的,而用 DCFDU 分配的字存儲單元并不嚴格字對齊。? ??& p% e8 |" B0 |# F! A# e9 T( s
? ? 使用示例:? ??CEDN論壇* I. V4 S% c- b: x0 ]/ A! U
? ? FDataTest DCFD 2E115 , -5E7 ;分配一片連續(xù)的字存儲單元并初始化為指定的雙精度數(shù)。? ??! A4 a9 K& f' B5 t??_( ]
9 x! q& Q# ^; ~9 t4 v# i6 y
? ? 5、 DCFS(或DCFSU)? ??
? ? 語法格式:? ??, q# b& R' y/ o0 x! C$ a
? ? 標號 DCFS (或 DCFSU ) 表達式? ??
? ? DCFS (或 DCFSU )偽指令用于為單精度的浮點數(shù)分配一片連續(xù)的字存儲單元并用偽指令中指定的表達式初始化。每個單精度的浮點數(shù)占據(jù)一個字單元。 用 DCFS 分配的字存儲單元是字對齊的,而用 DCFSU 分配的字存儲單元并不嚴格字對齊。? ??
? ? 使用示例:? ??: e' ^, S" u# H4 X8 b- U5 m2 y
? ? FDataTest DCFS 2E5 , -5E - 7 ;分配一片連續(xù)的字存儲單元并初始化為指定的單精度數(shù)。? ??
? ? 6、 DCQ(或DCQU)? ??5 a' ?8 C/ D1 b4 H( L8 g1 t
? ? 語法格式:? ??' ]1 k- G- r- M4 s* u# E) w! k
? ? 標號 DCQ (或 DCQU ) 表達式? ??0 N3 k, T$ m+ a1 k9 Q
? ? DCQ (或 DCQU )偽指令用于分配一片以 8 個字節(jié)為單位的連續(xù)存儲區(qū)域并用偽指令中指定的表達式初始化。? ??. p7 t??f$ u9 y% `$ g: u
? ? 用 DCQ 分配的存儲單元是字對齊的,而用 DCQU 分配的存儲單元并不嚴格字對齊。? ??
? ? 使用示例:? ??$ A??P6 o: y, W# v6 D
? ? DataTest DCQ 100 ;分配一片連續(xù)的存儲單元并初始化為指定的值。?
? ?) E" Q- _* F' U
? ? 7、 SPACE? ??7 j6 F??z* S4 N1 V. J3 /
? ? 語法格式:? ??
? ? 標號 SPACE 表達式? ??- K7 ]' L4 `) T4 @8 H
? ? SPACE 偽指令用于分配一片連續(xù)的存儲區(qū)域并初始化為 0 。其中,表達式為要分配的字節(jié)數(shù)。? ??
? ? SPACE 也可用 “ % ” 代替。? ??
? ? 使用示例:? ??CEDN論壇: t+ m4 S! h: [( /- E
? ? DataSpace SPACE 100 ;分配連續(xù) 100 字節(jié)的存儲單元并初始化為 0 。? ??
: t; R$ [. D2 r& r6 v* N
? ? 8、 MAP? ??CEDN論壇: N% S: A4 U, q
? ? 語法格式:? ??! w+ H" V5 D! h# L& ~* z
? ? MAP 表達式 { ,基址寄存器 }? ????N* D??s: j3 @. L' X
? ? MAP 偽指令用于定義一個結構化的內(nèi)存表的首地址。 MAP 也可用 “ ^ ” 代替。? ??
? ? 表達式可以為程序中的標號或數(shù)學表達式,基址寄存器為可選項,當基址寄存器選項不存在時,表達式的值即為內(nèi)存表的首地址,當該選項存在時,內(nèi)存表的首地址為表達式的值與基址寄存器的和。? ??: f& A) g8 r7 ]2 h+ `( ^' r1 p
? ? MAP 偽指令通常與 FIELD 偽指令配合使用來定義結構化的內(nèi)存表。? ??. m; v" V/ s4 U" x: T+ c+ m( /0 D3 [. I
? ? 使用示例:? ??
? ? MAP 0x100 , R0 ;定義結構化內(nèi)存表首地址的值為 0x100 + R0 。?
? ?; ]0 T- V4 T, K4 Y0 M" J3 X
? ? 9、 FILED? ??
? ? 語法格式:? ??
? ? 標號 FIELD 表達式? ??
? ? FIELD 偽指令用于定義一個結構化內(nèi)存表中的數(shù)據(jù)域。 FILED 也可用 “ # ” 代替。? ??
? ? 表達式的值為當前數(shù)據(jù)域在內(nèi)存表中所占的字節(jié)數(shù)。? ??
? ? FIELD 偽指令常與 MAP 偽指令配合使用來定義結構化的內(nèi)存表。 MAP 偽指令定義內(nèi)存表的首地址, FIELD 偽指令定義內(nèi)存表中的各個數(shù)據(jù)域,并可以為每個數(shù)據(jù)域指定一個標號供其他的指令引用。? ??
? ? 注意 MAP 和 FIELD 偽指令僅用于定義數(shù)據(jù)結構,并不實際分配存儲單元。? ??. _% m$ c& H$ y3 F! @
? ? 使用示例:? ??
? ? MAP 0x100 ;定義結構化內(nèi)存表首地址的值為 0x100 。? ??
? ? A FIELD 16 ;定義 A 的長度為 16 字節(jié),位置為 0x100? ??
? ? B FIELD 32 ;定義 B 的長度為 32 字節(jié),位置為 0x110? ??
? ? S FIELD 256 ;定義 S 的長度為 256 字節(jié),位置為 0x130? ??9 U% [( D( y9 r* P3 [0 T
# E( J0 D# E??U: A9 w
? ? 匯編控制( Assembly Control )偽指令? ??CEDN論壇8 ^7 X, n8 C; T4 R: X% j
? ? 匯編控制偽指令用于控制匯編程序的執(zhí)行流程,常用的匯編控制偽指令包括以下幾條:? ??
? ? — IF 、 ELSE 、 ENDIF? ??6 `( n% ~2 ?- ~3 j: Y# N
? ? — WHILE 、 WEND? ??6 h8 x/ Z" N+ z( Q7 X
? ? — MACRO 、 MEND? ??, u; r2 F??g; _: X% W) @
? ? — MEXIT? ??( F9 G' p6 /6 V( `, [1 Z5 G: L
? ? 1、 IF、ELSE、ENDIF? ??www.cedn.cn5 i3 w7 X' J4 N7 o3 ]2 C8 K??g- b
? ? 語法格式:? ??1 a1 n4 Z* Y4 U& N7 n
? ? IF 邏輯表達式? ??
? ? 指令序列 1? ??
? ? ELSE? ??
? ? 指令序列 2? ??CEDN論壇) c3 X4 `% r# C, q! P7 K( c
? ? ENDIF? ??7 v. }) o% g* ]2 U* V
? ? IF 、 ELSE 、 ENDIF 偽指令能根據(jù)條件的成立與否決定是否執(zhí)行某個指令序列。當 IF 后面的邏輯表達式為真,則執(zhí)行指令序列 1 ,否則執(zhí)行指令序列 2 。其中, ELSE 及指令序列 2 可以沒有,此時,當 IF 后面的邏輯表達式為真,則執(zhí)行指令序列 1 ,否則繼續(xù)執(zhí)行后面的指令。? ??
? ? IF 、 ELSE 、 ENDIF 偽指令可以嵌套使用。? ??
? ? 使用示例:? ??
? ? GBLL Test ;聲明一個全局的邏輯變量,變量名為 Test……? ??
? ? IF Test = TRUE? ??
? ? 指令序列 1? ??
? ? ELSE? ??/ u0 ?9 g. `( p4 q5 o6 L6 V$ ~
? ? 指令序列 2? ??. Z1 S! i9 S# M: g- f. {' F
? ? ENDIF? ??( e( `9 [3 ^( B$ k
* g7 c1 R3 g8 W& A??I. U* R0 J
? ? 2、 WHILE、WEND? ??' |) C1 |* b# /* K7 ]/ U
? ? 語法格式:? ??www.cedn.cn. F0 U& D% W( R7 q( g??H
? ? WHILE 邏輯表達式? ??www.cedn.cn??P' U; A0 j6 ^. L( r6 d
? ? 指令序列? ??; K* G. Y& S0 P; m
? ? WEND? ??
? ? WHILE 、 WEND 偽指令能根據(jù)條件的成立與否決定是否循環(huán)執(zhí)行某個指令序列。當 WHILE 后面的邏輯表達式為真,則執(zhí)行指令序列,該指令序列執(zhí)行完畢后,再判斷邏輯表達式的值,若為真則繼續(xù)執(zhí)行,一直到邏輯表達式的值為假。? ??
? ? WHILE 、 WEND 偽指令可以嵌套使用。? ??" ^" o- z1 }* _0 G. f
? ? 使用示例:? ??
? ? GBLA Counter ;聲明一個全局的數(shù)學變量,變量名為 Counter? ??CEDN論壇" W??g/ h??]2 l) R
? ? Counter SETA 3 ;由變量Counter 控制循環(huán)次數(shù)? ??
? ? ……? ??2 w1 v, /5 d9 A! z) Q/ a- F
? ? WHILE Counter < 10? ??4 m# |2 o( o7 E" f/ k+ Q
? ? 指令序列? ??0 n. {3 }9 ~- R% k' M. D
? ? WEND? ??
% Y??[( v& o2 b# n& F
? ? 3、 MACRO、MEND? ??( X6 l6 @??T/ O" O& M' V
? ? 語法格式:? ??
? ? $ 標號 宏名 $ 參數(shù) 1 , $ 參數(shù) 2 ,……? ??
? ? 指令序列? ??% t: q' a+ u+ p9 W/ _8 G) e
? ? MEND? ??www.cedn.cn, Y4 d! T( I; }2 A* Z" p0 u
? ? MACRO 、 MEND 偽指令可以將一段代碼定義為一個整體,稱為宏指令,然后就可以在程序中通過宏指令多次調(diào)用該段代碼。其中, $ 標號在宏指令被展開時,標號會被替換為用戶定義的符號, 宏指令可以使用一個或多個參數(shù),當宏指令被展開時,這些參數(shù)被相應的值替換。? ??' v: v( Z6 Y# D3 p
? ? 宏指令的使用方式和功能與子程序有些相似,子程序可以提供模塊化的程序設計、節(jié)省存儲空間并提高運行速度。但在使用子程序結構時需要保護現(xiàn)場,從而增加了系統(tǒng)的開銷,因此,在代碼較短且需要傳遞的參數(shù)較多時,可以使用宏指令代替子程序。? ??
? ? 包含在 MACRO 和 MEND 之間的指令序列稱為宏定義體,在宏定義體的第一行應聲明宏的原型(包含宏名、所需的參數(shù)),然后就可以在匯編程序中通過宏名來調(diào)用該指令序列。在源程序被編譯時,匯編器將宏調(diào)用展開,用宏定義中的指令序列代替程序中的宏調(diào)用,并將實際參數(shù)的值傳遞給宏定義中的形式參數(shù)。? ??
? ? MACRO 、 MEND 偽指令可以嵌套使用。? ?3 U% u8 q& L' c
? ? 4、 MEXIT? ??www.cedn.cn9 s; n. T+ E7 O/ |: W2 }* V
? ? 語法格式:? ??
? ? MEXIT? ??: K# N4 u4 h( Z- e7 u7 P* V
? ? MEXIT 用于從宏定義中跳轉出去。??3 U( N4 {5 z1 _1 T! v
www.cedn.cn: ^8 W* l; v& ?: T3 U. |??_
? ? 其他常用的偽指令? ??- G6 f- W6 _0 z
? ? 還有一些其他的偽指令,在匯編程序中經(jīng)常會被使用,包括以下幾條:? ??
? ? — AREA? ??0 j* p$ w) l) h6 S
? ? — ALIGN? ??
? ? — CODE16 、 CODE32? ??3 r$ A/ O$ p3 k( ~1 L) P
? ? — ENTRY? ??
? ? — END? ??
? ? — EQU? ??8 M; N; m; d! H
? ? — EXPORT (或 GLOBAL )? ??
? ? — IMPORT? ??
? ? — EXTERN? ??
? ? — GET (或 INCLUDE )? ??
? ? — INCBIN? ??
? ? — RN? ????Y, @??G1 {% p% I& W
? ? — ROUT? ??
? ? 1、 AREA? ??3 P0 W7 A& P2 D3 H
? ? 語法格式:? ??9 N6 G: r) r6 _& i
? ? AREA 段名 屬性 1 ,屬性 2 ,……? ??! w; i; ]# H1 v??p- K
? ? AREA 偽指令用于定義一個代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開頭,則該段名需用 “ | ” 括起來,如 |1_test| 。? ??www.cedn.cn: Y??n1 y% w/ ]( Y6 h9 t
? ? 屬性字段表示該代碼段(或數(shù)據(jù)段)的相關屬性,多個屬性用逗號分隔。常用的屬性如下:? ??
? ? — CODE 屬性:用于定義代碼段,默認為 READONLY 。? ??" ~% G- U3 l, o??W% |3 G$ M6 f
? ? — DATA 屬性:用于定義數(shù)據(jù)段,默認為 READWRITE 。? ??CEDN論壇" U" X: j( e" r) j5 V+ u+ Q
? ? — READONLY 屬性:指定本段為只讀,代碼段默認為 READONLY 。? ??4 N( M! s5 S/ T6 m! j
? ? — READWRITE 屬性:指定本段為可讀可寫,數(shù)據(jù)段的默認屬性為 READWRITE 。? ??www.cedn.cn1 O* t6 K9 ^0 Z+ c1 Y+ D
? ? — ALIGN 屬性:使用方式為 ALIGN 表達式。在默認時, ELF (可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對齊的,表達式的取值范圍為 0 ~ 31 ,相應的對齊方式為 2 表達式次方。? ??
? ? — COMMON 屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數(shù)據(jù)。各源文件中同名的 COMMON 段共享同一段存儲單元。? ??
? ? 一個匯編語言程序至少要包含一個段,當程序太長時,也可以將程序分為多個代碼段和數(shù)據(jù)段。? ??
? ? 使用示例:? ??- r" S4 h5 y% Y
? ? AREA Init , CODE , READONLY? ??
? ? 該偽指令定義了一個代碼段,段名為 Init ,屬性為只讀? ??
0 v% B8 U. U7 g8 m
? ? 2、 ALIGN? ??
? ? 語法格式:? ??
? ? ALIGN { 表達式 { ,偏移量 }}? ??$ t9 @) A8 g& P
? ? ALIGN 偽指令可通過添加填充字節(jié)的方式,使當前位置滿足一定的對其方式 | 。其中,表達式的值用于指定對齊方式,可能的取值為 2 的冪,如 1 、 2 、 4 、 8 、 16 等。若未指定表達式,則將當前位置對齊到下一個字的位置。偏移量也為一個數(shù)字表達式,若使用該字段,則當前位置的對齊方式為: 2 的表達式次冪+偏移量。? ??
? ? 使用示例:? ??www.cedn.cn& k9 f- k+ k5 A6 k( A
? ? AREA Init , CODE , READONLY , ALIEN = 3 ;指定后面的指令為 8 字節(jié)對齊。? ??CEDN論壇* m3 k: s( l* {* R
? ? 指令序列? ??, u( s" i1 /' m; g* N??H- @
? ? END? ??
& }4 g& I. d2 K8 a
? ? 3、 CODE16、CODE32? ??
? ? 語法格式:? ??
? ? CODE16 (或 CODE32 )? ??' D( b* e) V& k3 b# m9 P$ J: o# O
? ? CODE16 偽指令通知編譯器,其后的指令序列為 16 位的 Thumb 指令。? ??
? ? CODE32 偽指令通知編譯器,其后的指令序列為 32 位的 ARM 指令。? ??CEDN論壇4 H% j$ P! O??X- y7 u1 /" P
? ? 若在匯編源程序中同時包含 ARM 指令和 Thumb 指令時,可用 CODE16 偽指令通知編譯器其后的指令序列為 16 位的 Thumb 指令, CODE32 偽指令通知編譯器其后的指令序列為 32 位的 ARM 指令。因此,在使用 ARM 指令和 Thumb 指令混合編程的代碼里,可用這兩條偽指令進行切換,但注意他們只通知編譯器其后指令的類型,并不能對處理器進行狀態(tài)的切換。? ??www.cedn.cn9 T0 ]+ w6 B+ /; O: H! t
? ? 使用示例:? ??
? ? AREA Init , CODE , READONLY? ??
? ? ……? ??
? ? CODE32 ;通知編譯器其后的指令為 32 位的 ARM 指令? ??
? ? LDR R0 ,= NEXT + 1 ;將跳轉地址放入寄存器 R0? ??- c1 {7 m0 G4 t. K1 O' x
? ? BX R0 ;程序跳轉到新的位置執(zhí)行,并將處理器切換到 Thumb 工作狀態(tài)? ??
? ? ……? ??
? ? CODE16 ;通知編譯器其后的指令為 16 位的 Thumb 指令? ??
? ? NEXT LDR R3,=0x3FF? ??
? ? ……? ??6 E& c8 f& p- z' m) x9 t# T# r
? ? END ;程序結束?
? ?www.cedn.cn+ h( P! A0 c3 q- b0 Q
? ? 4、 ENTRY? ??
? ? 語法格式:? ??
? ? ENTRY? ??+ R: z: ~5 y??|5 @8 i/ h5 a6 G
? ? ENTRY 偽指令用于指定匯編程序的入口點。在一個完整的匯編程序中至少要有一個 ENTRY (也可以有多個,當有多個 ENTRY 時,程序的真正入口點由鏈接器指定),但在一個源文件里最多只能有一個 ENTRY (可以沒有)。? ??www.cedn.cn- O5 c??n1 S2 D- A
? ? 使用示例:? ??
? ? AREA Init , CODE , READONLY? ??www.cedn.cn4 R) ~" _. j* y+ v' |6 {- y! O& j
? ? ENTRY ;指定應用程序的入口點? ??CEDN論壇( o, n0 b# {: o% i+ Z6 g4 j
? ? ……? ??- L' [8 @7 w" H$ v) @! e0 @- B
? ? 5、 END? ??
? ? 語法格式:? ??
? ? END? ??
? ? END 偽指令用于通知編譯器已經(jīng)到了源程序的結尾。? ??CEDN論壇3 v" @5 a, F3 e9 N' f??D$ d
? ? 使用示例:? ??www.cedn.cn# a3 y& b7 |- s1 M2 c
? ? AREA Init , CODE , READONLY? ??
? ? ……? ??7 p6 /) Z) `/ K??k
? ? END ;指定應用程序的結尾? ???n% F" n* r1 _& K4 W. }6 V) Y8 H
? ? 6、 EQU? ??
? ? 語法格式:? ??- O, x7 s) d- S1 G2 U2 B- j2 Q& w$ }
? ? 名稱 EQU 表達式 { ,類型 }? ??
? ? EQU 偽指令用于為程序中的常量、標號等定義一個等效的字符名稱,類似于 C 語言中的# define 。? ??
? ? 其中 EQU 可用 “ * ” 代替。? ??
? ? 名稱為 EQU 偽指令定義的字符名稱,當表達式為 32 位的常量時,可以指定表達式的數(shù)據(jù)類型,可以有以下三種類型:? ??
? ? CODE16 、 CODE32 和 DATA? ??CEDN論壇, k6 /; K2 H1 t??Y0 i/ ]* S
? ? 使用示例:? ??; Q' ?+ |& y: O3 ]
? ? Test EQU 50 ;定義標號 Test 的值為 50? ??- q& F8 /; K& j5 F5 E0 e
? ? Addr EQU 0x55 , CODE32 ;定義 Addr 的值為 0x55 ,且該處為 32 位的 ARM 指令。? ??( t! v7 E6 g& ?* a5 G??L3 W( u6 K& t3 E
/ g8 j* ^7 b& l0 ^8 E) H' B
? ? 7、 EXPORT(或GLOBAL)? ??7 ?+ ?0 l1 s7 Q1 _
? ? 語法格式:? ??
? ? EXPORT 標號 {[WEAK]}? ??
? ? EXPORT 偽指令用于在程序中聲明一個全局的標號,該標號可在其他的文件中引用。 EXPORT可用 GLOBAL 代替。標號在程序中區(qū)分大小寫, [WEAK] 選項聲明其他的同名標號優(yōu)先于該標號被引用。? ??
? ? 使用示例:? ??www.cedn.cn' z$ t8 e) L/ P" Q' a2 V4 |
? ? AREA Init , CODE , READONLY? ??
? ? EXPORT Stest ;聲明一個可全局引用的標號Stest……? ??
? ? END? ??
6 x7 S, O% A0 e( C
? ? 8、 IMPORT? ??# |4 F0 w/ Y) e0 e" f2 N
? ? 語法格式:? ??) w+ s& N- v+ w2 D. Y
? ? IMPORT 標號 {[WEAK]}? ??
? ? IMPORT 偽指令用于通知編譯器要使用的標號在其他的源文件中定義,但要在當前源文件中引用,而且無論當前源文件是否引用該標號,該標號均會被加入到當前源文件的符號表中。? ??" H" H) s" D1 r) }% D
? ? 標號在程序中區(qū)分大小寫, [WEAK] 選項表示當所有的源文件都沒有定義這樣一個標號時,編譯器也不給出錯誤信息,在多數(shù)情況下將該標號置為 0 ,若該標號為 B 或 BL 指令引用,則將 B 或 BL指令置為 NOP 操作。? ??8 h% R0 c' _" W2 O5 E; N( @6 _
? ? 使用示例:? ??
? ? AREA Init , CODE , READONLY? ??www.cedn.cn' q1 L, q1 v5 E
? ? IMPORT Main ;通知編譯器當前文件要引用標號Main,但Main 在其他源文件中定義……? ??' ~# c6 y+ K7 r& B5 F4 u5 b
? ? END? ??
CEDN論壇6 y8 h8 w??s: v% O& K& ?5 Y* N2 u
? ? 9、 EXTERN? ??
? ? 語法格式:? ??% p. j% R6 w9 /8 y8 g
? ? EXTERN 標號 {[WEAK]}? ??
? ? EXTERN 偽指令用于通知編譯器要使用的標號在其他的源文件中定義,但要在當前源文件中引用,如果當前源文件實際并未引用該標號,該標號就不會被加入到當前源文件的符號表中。標號在程序中區(qū)分大小寫, [WEAK] 選項表示當所有的源文件都沒有定義這樣一個標號時,編譯器也不給出錯誤信息,在多數(shù)情況下將該標號置為 0 ,若該標號為 B 或 BL 指令引用,則將 B 或 BL指令置為 NOP 操作。? ??
? ? 使用示例:? ??
? ? AREA Init , CODE , READONLY? ??
? ? EXTERN Main ;通知編譯器當前文件要引用標號Main,但Main 在其他源文件中定義……? ??6 }??p" t: w# Y# A
? ? END? ??6 O9 }6 s' h* W
CEDN論壇??O) V2 r3 L* |& R! c0 _5 i; @
? ? 10、 GET(或INCLUDE)? ??
? ? 語法格式:? ??
? ? GET 文件名? ??www.cedn.cn" ]( L8 w: C. }
? ? GET 偽指令用于將一個源文件包含到當前的源文件中,并將被包含的源文件在當前位置進行匯編處理。可以使用 INCLUDE 代替 GET 。? ??
? ? 匯編程序中常用的方法是在某源文件中定義一些宏指令,用 EQU 定義常量的符號名稱,用 MAP和 FIELD 定義結構化的數(shù)據(jù)類型,然后用 GET 偽指令將這個源文件包含到其他的源文件中。使用方法與 C 語言中的 “ include ” 相似。? ??
? ? GET 偽指令只能用于包含源文件,包含目標文件需要使用 INCBIN 偽指令? ??
? ? 使用示例:? ??
? ? AREA Init , CODE , READONLY? ??: ~3 f' k# N: b9 _??q
? ? GET a1.s ;通知編譯器當前源文件包含源文件a1.s? ??5 c8 M( b- Y7 C- d2 I
? ? GE T C:/a2.s ;通知編譯器當前源文件包含源文件C:/ a2.s ……? ??www.cedn.cn9 R0 Z) z$ Q- W, d/ b* {7 ~
? ? END? ??! u% ]4 X, b9 f, Y" i. t% E
* f+ ^3 |6 N( p7 Y+ T! ?5 D
? ? 11、 INCBIN? ??www.cedn.cn3 j; o1 E, a' v% L; g7 W% w
? ? 語法格式:? ??' i, l; w4 P2 w' `) b
? ? INCBIN 文件名? ??
? ? INCBIN 偽指令用于將一個目標文件或數(shù)據(jù)文件包含到當前的源文件中,被包含的文件不作任何變動的存放在當前文件中,編譯器從其后開始繼續(xù)處理。? ??+ L( Q5 Q4 ~??Y. s
? ? 使用示例:? ??9 Y??x4 ~, J8 b# /9 ~4 y3 M1 p
? ? AREA Init , CODE , READONLY? ??, Y1 |$ h, ^7 i8 `' D) g
? ? INCBIN a1.dat ;通知編譯器當前源文件包含文件a1.dat? ??CEDN論壇# n& N: _& U+ x6 }5 }6 d* q& C* ?9 S
? ? INCBIN C:/a2.txt ;通知編譯器當前源文件包含文件C:/a2.txt……? ??
? ? END? ??
? ? 12、 RN? ??www.cedn.cn0 z+ u4 m& r2 @8 H( c& @
? ? 語法格式:? ??- L8 m. X. P. n( ^
? ? 名稱 RN 表達式? ??: l' a1 ^( C# Y' b$ C* h??W
? ? RN 偽指令用于給一個寄存器定義一個別名。采用這種方式可以方便程序員記憶該寄存器的功能。其中,名稱為給寄存器定義的別名,表達式為寄存器的編碼。? ??' @6 C3 u3 S! z" I* M??~7 @
? ? 使用示例:? ??+ W4 x2 Q! G$ [7 M- e2 ^# O8 }
? ? Temp RN R0 ;將R0 定義一個別名Temp? ??' /2 l??c" J- F& [9 ], }# ]
CEDN論壇) K??H% R- j+ @; w& w+ U5 @4 N. c
? ? 13、 ROUT? ??
? ? 語法格式:? ??
? ? { 名稱 } ROUT? ??
? ? ROUT 偽指令用于給一個局部變量定義作用范圍。在程序中未使用該偽指令時,局部變量的作用范圍為所在的 AREA ,而使用 ROUT 后,局部變量的作為范圍為當前 ROUT 和下一個 ROUT 之間。
總結
以上是生活随笔為你收集整理的ARM汇编伪指令介绍(全集)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: s3c2410_gpio_cfgpin函
- 下一篇: ARM汇编语言中的程序结构