ARM匯編語言源程序語句 ,一般由指令、偽操作、宏指令和偽指令作成。ARM匯編語言的設計基礎是匯編偽指令,匯編偽操作和宏指令。
目前常用的ARM編譯環境有2種:
ARMASM: ARM公司的IDE中使用了CodeWarrior的編譯器,絕大多數windows下的開發者都在使用這一環境,完全按照ARM的規定;
GNU ARM ASM:GNU工具的ARM版本,與ARMASM略有不同;
關於CodeWarriror ARM匯編的書和文章很多,本文假定你已經完全了解ARMASM,這里只說明GNU ARM匯編,並針對ARMASM給出說明。本文翻譯自:GNU ARM Assembler Quick Reference, 本人水平有限,錯誤難免,轉載隨意,請注明出處。英文原文地址不詳。
GNU ARM 匯編快速入門
任何匯編行都是如下結構:
[<label>:] [<instruction or directive>} @ comment
[<標簽>:] [<指令>} @ 注釋
[<標簽>:] [<指令>} @ 注釋
GNU ARM 匯編中,任何以冒號結尾的都被認為是一個標簽,而不一定非要在一行的開始。下面是一個簡單的例子,這段匯編程序定義了一個"add"的函數,該函數返回兩個參數的和:
.section .text, “x”
.global add @ give the symbol add external linkage
add:
ADD r0, r0, r1 @ add input arguments
MOV pc, lr @ return from subroutine
@ end of program
.global add @ give the symbol add external linkage
add:
ADD r0, r0, r1 @ add input arguments
MOV pc, lr @ return from subroutine
@ end of program
GNU ARM匯編偽指令
下面列出了一些GNU ARM匯編偽指令,並給出了相應說明。
.ascii “<string>” 在匯編中定義字符串並為之分配存儲空間(與armasm中的DCB功能類似)。
.asciz “<string>” 和.ascii類似, 但不分配存儲空間。
.balign <power_of_2> {,<fill_value> {,<max_padding>} }
以某種排列方式在內存中填充數值。 (該指令與armasm中的ALIGN類似)。
power_of_2表示排列方式,其值可為4,8,16或32,單位是byte;
fill_value是要填充的值;
max_padding最大的填充界限,請求填充的bytes數超過該值,將被忽略。
以某種排列方式在內存中填充數值。 (該指令與armasm中的ALIGN類似)。
power_of_2表示排列方式,其值可為4,8,16或32,單位是byte;
fill_value是要填充的值;
max_padding最大的填充界限,請求填充的bytes數超過該值,將被忽略。
.byte <byte1> {,<byte2>} … 定義一個或多個Byte,並為之分配空間(與armasm的DCB類似)。
.code <number_of_bits> 設定指令寬度,16表示Thumb,32表示ARM assembly
(和armasm中的CODE16,CODE32相同)。
(和armasm中的CODE16,CODE32相同)。
.if
.else
.endif
預編譯宏(與armasm中的IF ELSE ENDIF相同)。
.else
.endif
預編譯宏(與armasm中的IF ELSE ENDIF相同)。
.end 匯編文件結束標志,常常省略不用。
.endm 宏結束標志。
.exitm 宏跳出。
.macro <name> {<arg_1} {,<arg_2>} … {,<arg_N>}
定義一段名為name的宏,arg_xxx為參數。
必須有對應的.endm結尾。
可以使用.exitm從中間跳出宏。(與armasm中的MACRO, MEND, MEXIT相同)。
在使用宏參數時必須這樣使用:“\<arg>”。
例如:
[CODE].macro SHIFTLEFT a, b
.if \b < 0
MOV \a, \a, ASR #-\b
.exitm
.endif
MOV \a, \a, LSL #\b
.endm
[CODE].macro SHIFTLEFT a, b
.if \b < 0
MOV \a, \a, ASR #-\b
.exitm
.endif
MOV \a, \a, LSL #\b
.endm
.rept <number_of_times> 循環執行.endr前的代碼段number_of_times次。
(與armasm中的WEN相似)
.irp <param> {,<val_1>} {,<val_2>} …
循環執行.endr前的代碼段,param依次取后面給出的值。
在循環執行的代碼段中必須以“\<param> ”表示參數。
.endr 結束循環(與armasm中的WEND相似).
.equ <symbol name>, <value> 為一個標號賦值,類似C中的#define。(與armasm中的EQU相同)
.err 編譯錯誤報告,將引起編譯的終止。
.global <symbol> 全局聲明標志,這樣聲明的標號將可以被外部使用。(與armasm中的EXPORT相同)。
.hword <short1> {,<short2>} …
插入一個16-bit的數據隊列。(與armasm中的DCW相同)
插入一個16-bit的數據隊列。(與armasm中的DCW相同)
.ifdef <symbol> 如果 <symbol>被定義,該快代碼將被編譯。以 .endif結束。
.ifndef <symbol> 如果 <symbol>未被定義,該快代碼將被編譯。以 .endif結束。
.ifndef <symbol> 如果 <symbol>未被定義,該快代碼將被編譯。以 .endif結束。
.include “<filename>” 包含文件。(與armasm中的INCLUDE 或者C中的#i nclude一樣)
<register_name> .req <register_name>
定義一個寄存器,.req的左邊是定義的寄存器名,右邊是使用的真正使用的寄存器。
(與armasm中的RN類似)
例如:acc .req r0
定義一個寄存器,.req的左邊是定義的寄存器名,右邊是使用的真正使用的寄存器。
(與armasm中的RN類似)
例如:acc .req r0
[CODE].section <section_name> {,”<flags>”}
開始一個新的代碼或數據段。.text, 代碼段;.data, 初始化數據段;.bss, 未初始化數據段。
這些段都有缺省的標志(flags),聯接器可以識別這些標志。(與armasm中的AREA相同)。
下面是ELF格式允許的段標志
<標志> 含義
a 允許段
w 可寫段
x 執行段
開始一個新的代碼或數據段。.text, 代碼段;.data, 初始化數據段;.bss, 未初始化數據段。
這些段都有缺省的標志(flags),聯接器可以識別這些標志。(與armasm中的AREA相同)。
下面是ELF格式允許的段標志
<標志> 含義
a 允許段
w 可寫段
x 執行段
.set <variable_name>, <variable_value> 變量賦值。(與armasm中的SETA相同)
.space <number_of_bytes> {,<fill_byte>}
分配number_of_bytes字節的數據空間,並填充其值為fill_byte,若未指定該值,缺省填充0。
(與armasm中的SPACE功能相同)
分配number_of_bytes字節的數據空間,並填充其值為fill_byte,若未指定該值,缺省填充0。
(與armasm中的SPACE功能相同)
.word <word1> {,<word2>} …
插入一個32-bit的數據隊列。(與armasm中的DCD功能相同)
插入一個32-bit的數據隊列。(與armasm中的DCD功能相同)
GNU ARM匯編特殊字符和語法
代碼行中的注釋符號: ‘@’
整行注釋符號: ‘#’
語句分離符號: ‘;’
直接操作數前綴: ‘#’ 或 ‘$’
.arm 以arm格式編譯,同code32
.thumb 以thumb格式編譯,同code16
.code16 以thumb格式編譯
.code32 以arm格式編譯
.thumb 以thumb格式編譯,同code16
.code16 以thumb格式編譯
.code32 以arm格式編譯
篇后語:
更詳細的使用說明請參照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1
補充:
4 ARM GNU常用匯編語言介紹
4.1 ARM GNU常用匯編偽指令介紹
1. abort
.abort: 停止匯編
.align abs-expr1, abs-expr2: 以某種對齊方式,在未使用的存儲區域填充值. 第一個值表示對齊方式,4, 8,16或32. 第
二個表達式值表示填充的值.
2. if...else...endif
.if
.else
.endif: 支持條件預編譯
3. include
.include "file": 包含指定的頭文件, 可以把一個匯編常量定義放在頭文件中.
4. comm
.comm symbol, length:在bss段申請一段命名空間,該段空間的名稱叫symbol, 長度為length. Ld連接器在連接會
為它留出空間.
5. data
.data subsection: 說明接下來的定義歸屬於subsection數據段.
6. equ
.equ symbol, expression: 把某一個符號(symbol)定義成某一個值(expression).該指令並不分配空間.
7. global
.global symbol: 定義一個全局符號, 通常是為ld使用.
8. ascii
.ascii "string": 定義一個字符串並為之分配空間.
9. byte
.byte expressions: 定義一個字節, 並為之分配空間.
10. short
.short expressions: 定義一個短整型, 並為之分配空間.
11. int
.int expressions: 定義一個整型,並為之分配空間.
12 long
.long expressions: 定義一個長整型, 並為之分配空間.
13 word
.word expressions: 定義一個字,並為之分配空間, 4bytes.
14. macro/endm
.macro: 定義一段宏代碼, .macro表示代碼的開始, .endm表示代碼的結束.
15. req
name .req register name: 為寄存器定義一個別名.
16. code
.code [16|32]: 指定指令代碼產生的長度, 16表示Thumb指令, 32表示ARM指令.
17. ltorg
.ltorg: 表示當前往下的定義在歸於當前段,並為之分配空間.
4.2 ARM GNU專有符號
1. @
表示注釋從當前位置到行尾的字符.
2. #
注釋掉一整行.
3. ;
新行分隔符.
4.3 操作碼
1. NOP
nop
空操作, 相當於MOV r0, r0
2. LDR
ldr <register> , = <expression>
相當於PC寄存器或其它寄存器的長轉移.
3.ADR
adr <register> <label>
相於PC寄存器或其它寄存器的小范圍轉移.
ADRL
adrl <register> <label>
相於PC寄存器或其寄存器的中范圍轉移.
原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx
1. @
表示注釋從當前位置到行尾的字符.
2. #
注釋掉一整行.
3. ;
新行分隔符.
4.3 操作碼
1. NOP
nop
空操作, 相當於MOV r0, r0
2. LDR
ldr <register> , = <expression>
相當於PC寄存器或其它寄存器的長轉移.
3.ADR
adr <register> <label>
相於PC寄存器或其它寄存器的小范圍轉移.
ADRL
adrl <register> <label>
相於PC寄存器或其寄存器的中范圍轉移.
原文地址:http://blog.csdn.net/lbsljn/archive/2009/06/17/4277640.aspx