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!

推薦閱讀: