18luck网站

18luck网站電子設計 | 18luck网站Rss 2.0 會員中心 會員注冊
搜索: 您現在的位置: 18luck网站 >> 18luck平台 >> 嵌入式係統 >> ARM >> 正文

ARM匯編偽指令詳解

作者:佚名    文章來源:本站原創    點擊數:    更新時間:2008-11-28

ARM匯編程序分析過程中,比較難理解的是他的偽(wei) 操作、宏指令和偽(wei) 指令。在讀vivi時遇到很多不懂的,所以在此對引導程序中出現偽(wei) 操作、宏指令和偽(wei) 指令進行總結,

 

*****************************************************
    一、GET option.s

 

// GET和INCLUDE功能相同
功能:引進一個(ge) 被編譯過的文件。
格式:GET    filename
其中:fiename    匯編時引入的文件名,可以有路徑名。
    GET符號在匯編時對宏定義(yi) ,EQU符號以及存儲(chu) 映射時是很有用的,在引入文件匯編完以後,匯編將從(cong) GET符號後開始。在被引入的文件中可能有GET符號再引入其他的文件。GET符號不能用來引入目標文件。

 

*****************************************************
    二、INTPND EQU 0x01e00004

 

//EQU可以用“*”代替,在閱讀源程序時注意。
功能:對一個(ge) 數字常量賦予一個(ge) 符號名。
格式:name    EQU   expression
其中:name   符號名。Expression    寄存器相關(guan) 或者程序相關(guan) 的固定值。
    使用EQU定義(yi) 常量,與(yu) C語言中用#define定義(yi) 一個(ge) 常量相同。
例:num   EQU   2    ; 數字2賦予符號num

 

*****************************************************
    三、GBLL    THUMBCODE
        [ {CONFIG} = 16
            THUMBCODE SETL {TRUE}
            CODE32
        | 
            THUMBCODE SETL {FALSE}
        ]

        [ THUMBCODE
            CODE32   ;for start-up code for Thumb mode
        ]

 

//其中[=IF ,|=ELSE ,]= ENDIF, CODE32 表明一下操作都在ARM狀態。這些都是偽(wei) 操作這段理解為(wei) 設定THUMCODE的值,然後確定,用戶的程序是在ARM狀態還是THUM狀態。

*****************************************************
    四、MACRO


        $HandlerLabel HANDLER $HandleLabel
        $HandlerLabel
        sub sp,sp,#4 ;decrement sp(to store jump address)
        stmfd sp!,{r0} ;PUSH the work register to stack
        ldr r0,=$HandleLabel;load the address of HandleXXX to r0
        ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
        str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
        ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
        MEND

 

//MACRO……MEND
功能:標誌一下宏的定義(yi) 。
格式:MACRO
     Macro_prototype
     MEND
宏表達式的格式如下:
{$label}   macroname    {$ parameter{,parameter2}…}
其中:
$ label   參數,在宏使用時,被給定的符號替代。
Macroname   宏的名稱,並不一定以一條指令或者符號名開始。
$parameter    在宏使用時,被替代的參數,格式為(wei) :$parameter=“default value”
   在宏體(ti) 中,參數如:$parameter和變量一樣使用,在被宏引用時,被賦於(yu) 新值,參數必須用“$”符號加於(yu) 區別。$label在宏定義(yi) 內(nei) 部符號 時很有用,可以看作宏的參數。使用“|”符號作為(wei) 使用一個(ge) 參數缺省值的變量,如果使用的是一個(ge) 空格符串,將省去該變量。在使用內(nei) 部標誌的宏定義(yi) 中,將內(nei) 部 標誌定義(yi) 為(wei) 帶後綴的標誌,將會(hui) 很有用。如果在擴展中空間不夠,可以作為(wei) 參數和後繼文字之間或者參數之間使用圓點隔開,但在文本和後繼參數之間不能使用圓點。宏可以定義(yi) 局部變量的範圍。宏還可以嵌套使用。
例:
MACRO
$label    xmac    $p1,$p2
          LCLS   err
$labell,loopl
          BGE    $pl
$labell,loop2
          BL     $p1
          BEG      $p1
          BEG      $labell,loop2
MEND

 

*****************************************************
    五、$和$$

 

//$臨(lin) 時變量替換,若程序中需要用字符$則用$$來表示,通常情況下,包含在兩(liang) 個(ge) ||之間的$並不表示進行變量替換,但是如果|線是在雙引號內(nei) ,則將進行變量替換。用“.”來分割出變量名的用法,
 GBLS STR1
 GBLS STR2
STR1 SETS "AAA"
STR2 SETS "BBB$$STR1.CCC"  //匯編後STR2的值為(wei) bbAAACCC

 

*****************************************************
    六、 IMPORT  Main    ; The main entry of mon program

 

//該偽(wei) 操作告訴編譯器當前的符號不是在本文件中定義(yi) 的,在本源文件中可能引用該符號,而不論該源文件是否使用該符號,該符號都將被加入到本源文件中。
格式:
IMPORT symbol {[WEAK]}
    symbol 引用的符號的名稱,他是區分大小寫(xie) 的,[WEAK]指定這個(ge) 選項後,如果symbol所在的源文件中沒有被定義(yi) ,編譯器也不會(hui) 報錯。他和EXTERN作用相同,不同之處在於(yu) ,如果本源文件沒有實際引用該符號,該符號將不會(hui) 被加入到本源文件的符號表中。


*****************************************************
    七、AREA    Init,CODE,READONLY
       ENTRY

 

//功能:指示匯編器匯編一段新的代碼或新的數據區。
格式:

name  給出的特定段名。以數字開頭,必須加豎線,否則,將報錯,例如:|1_Data-Area|。某些名字已保留,如:|C$$code|已經被C編譯器用作代碼,或者用作與(yu) C庫相連的代碼段。
Attr    段名屬性,下列屬性是有效的:
ALIGN=expression
缺省狀態下,AOF段將按4個(ge) 字節對準,expression可以是2~31之間的整數,該段將按2(上標為(wei) expression)字節對準。例如,espression等於(yu)

10,該段將按1KB對準。

 

CODE        特定機器指令,缺省為(wei) READONLY。
COMDEF      通用段定義(yi) 。該AOF段可能包括代碼和數據,但必須與(yu) 其他段名相區別。
COMMON      通用數據段,無須再注釋定義(yi) 任何代碼和數據,通常由鏈接器初始化為(wei) 零。
DATA        包含數據,但是不包含指令,缺省為(wei) READWRITE
INTERWORK   表明代碼段可以適用ARM/Thumb interworking功能。
NOINIT      表明數據段可以初始化為(wei) 零,隻包含指示符。
PIC         表明定位獨立段,可以不修改情況下,在任意地址執行。
READONLY    表明該段可讀可寫(xie) 。

 

 匯編時,必須至少有一個(ge) AREA指示符。使用AREA符號可以將源程序區分,但是必須不重名。通常需要獨立的AOF段做為(wei) 代碼或者數據段,較大程序 可以分為(wei) 多個(ge) 代碼段。AOF段可以定義(yi) 局部標簽的範圍,可以使用ROUT符號。如果沒有任何的AREA指示符定義(yi) ,匯編器將會(hui) 產(chan) 生名為(wei) |$$$$$$$| 的AOF段和一條診斷信息,將限製由於(yu) 缺少指示符而產(chan) 生的錯誤信息,但是並不一定會(hui) 成功匯編。

 

*****************************************************
    八、LTORG

 

//LTORG是在此指令出現的地方放一個(ge) 文本池(literal pool). 在ARM匯編中常用到
    ldr   r0, =instruction     將地址instruction載入r0
    此時編譯器將ldr盡可能的轉變成mov或mvn指令。 如果轉變不成, 將產(chan) 生一個(ge) ldr指令,通過pc相對地址從(cong) 一塊保存常數的內(nei) 存區讀出instruction的值。此內(nei) 存區既是文本池。一般的, 文本池放在END指令之後的地方。但是, 如果偏移地址大於(yu) 4k空間, ldr指令會(hui) 出錯(因為(wei) ldr的相對偏移地址為(wei) 12-bit的值). 此時使用LTORG放到會(hui) 出錯的ldr指令附近,以解決(jue) 此問題。編譯器會(hui) 收集沒有分配的ldr的值放到此文本池中

。所以必須在LDR指令前後4KB的範圍內(nei) 用LTORG顯式地在代碼段中添加一個(ge) 文字池。

 

*****************************************************
    九、LDR r0,=WTCON ;watch dog disable
      LDR r1,=0x0

 

功能:將一個(ge) 32位常量或地址讀取至寄存器。
格式:
LDR{condition} register,=[expression|Label-expression]
其中:
condition             可選的條件代碼。
register              讀取的寄存器。
expression            數字常量:
    如果該數字常量在MOV或MVN指令的範圍中,匯編器會(hui) 產(chan) 生合適的指令;
    如果該數字量不在MOV或MVN指令的範圍中,匯編器把該常量於(yu) 程序後,用程序相關(guan) 的LDR偽(wei) 指令讀取,PC與(yu) 該常量的偏移量不得超過4KB。
Label-expression      程序相關(guan) 的或外部的表達式。匯編器將其存放在程序後的常量庫(稱為(wei) 文字池(literal pool))中,用程序相關(guan) 的LDR偽(wei) 指令讀取,PC與(yu) 與(yu) 該常量的偏移量不得超過4KB。

LDR偽(wei) 指令的使用有兩(liang) 個(ge) 目的:
     對於(yu) 不能被MOV和MVN指令所讀取的立即數,將其變成常量,進行讀取。
     將一個(ge) 程序相關(guan) 的或外部的表達式讀取進寄存器中。
例:
LDR  R1, =0xfff
LDR  R2, =place

 

*****************************************************
    十、DCD 0x11110090

 ;Bank0=OM[1:0], Bank1~Bank7=16bit, bank2=8bit;

 

//DCD或“&”
功能: 分配一個(ge) 或多個(ge) 字,從(cong) 4個(ge) 字節邊界開始。
格式:
{label}DCD  expression{,expression}…
其中:
expression    可以是:
一個(ge) 數學表達式;
一個(ge) 程序相關(guan) 的表達式。

 如果在Thumb代碼中,使用DCD符號定義(yi) 帶標誌的數據時則必須使用DATA符號。
    按4個(ge) 字節對準時,DCD符號會(hui) 在第一個(ge) 字節之前插入3個(ge) 字節的空字符,如果無須對準的話,可以使用DCDU符號。
例:
datal   DCD    1,5,20
data2   DCD    mem06
data3    DCD  glb+4

 

*****************************************************
    十一、ALIGN

 

//功能:從(cong) 1個(ge) 字邊界開始。
格式:
ALIGN  {expression  {,offset-expression} }
其中:
    expression    2(上標為(wei) 0)到2(上標為(wei) 31)之間的任意數冪,當前按2(上標為(wei) n)字節對準,如果該參數沒有指定,ALIGN將按字對準。
    Offset-expression  定義(yi) expression指定的對準方式的字節偏移量。

 使用ALIGN符號,保證程序正確對準。對於(yu) Thumb地址,使用ALIGN符號保證其按字對準,例如:ADR  Thuub偽(wei) 指令隻能讀取字對準的地址。
    在代碼段出現數據定義(yi) 符時,使用ALIGE符號。當在代碼段使用數據定義(yi) 符(DCB,DCW,DCWU,DCDU和%),程序計數器PC並不一定按字對準。

 匯編器會(hui) 在下一條指令時插入3個(ge) 字節,保證:
    ARM狀態下按字對準;
    Thumb狀態下按半字對準。
    在Thumb狀態下,可以使用ALIGN2對Thumb代碼按半字對準。
    使用ALIGN狀態下,還可以充分利用一些ARM處理器的Cache,例如,ARM940T有一個(ge) 每行4字的Cache,使用ALIGN16按16字節對準,從(cong) 而最大限度使用Cache。

 

*****************************************************
    十二、^ _ISR_STARTADDRESS

 

//MAP與(yu) "^"
    MAP用於(yu) 定義(yi) 一個(ge) 結構化的內(nei) 存表(StorageMAP)的首地址。此時,內(nei) 存表的位置計數器{VAR}(匯編器的內(nei) 置變量)設置成該地址值。MAP可以用”^”代替。
語法:MAP  expr {,base-register}
    其中,expr為(wei) 數字表達式或者是程序中已經定義(yi) 過的標號。Base-register為(wei) 一個(ge) 寄存器。當指令中沒有Base-register時, expr為(wei) 結構化內(nei) 存表的首地址。此時,內(nei) 存表的位置計數器{VAR}設置成該地址值。當指令中包含這一項時,結構化內(nei) 存表的首地址為(wei) expr和Base -register寄存器內(nei) 容的和。
使用說明:MAP偽(wei) 操作和FIELD偽(wei) 操作配合使用來定義(yi) 結構化的內(nei) 存表結構。

舉(ju) 例:MAP偽(wei) 操作
MAP  fun  ;fun就是內(nei) 存表的首地址
MAP   0x100,R9  ;內(nei) 存表的首地址為(wei) R9+0x100

 

*****************************************************
     十三、HandleReset # 4
        HandleUndef # 4
        HandleSWI # 4

 

//FIELD和"#"
FIELD 用於(yu) 定義(yi) 一個(ge) 結構化的內(nei) 存表中的數據域。FIELD 可用“#”代替。
語法:{label} FIELD expr
其中:{label}為(wei) 可選的。當指令中包含這一項時,label的值為(wei) 當前內(nei) 存表的位置計數器{VAR}的值。匯編編譯器處理了這條FIELD偽(wei) 操作後。

內(nei) 存表計數器的值將加上expr.expr表示本數據域在內(nei) 存中所占的字節數。

使用說明:MAP偽(wei) 操作和FIELD偽(wei) 操作配合使用來定義(yi) 結構化的內(nei) 存表結構。MAP偽(wei) 操作定義(yi) 內(nei) 存表的首地址。FIELD偽(wei) 操作定義(yi) 內(nei) 存表的數據域的字節長度,並可以為(wei) 每一格數據域指定一個(ge) 標號,其他指令可以引用該標號。

MAP偽(wei) 操作中的Base-registe寄存器值隊以其後所有FIELD偽(wei) 操作定義(yi) 的數據域是默認使用的,直到遇到新的包含Base-registe項的MAP偽(wei) 操作需要特別注意的是,MAP偽(wei) 操作和FIELD偽(wei) 操作僅(jin) 僅(jin) 是定義(yi) 數據結構,他們(men) 並不實際分配內(nei) 存單元。由MAP偽(wei) 操作和FIELD偽(wei) 操作配合 定義(yi) 的內(nei) 存表有3種:基於(yu) 絕對地址的內(nei) 存表,基於(yu) 相對地址的內(nei) 存表和基於(yu) PC的內(nei) 存表。

舉(ju) 例:基於(yu) 絕對地址的內(nei) 存表

 用偽(wei) 操作序列定義(yi) 一個(ge) 內(nei) 存表,其首地址為(wei) 固定的地址8192(0X2000),該內(nei) 存表中包括5個(ge) 數據域。  

    Consta長度為(wei) 4個(ge) 字節;constb長為(wei) 4個(ge) 字節,x長為(wei) 8字節;y長為(wei) 8字節;string長為(wei) 16字節。這種內(nei) 存表成為(wei) 基於(yu) 絕對地址的內(nei) 存表。

MAP  8192 ; //內(nei) 存表的首地址8192(0x2000)
Consta FIELD 4 ; //consta 長為(wei) 4字節,相對位置為(wei) 0
Constb FIELD 4; //constb長為(wei) 4字節,相對位置為(wei) 4
X   FIELD  8; // X長為(wei) 8字節,相對位置為(wei) 8
Y    FIELD 8; // y長為(wei) 8字節,相對位置為(wei) 16
String FIELD 16 ;// String為(wei) 16字節,相對位置為(wei) 24

在指令中,可以這樣引用內(nei) 存表中的數據域;

LDR R0,consta; //將consta地址處對應內(nei) 存加載到R0上麵的指令僅(jin) 僅(jin) 可以訪問LDR指令前後4KB地址範圍的數據域。

舉(ju) 例:相對絕對地址的內(nei) 存表

 下麵的偽(wei) 操作序列定義(yi) 一個(ge) 內(nei) 存表,其首地址為(wei) 0與(yu) R9寄存器值得和,該內(nei) 存表中包含5個(ge) 數據域。這種表稱為(wei) 相對地址的內(nei) 存表。

MAP 0,R9;//內(nei) 存表的首地址寄存器R9的值
Consta FIELD 4 ; //consta 長為(wei) 4字節,相對位置為(wei) 0
Constb FIELD 4; //constb長為(wei) 4字節,相對位置為(wei) 4
X   FIELD  8; // X長為(wei) 8字節,相對位置為(wei) 8
Y    FIELD 8; // y長為(wei) 8字節,相對位置為(wei) 16
String FIELD 16;// String為(wei) 16字節,相對位置為(wei) 24

可以通過下麵的指令訪問地址範圍超過4KB的數據;

ADR  R9, Field ;  //偽(wei) 指令
LDR  R5,Constb;//相當於(yu) LDR R5,[R9,#4]

 在這裏,內(nei) 存表中的數據都是相對於(yu) R9寄存器的內(nei) 容,而不是相對於(yu) 一個(ge) 固定的地址。通過在LDR中指定不同的基址寄存器的值,定義(yi) 的內(nei) 存表結構可以在程序中有多個(ge) 實例。可多次使用LDR指令,用以實現不同的程序實例。

舉(ju) 例:基於(yu) PC的內(nei) 存表

Data   SPACE 100 ; //分配100字節的內(nei) 存單元,並初始化為(wei) 0
MAP Data;//內(nei) 存表的首地址為(wei) Datastruc內(nei) 存單元
Consta FIELD 4 ; //consta 長為(wei) 4字節,相對位置為(wei) 0
Constb FIELD 4; //constb長為(wei) 4字節,相對位置為(wei) 4
X   FIELD  8; // X長為(wei) 8字節,相對位置為(wei) 8
Y    FIELD 8; // y長為(wei) 8字節,相對位置為(wei) 16
String FIELD 16;// String為(wei) 16字節,相對位置為(wei) 24

可以通過下麵的指令訪問範圍不超過4kb的數據;

LDR R5,constb ;相當於(yu) LDR R5,[PC,offset]

Tags:ARM,匯編,偽指令  
責任編輯:admin
  • 上一篇文章:
  • 下一篇文章:
  • 請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
    1分 2分 3分 4分 5分

    還可以輸入 200 個字
    [ 查看全部 ] 網友評論
    關於我們 - 聯係我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
    返回頂部
    刷新頁麵
    下到頁底
    晶體管查詢