天天看點

GNU ARM彙編快速入門

前言:

以前用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