【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)

简介: 【ARM汇编速成】零基础入门汇编语言之C与汇编混合编程(四)

四.C语言与汇编混合编程

1.混合编程前置条件

ATPCS规则(ARM-Thumb Procedure Call Standard),即定义了子程序调用的具体规则:

ARM 程序要使用满递减堆栈, 入栈/出栈操作要使用STMFD/LDMFD指令

子程序间要通过寄存器R0~R3(可记作a0~a3)传递参数,当参数个数大于4时,剩余的参数使用堆栈来传递

子程序通过R0~R1返回结果

子程序中使用R4~R11(可记作v1~v8)来保存局部变量

R12作为调用过程中的临时寄存器,一般用来保存函数的栈帧基址,记作FP

R13作为堆栈指针寄存器,记作SP

R14作为链接寄存器,用来保存函数调用者的返回地址,记作LR

R15作为程序计数器,总是指向当前正在运行的指令,记作PC

2.混合编程优势

  • 性能优化:对于某些对性能要求极高的代码部分,使用汇编语言可以手动优化指令序列,提高执行效率。
  • 硬件操作:某些硬件操作(如设置特定的CPU寄存器)只能通过汇编语言实现。
  • 兼容性:在C语言标准中未定义的操作或旧硬件的特定功能可能需要汇编语言来实现。

3.混合编程的实现

3.1在C程序中内嵌汇编代码


       通过ARM编译器在ANSI C标准的基础上扩展的关键字__asm,我们就可以在C程序中内嵌ARM汇编代码。(在内嵌的汇编代码中添加注释,要使用C语言的/**/注释符,而不是汇编语言的分号注释符。)


       不同的编译器基于ANSI C标准扩展了不同的关键字,使用的汇编格式可能不太一样。如GNU ARM编译器提供了一个__asm__关键字,__asm__的后面还可以选择使用__volatile__关键字修饰,用来告诉编译器不要优化这段代码。


__asm

{

指令  /*注释*/

...

[指令]

}


__asm__ __volatile__

{

 "汇编语句;"

 ...

 "汇编语句;"

}

具体步骤:



编写汇编代码:首先,你需要编写汇编代码片段,通常这些代码片段是独立的功能模块。


声明外部函数:在C语言中,使用 extern 关键字声明汇编函数,这样C编译器知道这些函数在其他地方定义。


extern void assembly_function();

汇编代码中的函数标签:在汇编代码中,使用特定的标签来标识可以被C代码调用的函数。


; 假设使用的是ARM汇编

.global assembly_function

assembly_function:

   ; 汇编指令

   BX lr

调用汇编函数:在C代码中,像调用普通C函数一样调用汇编函数。


int main() {

   assembly_function();

   return 0;

}

实例:

#include <stdio.h>

 

int main() {

   int a = 10;

   int b = 20;

   int result;

 

   // 使用GCC的内嵌汇编语法

   __asm__ (

       "addl %%ebx, %%eax;" // 将ebx寄存器的值加到eax寄存器上

       : "=a" (result)      // 输出操作,将eax寄存器的值存储到result变量中

       : "a" (a), "b" (b)   // 输入操作,将变量a的值加载到eax寄存器,将变量b的值加载到ebx寄存器

   );

 

   printf("The result is: %d\n", result);

   return 0;

}

3.2在汇编中调用C程序


//汇编文件

IMPORT sum

AREA SUM_ASM,CODE,READONLY

EXPORT SUM_ASM

SUM_ASM

MOV RO, 0X0   ;arg1-->R0

MOV R1, 0X1   ;arg2-->R1

MOV R2, 0X2   ;arg3-->R2

MOV R3, 0X3   ;arg4-->R3


MOV R4, 0X5   ;arg6-->SP,注意这里不是第五个参数,因为栈的特点是先进后出

STR R4, [SP, #-4]

MOV R4, 0X4   ;arg5-->SP

STR R4, [SP, #-4]

BL sum

MOV PC,LR

END

//C文件

int sum(intb,intc,int c,int d,int d,int f)

{

int result=0;

printf("result=%d\n", result);

return result;

}

int main(void)

{

SUM_ASM();

return 0;

}



相关文章
|
2月前
|
编译器
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
|
2月前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
2月前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
177 0
|
4月前
|
程序员 编译器 数据处理
汇编高手秘籍:解锁性能优化新境界,用汇编语言让你的程序飞起来!
【8月更文挑战第31天】汇编语言作为编程基石,其高效性能备受推崇。尽管现代软件开发更偏爱高级语言,但在性能要求极高的场景下,汇编优化仍不可或缺。本文通过示例代码介绍四种优化技巧:循环展开、寄存器分配、指令重排及SIMD指令使用,显著提升执行效率。同时强调分析性能瓶颈、测试优化效果及保持代码可读性的重要性,助力开发者在关键代码路径上实现性能突破。
99 0
|
4月前
51单片机汇编语言点亮一位数码管,并计时(超详细分析汇编语言)
51单片机汇编语言点亮一位数码管,并计时(超详细分析汇编语言)
172 0
|
7月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
239 2
|
7月前
|
存储 机器学习/深度学习 移动开发
汇编语言指令系列
汇编语言指令系列
749 0
几组汇编指令的比较
几组汇编指令的比较
|
5月前
|
存储 机器学习/深度学习 芯片
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
|
5月前
|
存储 算法 安全
深入理解汇编语言:基础语法和常用指令介绍
深入理解汇编语言:基础语法和常用指令介绍