ARM的彙編學習

如果你還是學習電子通信的學生又或者是從事嵌入式電子通信工作的工程師、助理工程、實習生、打雜員,筆者想你也曾經對彙編有着複雜的恐懼,甚至是這一恐懼是大學裏學《微型計算機技術》開始的。但是就筆者淺薄的工作經歷看來,如果你能掌握或者退一步說能看懂彙編,那你才能享受到作爲一名底層硬件程序員的樂趣。試想一下用匯編任意操縱一款ARM內核處理器的寄存器、內存空間、外設空間,把它玩弄於手掌之中,這樣是不是很有成就感?

  同時,筆者認爲,要想對ARM內核有一個比較深刻的認識,還真非得過了彙編這關。因爲很多東西與彙編相關,例如ARM的中斷向量表,中斷過程中的工作模式、堆棧的變化,ARM的一些協處理器寄存器,Cache,MMU等。所以筆者覺得自己有必要記錄怎麼去搞一搞這ARM的彙編的。

  如果有人叫筆者現場來一段ARM彙編show,那還真考驗人,八成是寫不出,這可能也與筆者陋習有關,就是有些東西不用的話就很快被大腦遺忘。但是,但是,如果能給我一份ARM指令表,或相關編譯器的文檔用以查閱的話,寫出一段能用的ARM啓動文件,那還是問題不大的。所以如果實在記不來那所謂的“精簡指令集”的話,也不用太過灰心,下載一份前輩們整理出的指令表,據需要一條一條查。寫彙編程序時從“MOV、LDR 、STR”指令開始,也是一條一條把彙編用上去,然後自然而然就懂了。現在一些ARM內核處理器的官方彙編啓動文件貌似很複雜,可是筆者認爲大部分是因爲這樣的文件會將各種情況都考慮在其中,而在對於用戶來說可能就只會用到裏面的一種情況,所以如果用戶可以根據自己的系統進行改寫,那樣出來的程序則不會複雜。就筆者膚淺的認識,一段ARM的啓動文件,裏面只要有一段中斷向量表、和堆棧設置就可以將處理器跑起來。

  下面開始幾個簡單而又常用的指令。(筆者用的編譯環境是RVDS4.0,彙編指令大小書寫都是一樣哦)

  (1)mov 指令

       mov r0,#0x10 ;將一個立即數0x10賦給r0寄存器。mov指令就常用這一功能行了

       mov r0,r1   ;將寄存器r1的值賦給寄存器r0

   (2)ldr 指令

       ldr r0,=0x12345 ;將常數0x12345加載到r0寄存器,是不是與mov很像?

       ldr r0,[r1]  ;將地址爲r1值上的數加載給r0,拗口吧?例如r1=0x80000000的話,就相當於把地址

                    ;0x80000000處的值賦給r0,用C語言可以如下表示,unsigned int *pData=(unsigned 

                    ;int *)0x80000000,“r0”=*pData;此條指令可以衍生出很多常用的形式,不再舉例。

   注:無論是mov指令還是ldr指令,都可以將一個數賦給一個寄存器,但是對於mov指令,那個被“mov”的數是有條件限制的,並不是所以數都可以用mov指令來賦給一個寄存器,只能是由8bit(0或1)連續有效位通過偶數次移位能得到的數,於此可以得出一個結論就是凡是小等於255的數都可以用mov指令,大於255的也有行的哦。筆者習慣常用ldr指令,但是興致到濃時也會用一下mov指令,“mov”不了的話再改用ldr指令。

    (3)str 指令

       str r0,[r1] ;將寄存器r0的值寫到與地址爲r1上,如r1=0x80000000,則是往地址0x80000000寫入r0的值

   注,str 經常與ldr配套使用,也是最常用的一pair 指令了。

    (4)orr 指令

        orr r0,r0,r1 ;r0與r1按位或然後賦給r0

    (5)sub 指令

         sub r1, r1, #1 ;r1減1

         subs r1, r1, #1 ;與上是有區別的,特別是在ARM中斷返回時常用“subs”,要闡述這個的話得大量

                         ;語言,還是用到時自行查閱吧

     (6)b,bl 指令

           均是跳轉指令,跳轉範圍有限制的(ARM指令正負32MB,Thumb指令正負16MB)

          b指令是不帶鏈接的跳轉,用b指令跳到某一段子函數時,在執行完這段子函數後再也無法跳回來。

          bl指令是帶鏈接的跳轉,在跳轉前程序會自動將鏈接寄存器備份,在跳轉出去後還能跳回來。

     (7)循環指令

          mov r0,#3

          1    
              subs r0, r0, #1
              bne  �

           注:前面一段是r0減1,後面“bne”是判斷r0不等於0的話就執行“�”,其中裏面的“b”可以理解爲back,“1”是彙編標號,意思是r0不等於0時就向後找到第一個爲“1”的標號的指令段然後再按順序執行。其實就是循環3次了。

     (6)其他常用指令...

        查閱ARM指令集...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章