68精品久久久久久欧美,最近中文字幕完整在线看一,久久亚洲男人天堂,最近中文字幕完整视频高清1

您好,歡迎進入深圳市穎特新科技有限公司官方網(wǎng)站!

您現(xiàn)在的位置:首頁 新聞資訊 >> 新聞頭條 >> 說說C與匯編之間的互相聯(lián)系(轉)
新聞資訊
NEWS INFORMATION

說說C與匯編之間的互相聯(lián)系(轉)

發(fā)布時間:2019-05-22

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

1. 在C語言中內(nèi)嵌匯編 

在C中內(nèi)嵌的匯編指令包含大部分的ARM和Thumb指令,不過其使用與匯編文件中的指令有些不同,存在一些限制,主要有下面幾個方面:

a. 不能直接向PC寄存器賦值,程序跳轉要使用B或者BL指令
b. 在使用物理寄存器時,不要使用過于復雜的C表達式,避免物理寄存器沖突
c. R12和R13可能被編譯器用來存放中間編譯結果,計算表達式值時可能將R0到R3、R12及R14用于子程序調(diào)用,因此要避免直接使用這些物理寄存器
d. 一般不要直接指定物理寄存器,而讓編譯器進行分配 內(nèi)嵌匯編使用的標記是 __asm或者asm關鍵字,
用法如下: __asm { instruction [; instruction] … [instruction] } asm(“instruction [; instruction]”);
下面通過一個例子來說明如何在C中內(nèi)嵌匯編語言, 
在這里C和匯編之間的值傳遞是用C的指針來實現(xiàn)的,因為指針對應的是地址,所以匯編中也可以訪問。

#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; 
} 

 

2. 在匯編中使用C定義的全局變量 

內(nèi)嵌匯編不用單獨編輯匯編語言文件,比較簡潔,但是有諸多限制,當匯編的代碼較多時一般放在單獨的匯編文件中。這時就需要在匯編和C之間進行一些數(shù)據(jù)的傳遞,最簡便的辦法就是使用全局變量。
 /* cfile.c * 定義全局變量,并作為主調(diào)程序 */

#include 
int gVar_1 = 12; 
extern asmDouble(void); 
int main() 
{ 
printf("original value of gVar_1 is: %d", 
gVar_1); 
asmDouble(); 
printf(" modified value of gVar_1 is: %d", gVar_1); 
return 0; 
} 
對應的匯編語言文件 ;
called by main(in C),
to double an integer, 
a global var defined in C is used. 
AREA asmfile, 
CODE, 
READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0, 
=gVar_1 ldr r1, 
[r0] mov r2, #2 
mul r3, r1, r2 str r3, [r0] mov pc, lr END

 /* cfile.c * 定義全局變量,并作為主調(diào)程序 */
 #include 
int gVar_1 = 12; 
extern asmDouble(void); 
int main() 
{ 
printf("original value of gVar_1 is: %d", 
gVar_1); 
asmDouble(); 
printf(" modified value of gVar_1 is: %d", gVar_1); 
return 0; 
} 

 

對應的匯編語言文件 ;

called by main(in C),
to double an integer, 
a global var defined in C is used. 
AREA asmfile, 
CODE, 
READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0, 
=gVar_1 ldr r1, 
[r0] mov r2, #2 
mul r3, r1, r2 str r3, [r0] mov pc, lr END

 

3. 在C中調(diào)用匯編的函數(shù) 

在C中調(diào)用匯編文件中的函數(shù),要做的主要工作有兩個,

一是在C中聲明函數(shù)原型,并加extern關鍵字;
二是在匯編中用EXPORT導出函數(shù)名,并用該函數(shù)名作為匯編代碼段的標識,最后用mov pc, lr返回。然后,就可以在C中使用該函數(shù)了。從C的角度,并不知道該函數(shù)的實現(xiàn)是用C還是匯編。更深的原因是因為C的函數(shù)名起到表明函數(shù)代碼起始地址的左右,這個和匯編的label是一致的。

called by main(in C),
to double an integer, 
a global var defined in C is used. 
AREA asmfile, 
CODE, 
READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0, 
=gVar_1 ldr r1, 
[r0] mov r2, #2 
mul r3, r1, r2 str r3, [r0] mov pc, lr END

 

在這里,C和匯編之間的參數(shù)傳遞是通過ATPCS(ARM Thumb Procedure Call Standard)的規(guī)定來進行的。簡單的說就是如果函數(shù)有不多于四個參數(shù),對應的用R0-R3來進行傳遞,多于4個時借助棧,函數(shù)的返回值通過R0來返回。

4. 在匯編中調(diào)用C的函數(shù),

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

;the details of parameters transfer comes from ATPCS ;

if there are more than 4 args, stack will be used EXPORT asmfile AREA asmfile, CODE, READONLY IMPORT cFun ENTRY mov r0,

#11 mov r1,

#22 mov r2,

#33 BL cFun END /*C file, called by asmfile */

int cFun(int a, int b, int c)

{

return a + b + c;

}

在匯編中調(diào)用C的函數(shù),參數(shù)的傳遞也是通過ATPCS來實現(xiàn)的。需要指出的是當函數(shù)的參數(shù)個數(shù)大于4時,要借助stack,具體見ATPCS規(guī)范。

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

說明 以上代碼在ADS 1.2的工程中編譯,并在對應的AXD中軟件仿真通過。

聯(lián)系方式0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08

永川市| 商南县| 邵武市| 扶风县| 绿春县| 攀枝花市| 尼木县| 西宁市| 彭泽县| 南宫市| 英吉沙县| 兴宁市| 繁昌县| 嘉荫县| 石嘴山市| 集安市| 江口县| 宽城| 鹿邑县| 双流县| 江孜县| 兴隆县| 鞍山市| 舒城县| 柳江县| 桃江县| 廉江市| 蓬安县| 资兴市| 萍乡市| 兖州市| 张家港市| 井冈山市| 新密市| 延寿县| 科技| 古丈县| 广丰县| 贺兰县| 来安县| 武安市|