C與匯編混合編程的實現(xiàn)示例
上一期中,使用鏈表的方式進行對不同任務的調用,實現(xiàn)的效果還是不錯的,但是,任務在進行過程中不能進行來回的切換,必須要執(zhí)行完,這是一個弊端,若不使用實時操作系統(tǒng)的情況下,如何切換呢,那就要說一下萬能的匯編了,用匯編則可以做到任務的切換
首先我們知道,c與匯編的聯(lián)合使用就三種情況,如下
1. C語言內聯(lián)匯編
首先看一下代碼
__inline int ADD(int input1,int intput2)
{
int output;
__asm{
ADD output,input1,intput2
}
return output;
}
int Number(void);
int value;
int main(void)
{
int a = 12,b = 13;
while(1)
{
value = ADD(a,b);
}
}
執(zhí)行效果

0x19的十進制為25
2. C語言調用匯編函數(shù)
調用匯編函數(shù),首先創(chuàng)建一個.s匯編文件

創(chuàng)建完成后,在匯編文件中寫入一個匯編函數(shù)
AREA |.text|,CODE,READONLY EXPORT Get_Number Get_Number MOV R0,#761 BX LR ALIGN END
然后寫一個main函數(shù)調用它
int Get_Number(void);
int value;
int main(void)
{
while(1)
{
value = Get_Number();
}
}
查看執(zhí)行效果

3. 匯編代碼調用C語言函數(shù)
在匯編文件中,輸入如下代碼
AREA |.text|,CODE,READONLY IMPORT Get_Number IMPORT Number EXPORT __main ENTRY __main LDR R1,=Number MOV R0,#100 STR R0,[R1] BL Get_Number END
在C文件中輸入如下代碼
int Number;
int Get_Number(void)
{
Number = Number + 32;
return Number;
}
看一下執(zhí)行效果吧


繼續(xù)向下執(zhí)行

數(shù)字由100變成132;實現(xiàn)功能
解釋說明:
/*
AREA
語法格式:
AREA 段名 屬性1 ,屬性2 ,……
AREA偽指令用于定義一個代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開頭,則該段名需用“|”括起來,如:|1_test| 。
屬性字段表示該代碼段(或數(shù)據(jù)段)的相關屬性,多個屬性用逗號分隔。常用的屬性如下:
— CODE 屬性:用于定義代碼段,默認為READONLY 。
— DATA 屬性:用于定義數(shù)據(jù)段,默認為READWRITE 。
— READONLY 屬性:指定本段為只讀,代碼段默認為READONLY 。
— READWRITE 屬性:指定本段為可讀可寫,數(shù)據(jù)段的默認屬性為READWRITE 。
— ALIGN 屬性:使用方式為ALIGN表達式。在默認時,ELF(可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對齊的,表達式的取值范圍為0~31,相應的對齊方式為2表達式次方。
— COMMON 屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數(shù)據(jù)。各源文件中同名的COMMON段共享同一段存儲單元。
*/
/*
MOV
傳送指令 將右邊數(shù)據(jù)移入左邊寄存器
LDR
將右值地址存的數(shù)據(jù)移入左邊寄存器
BX
通用寄存器 里面存入基地址、偏移量、臨時數(shù)據(jù)
BL
跳轉指令
LR r14
(1)當使用bl或者blx跳轉到子過程的時候,r14保存了返回地址,可以在調用過程結尾恢復
(2)異常中斷發(fā)生時,這個異常模式特定的物理R14被設置成該異常模式將要返回的地址
ENTRY 是程序入口偽指令。在一個完整的匯編程序中至少有一個 ENTRY,編譯程序在編譯連接時依據(jù)程序入口進行連接。
在只有一個入口時,編譯程序會把這個入口的地址定義為系統(tǒng)復位后的程序起始點。但在一個源文件里最多只能有一個 ENTRY。
ENDP 表示PROC所定義的過程結束. (end procedure)
ENDS 表示SEGMENT定義的段結束. (end segment)
END 程序結束.
*/
使用BL跳轉
BL指令同時還將PC寄存器的值保存到LR寄存器中,是帶返回的跳轉指令
所以
假設在一個匯編程序中,要調用兩個C語言函數(shù)
用事實證明可以返回
將匯編代碼修改為如下
AREA |.text|,CODE,READONLY IMPORT Get_Number IMPORT Number IMPORT Get_Value IMPORT Value EXPORT __main ENTRY __main LDR R1,=Number MOV R0,#100 STR R0,[R1] BL Get_Number LDR R1,=Value MOV R0,#100 STR R0,[R1] BL Get_Value END
對應的c文件為
int Number;
int Get_Number(void)
{
Number = Number + 32;
return Number;
}
int Value;
int Get_Value(void)
{
Value = Value - 32;
return Value;
}
查看代碼執(zhí)行情況
首先進行第一個函數(shù)的執(zhí)行,數(shù)字發(fā)生改變

接下來是第二個函數(shù)執(zhí)行,數(shù)字發(fā)生改變

證明BL跳轉可以返回。
可以使用匯編加C語言的編程思路,打破一些限制
也為后面進行PC的跳轉打下基礎
到此這篇關于C與匯編混合編程的實現(xiàn)示例的文章就介紹到這了,更多相關C與匯編混合編程 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
利用Matlab仿真實現(xiàn)圖像煙霧識別(k-means聚類圖像分割+LBP+PCA+SVM)
本文主要介紹了利用k-means聚類實現(xiàn)圖像分割+LBP算法進行特征提取+PCA算法進行特征降維+SVM算法訓練二分類模型從而實現(xiàn)煙霧識別。文中介紹很詳細,感興趣的朋友可以了解一下2021-12-12
C++使用模板實現(xiàn)單鏈表(類外實現(xiàn))
這篇文章主要為大家詳細介紹了C++使用模板實現(xiàn)單鏈表的相關資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12
C語言實現(xiàn)一個文件版動態(tài)通訊錄流程詳解
這篇文章主要介紹了C語言實現(xiàn)一個文件版動態(tài)通訊錄流程,希望大家能從這篇文章中收獲到許多,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01
Qt采用線程以隊列方式實現(xiàn)下發(fā)數(shù)據(jù)
在C++中隊列是一種常用的數(shù)據(jù)結構之一,一種特殊的線性表,一般采用先進先出的方式。本文主要為大家介紹了Qt如何以隊列方式實現(xiàn)下發(fā)數(shù)據(jù),感興趣的可以了解一下2022-10-10

