前言:
以前用ARM的 IDE工具,使用的是ARM标準的彙編語言。現在要使用GNU的工具,當然要了解一點GNU ARM彙編的不同之處。其實非常的簡單,浏覽一下文檔然後再看看程式就完全可以搞定了,或者你硬着頭皮看GNU ARM的彙程式設計式,用不了多少時間你就就可以無師自通了。個人比較健忘,還是把文檔翻譯了一下,算是給自己一個避免遺忘的理由吧。
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 彙編快速入門
任何彙編行都是如下結構:
[:] [} @ 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
GNU ARM彙編僞指令
下面列出了一些GNU ARM彙編僞指令,并給出了相應說明。
.ascii “” 在彙編中定義字元串并為之配置設定存儲空間(與armasm中的DCB功能類似)。
.asciz “” 和.ascii類似, 但不配置設定存儲空間。
.balign {, {,} }
以某種排列方式在記憶體中填充數值。 (該指令與armasm中的ALIGN類似)。
power_of_2表示排列方式,其值可為4,8,16或32,機關是byte;
fill_value是要填充的值;
max_padding最大的填充界限,請求填充的bytes數超過該值,将被忽略。
.byte {,} … 定義一個或多個Byte,并為之配置設定空間(與armasm的DCB類似)。
.code 設定指令寬度,16表示Thumb,32表示ARM assembly
(和armasm中的CODE16,CODE32相同)。
.if
.else
.endif
預編譯宏(與armasm中的IF ELSE ENDIF相同)。
.end 彙編檔案結束标志,常常省略不用。
.endm 宏結束标志。
.exitm 宏跳出。
.macro {} … {,}
定義一段名為name的宏,arg_xxx為參數。
必須有對應的.endm結尾。
可以使用.exitm從中間跳出宏。(與armasm中的MACRO, MEND, MEXIT相同)。
在使用宏參數時必須這樣使用:“\”。
例如:
[CODE].macro SHIFTLEFT a, b
.if \b MOV \a, \a, ASR #-\b
.exitm
MOV \a, \a, LSL #\b
.endm
.rept 循環執行.endr前的代碼段number_of_times次。
(與armasm中的WEN相似)
.irp {,} {,} …
循環執行.endr前的代碼段,param依次取後面給出的值。
在循環執行的代碼段中必須以“\ ”表示參數。
.endr 結束循環(與armasm中的WEND相似).
.equ , 為一個标号指派,類似C中的#define。(與armasm中的EQU相同)
.err 編譯錯誤報告,将引起編譯的終止。
.global 全局聲明标志,這樣聲明的标号将可以被外部使用。(與armasm中的EXPORT相同)。
.hword {,} …
插入一個16-bit的資料隊列。(與armasm中的DCW相同)
.ifdef 如果 被定義,該快代碼将被編譯。以 .endif結束。
.ifndef 如果 未被定義,該快代碼将被編譯。以 .endif結束。
.include “” 包含檔案。(與armasm中的INCLUDE 或者C中的#i nclude一樣)
.req
定義一個寄存器,.req的左邊是定義的寄存器名,右邊是使用的真正使用的寄存器。
(與armasm中的RN類似)
例如:acc .req r0
[CODE].section {,””}
開始一個新的代碼或資料段。.text, 代碼段;.data, 初始化資料段;.bss, 未初始化資料段。
這些段都有預設的标志(flags),聯接器可以識别這些标志。(與armasm中的AREA相同)。
下面是ELF格式允許的段标志
含義
a 允許段
w 可寫段
x 執行段
.set , 變量指派。(與armasm中的SETA相同)
.space {,}
配置設定number_of_bytes位元組的資料空間,并填充其值為fill_byte,若未指定該值,預設填充0。
(與armasm中的SPACE功能相同)
.word {,} …
插入一個32-bit的資料隊列。(與armasm中的DCD功能相同)
GNU ARM彙編特殊字元和文法
整行注釋符号: ‘#’
語句分離符号: ‘;’
直接操作數字首: ‘#’ 或 ‘$’
.arm 以arm格式編譯,同code32
.thumb 以thumb格式編譯,同code16
.code16 以thumb格式編譯
.code32 以arm格式編譯
篇後語:
更詳細的使用說明請參照:ARM Architecture Reference Manual, Addison-Wesley ISBN 0-201-73719-1