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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > arm中ads實現(xiàn)c和匯編混合編譯的方法

          arm中ads實現(xiàn)c和匯編混合編譯的方法

          作者: 時間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          嵌入式系統(tǒng)開發(fā)中,目前使用的主要編程語言是C 和匯編,雖然C++已經(jīng)有相應(yīng)的編譯器,但是現(xiàn)在使用還是比較少的。

          在稍大規(guī)模的嵌入式程序設(shè)計中,大部分的代碼都是用C來編寫的,主要是因為C語言具有較強(qiáng)的結(jié)構(gòu)性,便于人的理解,并且具有大量的庫支持。但對于一寫硬件上的操作,很多地方還是要用到匯編語言,例如硬件系統(tǒng)的初始化中的CPU 狀態(tài)的設(shè)定,中斷的使能,主頻的設(shè)定,RAM控制參數(shù)等。另外在一些對性能非常敏感的代碼塊,基于匯編與機(jī)器碼一一對應(yīng)的關(guān)系,這時不能依靠C編譯器的生成代碼,而要手工編寫匯編,從而達(dá)到優(yōu)化的目的。匯編語言是和CPU的指令集緊密相連的,作為涉及底層的嵌入式系統(tǒng)開發(fā),熟練對應(yīng)匯編語言的使用也是必須的。
          單純的C或者匯編編程請參考相關(guān)的書籍或者手冊,這里主要討論C和匯編的混合編程,包括相互之間的函數(shù)調(diào)用。下面分四種情況來進(jìn)行討論,不涉及C++語言。

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

          一、在C語言中內(nèi)嵌匯編
          在C中內(nèi)嵌的匯編指令包含大部分的ARM和Thumb指令,不過使用與單純的匯編程序使用的指令略有不同,存在一些限制,主要有下面幾個方面:
          a 不能直接向PC 寄存器賦值,程序跳轉(zhuǎn)要使用B或者BL指令;
          b 在使用物理寄存器時,不要使用過于復(fù)雜的C表達(dá)式,避免物理寄存器沖突;
          c R12和R13可能被編譯器用來存放中間編譯結(jié)果,計算表達(dá)式值時可能把R0-R3、R12及R14用于子程序調(diào)用,因此避免直接使用這些物理寄存器;
          d 一般不要直接指定物理寄存器;
          e 讓編譯器進(jìn)行分配內(nèi)嵌匯編使用的標(biāo)記是__asm或asm關(guān)鍵字,用法如下:

          __asm{instruction [; instruction]}或

          asm("instruction

          [; instruction]")

          下面是一個例子來說明如何在C中內(nèi)嵌匯編語言:

          //C語言文件*.c

          #include
          void my_strcpy(const char *src, char *dest){
          char ch;
          __asm{
          loop:
          ldrb ch, [src], #1
          strb ch, [dest], #1
          cmp ch, #0
          bne loop
          }
          }
          int main(){
          char *a="forget it and move on!";
          char b[64];
          my_strcpy(a, b);
          printf("original: %s", a);
          printf("copyed: %s", b);
          return 0;
          }
          在此例子中C語言和匯編之間的值傳遞是用C語言的指針來實現(xiàn)的,因為指針對應(yīng)的是地址,所以匯編中也可以訪問。

          二、在匯編中使用C定義的全局變量
          內(nèi)嵌匯編不用單獨編輯匯編語言文件,比較簡潔,但是有很多的限制。當(dāng)匯編的代碼較多時一般放在單獨的匯編文件中,這時就需要在匯編文件和C文件之間進(jìn)行一些數(shù)據(jù)的傳遞,最簡便的辦法就是使用全局變量。
          下面是一個C語言和匯編語言共享全局變量的例子:

          //C語言文件*.c
          #include
          int gVar=12;
          extern asmDouble(void);
          int main(){
          printf("original value of gVar is: %d", gVar_1);
          asmDouble();
          printf(" modified value of gVar is: %d", gVar_1);
          return 0;
          }

          ;匯編語言文件*.S
          AREA asmfile, CODE, READONLY

          EXPORT asmDouble
          IMPORT gVar
          asmDouble
          ldr r0, =gVar
          ldr r1, [r0]
          mov r2, #2
          mul r3, r1, r2
          str r3, [r0]
          mov pc, lr
          END
          在此例中,匯編文件與C文件之間相互傳遞了全局變量gVar和函數(shù)asmDouble,留意聲明的關(guān)鍵字extern和IMPORT


          三、在C中調(diào)用匯編的函數(shù)
          有一些對機(jī)器要求高的敏感函數(shù),通過C語言編寫再通過C編譯器翻譯有時會出現(xiàn)誤差,因此這樣的函數(shù)一般采用匯編語言來編寫,然后供C語言調(diào)用。在C文件中調(diào)用匯編文件中的函數(shù),要注意的有兩點,一是要在C文件中聲明所調(diào)用的匯編函數(shù)原型,并加入extern關(guān)鍵字作為引入函數(shù)的聲明;二是在匯編文件中對對應(yīng)的匯編代碼段標(biāo)識用EXPORT關(guān)鍵字作為導(dǎo)出函數(shù)的聲明,函數(shù)通過mov pc, lr指令返回。這樣,就可以在C文件中使用該函數(shù)了。從C語言的角度的角度,并不知道調(diào)用的函數(shù)的實現(xiàn)是用C語言還是匯編匯編語言,原因C語言的函數(shù)名起到表明函數(shù)代碼起始地址的作用,而這個作用和匯編語言的代碼段標(biāo)識符是一致的。
          下面是一個C語言調(diào)用匯編函數(shù)例子:
          //C語言文件*.c
          #include
          extern void asm_strcpy(const char *src, char *dest);
          int main(){
          const char *s="seasons in the sun"; char d[32];
          asm_strcpy(s, d);
          printf("source: %s", s);
          printf(" destination: %s",d);
          return 0;
          }

          ;匯編語言文件*.S
          AREA asmfile, CODE, READONLY
          EXPORT asm_strcpy
          asm_strcpy
          loop
          ldrb r4, [r0], #1
          cmp r4, #0
          beq over
          strb r4, [r1], #1
          b loop
          over
          mov pc, lr
          END
          在此例中,C語言和匯編語言之間的參數(shù)傳遞是通過對應(yīng)的用R0-R3來進(jìn)行傳遞,即R0傳遞第一個參數(shù),R1傳遞第二個參數(shù),多于4個時借助棧完成,函數(shù)的返回值通過R0來傳遞。這個規(guī)定叫作ATPCS(ARM Thumb Procedure Call Standard),具體見ATPCS規(guī)范。

          四、在匯編中調(diào)用C的函數(shù)
          在匯編語言中調(diào)用C語言的函數(shù),需要在匯編中IMPORT對應(yīng)的C函數(shù)名,然后將C的代碼放在一個獨立的C文件中進(jìn)行編譯,剩下的工作由連接器來處理。
          下面是一個匯編語言調(diào)用C語言函數(shù)例子:
          //C語言文件*.c

          int cFun(int a, int b, int c){
          return a+b+c;
          }

          ;匯編語言文件*.S
          AREA asmfile, CODE, READONLY
          IMPORT cFun
          start
          mov r0, #0x1
          mov r1, #0x2
          mov r2, #0x3
          bl cFun
          nop
          nop
          b start
          END

          在匯編語言中調(diào)用C語言的函數(shù),參數(shù)的傳遞也是按照ATPCS規(guī)范來實現(xiàn)的。

          在這里簡單介紹一下部分ATPCS規(guī)范:

          子程序間通過寄存器R0~R3來傳遞參數(shù)。
          A.在子程序中,使用寄存器R4~R11來保存局部變量。
          B.寄存器R12用于子程序間scratch寄存器(用于保存SP,在函數(shù)返回時使用該寄存器出桟),記作IP。
          C.寄存器R13用于數(shù)據(jù)棧指針,記作SP。寄存器SP在進(jìn)入子程序時的值和退出子程序時的值必須相等。
          D.寄存器R14稱為鏈接寄存器,記作LR。它用于保存子程序的返回地址。
          E.寄存器R15是程序計數(shù)器,記作PC
          F.參數(shù)不超過4個時,可以使用寄存器R0~R3來傳遞參數(shù),當(dāng)參數(shù)超過4個時,還可以使用數(shù)據(jù)棧來傳遞參數(shù)。
          G.結(jié)果為一個32位整數(shù)時,可以通過寄存器R0返回
          H.結(jié)果為一個64位整數(shù)時,可以通過寄存器R0和R1返回,依次類推。

          以上通過幾個簡單的例子演示了嵌入式開發(fā)中常用的C 和匯編混合編程的一些方法和基本的思路,其實最核心的問題就是如何在C 和匯編之間傳值,剩下的問題就是各自用自己的方式來進(jìn)行處理。以上只是拋磚引玉,更詳細(xì)和復(fù)雜的使用方法要結(jié)合實際應(yīng)用并參考相關(guān)的資料。



          關(guān)鍵詞: armads混合編

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁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); })();