以前用ARMIDE工具,使用的是ARM標准的組合語言。現在要使用GNU的工具,當然要了解一點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表示排列方式,其值可為481632,單位是byte


fill_value是要填補的值;


max_padding最大的填補界限,要求填補的bytes數超過該值,將被舍棄。


.byte <byte1> {,<byte2>} … 定義一個或多個Byte,并為之配置空間(與armasmDCB類似)。


.code <number_of_bits> 設定指令寬度,16表示Thumb32表示ARM assembly


(armasm中的CODE16CODE32相同)


.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格式編譯




文章出處:http://www.diybl.com/course/6_system/linux/Linuxjs/200888/135022.html

立你斯 發表在 痞客邦 留言(0) 人氣()