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

}



相关文章
|
1天前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
1天前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
|
1天前
|
编译器
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
【ARM汇编速成】零基础入门汇编语言之基本认识(一)
|
2月前
|
程序员 编译器 数据处理
汇编高手秘籍:解锁性能优化新境界,用汇编语言让你的程序飞起来!
【8月更文挑战第31天】汇编语言作为编程基石,其高效性能备受推崇。尽管现代软件开发更偏爱高级语言,但在性能要求极高的场景下,汇编优化仍不可或缺。本文通过示例代码介绍四种优化技巧:循环展开、寄存器分配、指令重排及SIMD指令使用,显著提升执行效率。同时强调分析性能瓶颈、测试优化效果及保持代码可读性的重要性,助力开发者在关键代码路径上实现性能突破。
60 0
|
2月前
51单片机汇编语言点亮一位数码管,并计时(超详细分析汇编语言)
51单片机汇编语言点亮一位数码管,并计时(超详细分析汇编语言)
|
5月前
|
数据处理 编译器 数据库
x64 和 arm64 处理器架构的区别
x64 和 arm64 处理器架构的区别
|
1天前
|
存储 Docker 容器
ARM架构鲲鹏主机BClinux离线安装docker步骤
下载并安装适用于ARM架构的Docker CE二进制文件,解压后移动至/usr/bin目录。创建docker组,配置systemd服务脚本(docker.service、docker.socket、containerd.service),重载systemd配置,启动并启用docker服务。编辑daemon.json配置存储驱动、镜像加速地址等,最后拉取所需镜像。
6 0
|
6天前
|
NoSQL MongoDB Docker
求助,有没有大神可以找到arm64架构下mongodb的3.6.8版本的docker镜像?
在Docker Hub受限的情况下,寻求适用于ARM架构的docker镜像资源或拉取链接,以便在x86架构上获取;内网中的机器为ARM架构,因此优先请求适合ARM的Docker镜像或Dockerfile,非常感激您的帮助。
|
2月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
|
1月前
ARM64架构提供的Cache操作
ARM64架构提供的Cache操作