新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM中ADS環境下C語言和匯編語言混合編程及示例

        ARM中ADS環境下C語言和匯編語言混合編程及示例

        作者: 時間:2016-08-10 來源:網絡 收藏

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

        本文引用地址:http://www.104case.com/article/201608/295298.htm

          一、在C語言中內嵌匯編

          在C中內嵌的匯編指令包含大部分的和Thumb指令,不過使用與單純的匯編程序使用的指令略有不同,存在一些限制,主要有下面幾個方面:

          a 不能直接向PC 寄存器賦值,程序跳轉要使用B或者BL指令;

          b 在使用物理寄存器時,不要使用過于復雜的C表達式,避免物理寄存器沖突;

          c R12和R13可能被編譯器用來存放中間編譯結果,計算表達式值時可能把R0-R3、R12及R14用于子程序調用,因此避免直接使用這些物理寄存器;

          d 一般不要直接指定物理寄存器;

          e 讓編譯器進行分配內嵌匯編使用的標記是__asm或asm關鍵字,用法如下:__asm{instruction [; instruction]}或 asm(instruction

          [; instruction])。

          下面是一個例子來說明如何在C中內嵌匯編語言

          C語言文件.c httphi.baidu.comprocatlaw

          #include stdio.h

          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語言的指針來實現的,因為指針對應的是地址,所以匯編中也可以訪問。

          二、在匯編中使用C定義的全局變量

          內嵌匯編不用單獨編輯匯編語言文件,比較簡潔,但是有很多的限制。當匯編的代碼較多時一般放在單獨的匯編文件中,這時就需要在匯

          編文件和C文件之間進行一些數據的傳遞,最簡便的辦法就是使用全局變量。

          下面是一個C語言和匯編語言共享全局變量的例子:

          C語言文件.c

          #include stdio.h

          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 httphi.baidu.comprocatlaw

          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和函數asmDouble,留意聲明的關鍵字extern和IMPORT

          三、在C中調用匯編的函數

          有一些對機器要求高的敏感函數,通過C語言編寫再通過C編譯器翻譯有時會出現誤差,因此這樣的函數一般采用匯編語言來編寫,然后供C語言調用。在C文件中調用匯編文件中的函數,要注意的有兩點,一是要在C文件中聲明所調用的匯編函數原型,并加入extern關鍵字作為引入函數的聲明;二是在匯編文件中對對應的匯編代碼段標識用EXPORT關鍵字作為導出函數的聲明,函數通過mov pc, lr指令返回。這樣,就可以在C文件中使用該函數了。從C語言的角度的角度,并不知道調用的函數的實現是用C語言還是匯編匯編語言,原因C語言的函數名起到表明函數

          代碼起始地址的作用,而這個作用和匯編語言的代碼段標識符是一致的。

          下面是一個C語言調用匯編函數例子:

          C語言文件.c httphi.baidu.comprocatlaw

          #include stdio.h

          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 httphi.baidu.comprocatlaw

          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語言和匯編語言之間的參數傳遞是通過對應的用R0-R3來進行傳遞,即R0傳遞第一個參數,R1傳遞第二個參數,多于4個時借助棧完成,函數的返回值通過R0來傳遞。這個規定叫作ATPCS( Thumb Procedure Call Standard),具體見ATPCS規范。

          四、在匯編中調用C的函數

          在匯編語言中調用C語言的函數,需要在匯編中IMPORT對應的C函數名,然后將C的代碼放在一個獨立的C文件中進行編譯,剩下的工作由連接器來處理。

          下面是一個匯編語言調用C語言函數例子:

          C語言文件.c int cFun(int a, int b, int c){ return a+b+c;}

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

          EXPORT cFun

          start

          mov r0, #0x1

          mov r1, #0x2

          mov r2, #0x3

          bl cFun

          nop

          nop

          b start

          END

          在匯編語言中調用C語言的函數,參數的傳遞也是按照ATPCS規范來實現的。

          在這里簡單介紹一下部分ATPCS規范:子程序間通過寄存器R0~R3來傳遞參數。

          A.在子程序中,使用寄存器R4~R11來保存局部變量。

          B.寄存器R12用于子程序間scratch寄存器(用于保存SP,在函數返回時使用該寄存器出桟),記作IP。

          C.寄存器R13用于數據棧指針,記作SP。寄存器SP在進入子程序時的值和退出子程序時的值必須相等。

          D.寄存器R14稱為鏈接寄存器,記作LR。它用于保存子程序的返回地址。

          E.寄存器R15是程序計數器,記作PC

          F.參數不超過4個時,可以使用寄存器R0~R3來傳遞參數,當參數超過4個時,還可以使用數據棧來傳遞參數。

          G.結果為一個32位整數時,可以通過寄存器R0返回

          H.結果為一個64位整數時,可以通過寄存器R0和R1返回,依次類推。



        關鍵詞: ARM 嵌入式系統

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 嘉鱼县| 桦南县| 漯河市| 东台市| 徐闻县| 连平县| 惠来县| 彭阳县| 阿勒泰市| 宁南县| 石棉县| 安阳县| 岳西县| 万荣县| 化州市| 宝应县| 清徐县| 南木林县| 湛江市| 天祝| 安化县| 阿拉尔市| 郧西县| 荣昌县| 呼和浩特市| 民县| 玉门市| 正镶白旗| 茌平县| 扎囊县| 墨江| 泰顺县| 合山市| 察隅县| 潞西市| 乐都县| 神农架林区| 景谷| 汕头市| 沅江市| 开化县|