C与汇编混合编程的实现示例

时间:2022-09-14 12:52:16

上一期中,使用链表的方式进行对不同任务的调用,实现的效果还是不错的,但是,任务在进行过程中不能进行来回的切换,必须要执行完,这是一个弊端,若不使用实时操作系统的情况下,如何切换呢,那就要说一下万能的汇编了,用汇编则可以做到任务的切换

首先我们知道,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);
	}
}

执行效果

C与汇编混合编程的实现示例

0x19的十进制为25

 

2. C语言调用汇编函数

调用汇编函数,首先创建一个.s汇编文件

C与汇编混合编程的实现示例

创建完成后,在汇编文件中写入一个汇编函数

				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();
	}
}

查看执行效果

C与汇编混合编程的实现示例

 

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

看一下执行效果吧

C与汇编混合编程的实现示例

C与汇编混合编程的实现示例

继续向下执行

C与汇编混合编程的实现示例

数字由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;
}

查看代码执行情况
首先进行第一个函数的执行,数字发生改变

C与汇编混合编程的实现示例

接下来是第二个函数执行,数字发生改变

C与汇编混合编程的实现示例

证明BL跳转可以返回。
可以使用汇编加C语言的编程思路,打破一些限制
也为后面进行PC的跳转打下基础

到此这篇关于C与汇编混合编程的实现示例的文章就介绍到这了,更多相关C与汇编混合编程 内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_44748127/article/details/118682219