除了匯編語言工程和C語言工程,許多嵌入式工程既包含C語言又包含匯編語言。由于Keil MDK的默認啟動代碼是用匯編編寫的,但是又是獨立的一個啟動代碼是匯編實現(xiàn),一般其他程序都是C語言實現(xiàn)。
我們一起來看下混合語言工程中,就比如在匯編程序中調用C函數(shù),或者在C語言代碼中調用匯編函數(shù)需要注意什么,稍不留意結果就可能是無法預測的。比如程序在一種版本的編譯器下可以正常工作,而在另外的版本下,或者更換編譯器后,工程可能會由于寄存器的使用沖突而停止工作。
1、在匯編中調用C函數(shù)
當在匯編文件中調用C函數(shù)的時候,需要注意一下方面:
①寄存器R0到R3、R12以及LR可能會被更改,如果這些寄存器中的數(shù)據(jù)之后還要使用,就需要將它們保存到棧上。
②SP的值應該是雙字對齊的
③需要確保輸入?yún)?shù)存儲在正確的寄存器中(比如簡單例子,使用R0~R3)
④返回值(假定為32位或更?。┮话愦嬖赗0中
舉個例子:如果有一個將四個值相加的函數(shù):
int my_add(int x1,int x2,int x3,int x4)
{
return (x1+x2+x3+x4);
}
在Keil MDK中,可以使用以下的代碼在匯編中調用C函數(shù):
MOVS R0,#1 ;第一個參數(shù)(x1)
MOVS R1,#2 ;第二個參數(shù)(x2)
MOVS R2,#3 ;第三個參數(shù)(x3)
MOVS R3,#4 ;第四個參數(shù)(x4)
IMPORT my_add
BL my_add ;調用“my_add”函數(shù),結果保存在R0中
如果匯編代碼是按照C文件中的嵌入式匯編編寫的,應該使用_CPP關鍵字代替IMPORT關鍵字來引入地址符號。
_CPP的用法如下:
上例程中:
IMPORT my_add
BL my_add ;調用“my_add”函數(shù),結果保存在R0中
改為:
BL _CPP(my_add) ;調用“my_add”函數(shù),結果保存在R0中
在Keil MDK中,_CPP關鍵字用于訪問C或C++編譯時的常量表達式,而對于其他工具鏈,情況可能就有所不同了。
2、在C代碼中調用匯編函數(shù)
如果要從C代碼中調用匯編函數(shù),在實現(xiàn)匯編函數(shù)時,需要注意一下幾點:
①若改變了寄存器R4到R11里的任何數(shù)值,需要將原始數(shù)值保存到棧中,并且在返回到C代碼以前恢復原始值。
②若要在匯編函數(shù)中調用另一個函數(shù),需要將LR的值保存在棧中,并且利用它執(zhí)行返回操作。
③函數(shù)返回值一般存在R0中
舉個例子:如果一個實現(xiàn)4個數(shù)相加的匯編函數(shù):
EXPORT my_add
my_add FUNCTION
ADDS R0,R0,R1
ADDS R0,R0,R2
ADDS R0,R0,R3
BX LR ;返回值在R0中
ENDFUNC
在C代碼中,需要將函數(shù)聲明為:
extern int my_add(int x1,int x2,int x3,int x4);
int y;
……
y= my_add(1,2,3,4);//調用my_add函數(shù)
如果匯編代碼需要訪問C代碼中的一些變量,也可以使用IMPORT關鍵字。
大多數(shù)情況下,可能只需要一到兩個簡單的匯編函數(shù),所以就想將這些匯編代碼嵌入C代碼的文件中。多數(shù)開發(fā)工具都有一種被稱作內(nèi)聯(lián)匯編的特性,而ARM工具鏈則采用了另外一種特性“嵌入?yún)R編”。
通過嵌入?yún)R編,我們可以在C文件中實現(xiàn)匯編函數(shù)。例如,將4個參數(shù)相加的函數(shù)可以如下寫法:
_asm int my_add(int x1,int x2,int x3,int x4)
{
ADDS R0,R0,R1
ADDS R0,R0,R2
ADDS R0,R0,R3
BX LR ;返回值在R0中
}
可以在C代碼中像普通C函數(shù)一樣調用這個函數(shù):
y = my_add(1,2,3,4);
嵌入?yún)R編允許你在異常處理中定位棧幀,這也是嵌入?yún)R編的一個優(yōu)勢。
責任編輯:haq
-
C語言
+關注
關注
180文章
7632瀏覽量
141495 -
函數(shù)
+關注
關注
3文章
4379瀏覽量
64765
原文標題:C語言與匯編混合工程
文章出處:【微信號:gh_e7f294a514ca,微信公眾號:單片機匠人】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
深入理解C語言:函數(shù)—編程中的“積木塊”藝術

穩(wěn)壓器在安裝接線前需要注意哪些

分析C語言代碼結構的設計問題
速度探頭在使用過程中需要注意哪些問題呢
C語言如何處理函數(shù)的返回值
EE-128:C語言中的DSP:從C調用匯編類成員函數(shù)

AKI跨語言調用庫神助攻C/C++代碼遷移至HarmonyOS NEXT
c51單片機中斷
TMS320LF240x DSP的C語言和匯編代碼快速入門

hex文件怎么能轉回去c語言
hex文件如何查看原c語言代碼
bnc公頭注塑需要注意什么

評論