C與匯編混合編程的實現示例
上一期中,使用鏈表的方式進行對不同任務的調用,實現的效果還是不錯的,但是,任務在進行過程中不能進行來回的切換,必須要執行完,這是一個弊端,若不使用實時操作系統的情況下,如何切換呢,那就要說一下萬能的匯編瞭,用匯編則可以做到任務的切換
首先我們知道,c與匯編的聯合使用就三種情況,如下
1. C語言內聯匯編
首先看一下代碼
__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); } }
執行效果
0x19的十進制為25
2. C語言調用匯編函數
調用匯編函數,首先創建一個.s
匯編文件
創建完成後,在匯編文件中寫入一個匯編函數
AREA |.text|,CODE,READONLY EXPORT Get_Number Get_Number MOV R0,#761 BX LR ALIGN END
然後寫一個main
函數調用它
int Get_Number(void); int value; int main(void) { while(1) { value = Get_Number(); } }
查看執行效果
3. 匯編代碼調用C語言函數
在匯編文件中,輸入如下代碼
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; }
看一下執行效果吧
繼續向下執行
數字由100變成132;實現功能
解釋說明:
/* AREA 語法格式: AREA 段名 屬性1 ,屬性2 ,…… AREA偽指令用於定義一個代碼段或數據段。其中,段名若以數字開頭,則該段名需用“|”括起來,如:|1_test| 。 屬性字段表示該代碼段(或數據段)的相關屬性,多個屬性用逗號分隔。常用的屬性如下: — CODE 屬性:用於定義代碼段,默認為READONLY 。 — DATA 屬性:用於定義數據段,默認為READWRITE 。 — READONLY 屬性:指定本段為隻讀,代碼段默認為READONLY 。 — READWRITE 屬性:指定本段為可讀可寫,數據段的默認屬性為READWRITE 。 — ALIGN 屬性:使用方式為ALIGN表達式。在默認時,ELF(可執行連接文件)的代碼段和數據段是按字對齊的,表達式的取值范圍為0~31,相應的對齊方式為2表達式次方。 — COMMON 屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數據。各源文件中同名的COMMON段共享同一段存儲單元。 */ /* MOV 傳送指令 將右邊數據移入左邊寄存器 LDR 將右值地址存的數據移入左邊寄存器 BX 通用寄存器 裡面存入基地址、偏移量、臨時數據 BL 跳轉指令 LR r14 (1)當使用bl或者blx跳轉到子過程的時候,r14保存瞭返回地址,可以在調用過程結尾恢復 (2)異常中斷發生時,這個異常模式特定的物理R14被設置成該異常模式將要返回的地址 ENTRY 是程序入口偽指令。在一個完整的匯編程序中至少有一個 ENTRY,編譯程序在編譯連接時依據程序入口進行連接。 在隻有一個入口時,編譯程序會把這個入口的地址定義為系統復位後的程序起始點。但在一個源文件裡最多隻能有一個 ENTRY。 ENDP 表示PROC所定義的過程結束. (end procedure) ENDS 表示SEGMENT定義的段結束. (end segment) END 程序結束. */
使用BL
跳轉
BL指令同時還將PC寄存器的值保存到LR寄存器中,是帶返回的跳轉指令
所以
假設在一個匯編程序中,要調用兩個C語言函數
用事實證明可以返回
將匯編代碼修改為如下
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; }
查看代碼執行情況
首先進行第一個函數的執行,數字發生改變
接下來是第二個函數執行,數字發生改變
證明BL跳轉可以返回。
可以使用匯編加C語言的編程思路,打破一些限制
也為後面進行PC
的跳轉打下基礎
到此這篇關於C與匯編混合編程的實現示例的文章就介紹到這瞭,更多相關C與匯編混合編程 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- C語言如何與ARM匯編語言混合編程示例詳解
- C語言中調用匯編語言詳解
- 基於HLS創建Golang視頻流服務器的優缺點
- 匯編語言系列之匯編實現簡單數學運算
- 匯編語言系列之匯編實現各種碼制的轉換(思路詳解)