<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開發(fā)網(wǎng)

      電子開發(fā)網(wǎng)電子設計 | 電子開發(fā)網(wǎng)Rss 2.0 會員中心 會員注冊
      搜索: 您現(xiàn)在的位置: 電子開發(fā)網(wǎng) >> 電子開發(fā) >> 嵌入式系統(tǒng) >> ARM >> 正文

      ARM匯編偽指令詳解

      作者:佚名    文章來源:本站原創(chuàng)    點擊數(shù):    更新時間:2008/11/28

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

       

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

       

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

       

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

       

      //EQU可以用“*”代替,在閱讀源程序時注意。
      功能:對一個數(shù)字常量賦予一個符號名。
      格式:name    EQU   expression
      其中:name   符號名。Expression    寄存器相關或者程序相關的固定值。
          使用EQU定義常量,與C語言中用#define定義一個常量相同。
      例:num   EQU   2    ; 數(shù)字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狀態(tài)。這些都是偽操作這段理解為設定THUMCODE的值,然后確定,用戶的程序是在ARM狀態(tài)還是THUM狀態(tài)。

      *****************************************************
          四、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
      功能:標志一下宏的定義。
      格式:MACRO
           Macro_prototype
           MEND
      宏表達式的格式如下:
      {$label}   macroname    {$ parameter{,parameter2}…}
      其中:
      $ label   參數(shù),在宏使用時,被給定的符號替代。
      Macroname   宏的名稱,并不一定以一條指令或者符號名開始。
      $parameter    在宏使用時,被替代的參數(shù),格式為:$parameter=“default value”
         在宏體中,參數(shù)如:$parameter和變量一樣使用,在被宏引用時,被賦于新值,參數(shù)必須用“$”符號加于區(qū)別。$label在宏定義內(nèi)部符號 時很有用,可以看作宏的參數(shù)。使用“|”符號作為使用一個參數(shù)缺省值的變量,如果使用的是一個空格符串,將省去該變量。在使用內(nèi)部標志的宏定義中,將內(nèi)部 標志定義為帶后綴的標志,將會很有用。如果在擴展中空間不夠,可以作為參數(shù)和后繼文字之間或者參數(shù)之間使用圓點隔開,但在文本和后繼參數(shù)之間不能使用圓點。宏可以定義局部變量的范圍。宏還可以嵌套使用。
      例:
      MACRO
      $label    xmac    $p1,$p2
                LCLS   err
      $labell,loopl
                BGE    $pl
      $labell,loop2
                BL     $p1
                BEG      $p1
                BEG      $labell,loop2
      MEND

       

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

       

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

       

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

       

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


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

       

      //功能:指示匯編器匯編一段新的代碼或新的數(shù)據(jù)區(qū)。
      格式:

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

      10,該段將按1KB對準。

       

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

       

       匯編時,必須至少有一個AREA指示符。使用AREA符號可以將源程序區(qū)分,但是必須不重名。通常需要獨立的AOF段做為代碼或者數(shù)據(jù)段,較大程序 可以分為多個代碼段。AOF段可以定義局部標簽的范圍,可以使用ROUT符號。如果沒有任何的AREA指示符定義,匯編器將會產(chǎn)生名為|$$$$$$$| 的AOF段和一條診斷信息,將限制由于缺少指示符而產(chǎn)生的錯誤信息,但是并不一定會成功匯編。

       

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

       

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

      。所以必須在LDR指令前后4KB的范圍內(nèi)用LTORG顯式地在代碼段中添加一個文字池。

       

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

       

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

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

       

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

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

       

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

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

       

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

       

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

       使用ALIGN符號,保證程序正確對準。對于Thumb地址,使用ALIGN符號保證其按字對準,例如:ADR  Thuub偽指令只能讀取字對準的地址。
          在代碼段出現(xiàn)數(shù)據(jù)定義符時,使用ALIGE符號。當在代碼段使用數(shù)據(jù)定義符(DCB,DCW,DCWU,DCDU和%),程序計數(shù)器PC并不一定按字對準。

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

       

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

       

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

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

       

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

       

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

      內(nèi)存表計數(shù)器的值將加上expr.expr表示本數(shù)據(jù)域在內(nèi)存中所占的字節(jié)數(shù)。

      使用說明:MAP偽操作和FIELD偽操作配合使用來定義結構化的內(nèi)存表結構。MAP偽操作定義內(nèi)存表的首地址。FIELD偽操作定義內(nèi)存表的數(shù)據(jù)域的字節(jié)長度,并可以為每一格數(shù)據(jù)域指定一個標號,其他指令可以引用該標號。

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

      舉例:基于絕對地址的內(nèi)存表

       用偽操作序列定義一個內(nèi)存表,其首地址為固定的地址8192(0X2000),該內(nèi)存表中包括5個數(shù)據(jù)域。  

          Consta長度為4個字節(jié);constb長為4個字節(jié),x長為8字節(jié);y長為8字節(jié);string長為16字節(jié)。這種內(nèi)存表成為基于絕對地址的內(nèi)存表。

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

      在指令中,可以這樣引用內(nèi)存表中的數(shù)據(jù)域;

      LDR R0,consta; //將consta地址處對應內(nèi)存加載到R0上面的指令僅僅可以訪問LDR指令前后4KB地址范圍的數(shù)據(jù)域。

      舉例:相對絕對地址的內(nèi)存表

       下面的偽操作序列定義一個內(nèi)存表,其首地址為0與R9寄存器值得和,該內(nèi)存表中包含5個數(shù)據(jù)域。這種表稱為相對地址的內(nèi)存表。

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

      可以通過下面的指令訪問地址范圍超過4KB的數(shù)據(jù);

      ADR  R9, Field ;  //偽指令
      LDR  R5,Constb;//相當于LDR R5,[R9,#4]

       在這里,內(nèi)存表中的數(shù)據(jù)都是相對于R9寄存器的內(nèi)容,而不是相對于一個固定的地址。通過在LDR中指定不同的基址寄存器的值,定義的內(nèi)存表結構可以在程序中有多個實例?啥啻问褂肔DR指令,用以實現(xiàn)不同的程序?qū)嵗?/P>

      舉例:基于PC的內(nèi)存表

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

      可以通過下面的指令訪問范圍不超過4kb的數(shù)據(jù);

      LDR R5,constb ;相當于 LDR R5,[PC,offset]

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

      還可以輸入 200 個字
      [ 查看全部 ] 網(wǎng)友評論
      關于我們 - 聯(lián)系我們 - 廣告服務 - 友情鏈接 - 網(wǎng)站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      主站蜘蛛池模板: 色综合99久久久无码国产精品| 亚洲七久久之综合七久久| 色综合色狠狠天天综合色| 六月婷婷国产精品综合| 综合偷自拍亚洲乱中文字幕| 精品综合久久久久久88小说| 伊人青青综合网站| 精品国产综合区久久久久久| 69国产成人综合久久精品91| 国产综合成色在线视频| 国产综合成人色产三级高清在线精品发布 | 一本久道久久综合狠狠躁| 久久久久久久综合综合狠狠| 久久本道综合久久伊人| 久久久亚洲裙底偷窥综合| 丁香亚洲综合五月天婷婷| 97se色综合一区二区二区| 婷婷综合另类小说色区| 亚洲国产综合精品中文字幕| 久久综合给合久久国产免费| 中文字幕色综合久久| 六月婷婷激情综合| 亚洲五月丁香综合视频| 狠狠色狠狠色综合日日不卡| 色综合久久天天综合观看| 亚洲sss综合天堂久久久| 精品亚洲综合久久中文字幕| 国产成人亚洲综合a∨| 亚洲乱码中文字幕小综合| 久久久久国产综合AV天堂| 99久久国产综合精品2020| 国产成人综合一区精品| 亚洲私人无码综合久久网| 国产成人综合久久精品免费| 国产成人综合精品| 狠狠色伊人久久精品综合网| 久久综合综合久久狠狠狠97色88| 狠狠色综合色综合网络| 99久久国产综合精品2020| 色综合久久一区二区三区| 色噜噜狠狠狠狠色综合久|