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 彙編快速入門

任何彙編行都是如下結構:
 
[<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
 
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數超過該值,將被忽略。
 
.byte <byte1> {,<byte2>} … 定義一個或多個Byte,併爲之分配空間(與armasm的DCB類似)。 
.code <number_of_bits> 設定指令寬度,16表示Thumb,32表示ARM assembly
(和armasm中的CODE16,CODE32相同)。
 
.if 
.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

.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相同)
 
.ifdef <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
 
[CODE].section <section_name> {,”<flags>”}
開始一個新的代碼或數據段。.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功能相同)
 
.word <word1> {,<word2>} …
插入一個32-bit的數據隊列。(與armasm中的DCD功能相同)

GNU ARM彙編特殊字符和語法
 
代碼行中的註釋符號: ‘@’
整行註釋符號: ‘#’
語句分離符號: ‘;’
直接操作數前綴: ‘#’ 或 ‘$’
 
.arm 以arm格式編譯,同code32
.thumb 以thumb格式編譯,同code16
.code16 以thumb格式編譯
.code32 以arm格式編譯
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章