<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > ARM匯編編程基礎之四-ARM匯編偽操作

          ARM匯編編程基礎之四-ARM匯編偽操作

          作者: 時間:2016-11-27 來源:網(wǎng)絡 收藏
          掌握了基本的ARM匯編指令后,要寫出簡單的ARM匯編程序,還必須要掌握基本的ARM匯編偽操作(directive)?,F(xiàn)在我們來看一個簡單的匯編程序,該程序調用子程序完成了加法操作。

          1 ;文件名:TEST.S
          2 ;功能:實現(xiàn)兩個寄存器相加
          3AREA Example,CODE,READONLY ;聲明代碼段Example
          4ENTRY ;標識程序入口
          5CODE32 ;聲明32位ARM指令
          6STARTMOV R0,#0 ;設置參數(shù)
          7MOV R1,#10
          8LOOP BL ADD_SUB ;調用子程序ADD_SUB
          9B LOOP ;跳轉到LOOP
          10 ADD_SUB
          11ADD R0,R0,R1 ;R0 = R0 + R1
          12MOV PC,LR ;子程序返回
          13END ;文件結束

          本文引用地址:http://www.ex-cimer.com/article/201611/322181.htm

          第6、7行將傳遞給子程序的參數(shù)存放在r0和r1中,第8行調用子程序。第11、12行是子程序的代碼,完成了2個參數(shù)相加,并將結果放在r0后返回主程序。第6、8、10行的START、LOOP、ADD_SUB是標號,最經(jīng)常用于跳轉指令B和BL,由于匯編語法要求的緣故,標號必須頂格寫(即:不能在行首有空格),否則編譯器會報錯。與之對應的是,匯編指令一定不能頂格寫。

          很明顯分號(;)在匯編程序中是注釋符號,相當于C語言的//號。除此之外,當然大家注意到了第3、4、5、13行是我們沒學習過的符號,其實它們就是本文的重點——ARM匯編偽操作。首先我先來解釋這幾個偽操作,第3行定義了一個代碼段,其段名為Example,屬性為只讀,從而表示第6——12行是程序代碼(而不是程序數(shù)據(jù))。第4行表示整個程序的入口點(即:程序運行的第一條指令)是第6行的MOV指令(注1)。第5行表示第6——12行的程序代碼是ARM指令,而不是thumb指令。第13行表示源代碼文件結束,其背后的含義就是:如果程序員在第13行后還寫有匯編指令,編譯器也根本不會理會這些代碼,更不會去編譯它們,當然這些代碼也就不可能出現(xiàn)在最后的可執(zhí)行文件中。哈哈,所以請務必記住,在END偽操作的后面再寫代碼,那是無用功,寫了也白寫。不要不以為然喲,根據(jù)經(jīng)驗,初學者總是會犯這樣的錯誤。

          特別說明:第9行的含義是要讓程序在運行結束后,在第9行進行死循環(huán),從而讓整個程序定格在第9行。這一點也許你很困惑:在寫應用程序時,程序結束就結束了,源代碼根本不需要再去寫個死循環(huán)。但你現(xiàn)在要弄清楚:你寫應用程序時,有OS為你處理程序結束后的若干事情??墒?,你現(xiàn)在已經(jīng)得不到OS服務。如果你不自己寫第9行的代碼,那么當你認為程序已經(jīng)運行結束(第8行執(zhí)行完成)的時候,CPU不會聰明地停下來,它會繼續(xù)任勞任怨地去取指第11行,繼續(xù)運行,這不是你所希望的。其實這還不是最糟糕的,最糟糕的是,如果你的程序沒有11-13行,那么CPU任勞任怨取出的指令其實是內存中的隨機數(shù),但CPU卻會把它當作指令來執(zhí)行,那么,你認為此時會出現(xiàn)什么情況呢?哈哈,只有天知道。

          當然,偽操作遠不止這幾條,下面我們再來介紹經(jīng)常使用的若干偽操作。

          GBLA:定義全局算術變量(準確說,應該是全局符號),例如:GBLA testval

          SETA:對全局算術符號進行賦值,例如:testvalSETA9;testval SETA testval + 1

          DCD:在編譯時為整數(shù)分配字存儲空間,例如:DCD 0x123456ab,這條偽操作將導致編譯器在最終的二進制可執(zhí)行文件中分配一個字的空間,并在該空間中存放整數(shù)0x123456ab

          DCB:在編譯時為整數(shù)分配字節(jié)存儲空間,例如:DCB ‘a’,這條偽操作將導致編譯器在最終的二進制可執(zhí)行文件中分配一個字節(jié)的空間,并在該空間中存放字符a的ASCII碼

          IF,ELSE及ENDIF:相當于C語言的條件編譯,例如:

          GBLA testval
          testvalSETA 9
          IF testval < 5
          mov r0, #testval
          ELSE
          mov r1, #testval
          ENDIF
          IF :DEF:testval
          mov r2, #testval
          ELSE
          INFO 4, "you should define testval"
          ENDIF

          編譯器編譯該段代碼的結果是:

          mov r1, #9

          mov r2, #9

          WHILE及WEND:例如

          GBLA testval
          testval SETA 1
          WHILE testval <= 3
          testval SETA testval + 1
          mov r0, #testval
          WEND

          編譯器編譯該段代碼的結果是:

          mov r0, #2

          mov r0, #3

          mov r0, #4

          MACRO、MEND及MEXIT:相當于C語言的宏替換,例如:

          MACRO
          $label xmac $p1,$p2
          ; code1
          $label.loop1
          ;code2
          BGE $label.loop1
          $label.loop2
          ;code3
          BL $p1
          BGT $label.loop2
          ; code4
          ADR r0, $p2
          ;code5
          MEND
          ;主程序
          abc xmac subr1,de

          編譯器編譯該段代碼的結果是:

          ;code1
          abc.loop1
          ;code2
          BGE abc.loop1
          abc.loop2
          ;code3
          BL subr1
          BGT abc.loop2
          ;code4
          ADR r0, de
          ;code5

          EQU:相當于C語言的宏定義,例如:testval EQU 4

          EXPORT: 見“ATPCS與混合編程”一文

          IMPORT:見“ATPCS與混合編程”一文

          非常重要的一點是:必須深刻理解匯編偽操作是給編譯器提供某些必要的信息,以幫助編譯器正確完成程序的編譯。當編譯完成后,匯編偽操作就完成了它的歷史使命,它不可能在最終的可執(zhí)行程序的二進制代碼中留下哪怕是一點點痕跡,當然也就不可能在程序運行時受到CPU的“青睞”。總之記住一句話,匯編偽操作是給編譯器看的,而不是給CPU看的。這是匯編偽操作與匯編指令最大的區(qū)別。


          上一頁 1 2 下一頁

          關鍵詞: ARM匯編編程偽操

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();