0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言代码中调用汇编函数需要注意什么

单片机匠人 来源:单片机匠人 作者:蔡琰老师 2021-11-12 11:04 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

除了汇编语言工程和C语言工程,许多嵌入式工程既包含C语言又包含汇编语言。由于Keil MDK的默认启动代码是用汇编编写的,但是又是独立的一个启动代码是汇编实现,一般其他程序都是C语言实现。

我们一起来看下混合语言工程中,就比如在汇编程序中调用C函数,或者在C语言代码中调用汇编函数需要注意什么,稍不留意结果就可能是无法预测的。比如程序在一种版本的编译器下可以正常工作,而在另外的版本下,或者更换编译器后,工程可能会由于寄存器的使用冲突而停止工作。

1、在汇编中调用C函数

当在汇编文件中调用C函数的时候,需要注意一下方面:

①寄存器R0到R3、R12以及LR可能会被更改,如果这些寄存器中的数据之后还要使用,就需要将它们保存到栈上。

②SP的值应该是双字对齐的

③需要确保输入参数存储在正确的寄存器中(比如简单例子,使用R0~R3)

④返回值(假定为32位或更小)一般存在R0中

举个例子:如果有一个将四个值相加的函数:

int my_add(int x1,int x2,int x3,int x4)

{

return (x1+x2+x3+x4);

}

在Keil MDK中,可以使用以下的代码在汇编中调用C函数:

MOVS R0,#1 ;第一个参数(x1)

MOVS R1,#2 ;第二个参数(x2)

MOVS R2,#3 ;第三个参数(x3)

MOVS R3,#4 ;第四个参数(x4)

IMPORT my_add

BL my_add ;调用“my_add”函数,结果保存在R0中

如果汇编代码是按照C文件中的嵌入式汇编编写的,应该使用_CPP关键字代替IMPORT关键字来引入地址符号。

_CPP的用法如下:

上例程中:

IMPORT my_add

BL my_add ;调用“my_add”函数,结果保存在R0中

改为:

BL _CPP(my_add) ;调用“my_add”函数,结果保存在R0中

在Keil MDK中,_CPP关键字用于访问C或C++编译时的常量表达式,而对于其他工具链,情况可能就有所不同了。

2、在C代码中调用汇编函数

如果要从C代码中调用汇编函数,在实现汇编函数时,需要注意一下几点:

①若改变了寄存器R4到R11里的任何数值,需要将原始数值保存到栈中,并且在返回到C代码以前恢复原始值。

②若要在汇编函数中调用另一个函数,需要将LR的值保存在栈中,并且利用它执行返回操作。

③函数返回值一般存在R0中

举个例子:如果一个实现4个数相加的汇编函数:

EXPORT my_add

my_add FUNCTION

ADDS R0,R0,R1

ADDS R0,R0,R2

ADDS R0,R0,R3

BX LR ;返回值在R0中

ENDFUNC

在C代码中,需要将函数声明为:

extern int my_add(int x1,int x2,int x3,int x4);

int y;

……

y= my_add(1,2,3,4);//调用my_add函数

如果汇编代码需要访问C代码中的一些变量,也可以使用IMPORT关键字。

大多数情况下,可能只需要一到两个简单的汇编函数,所以就想将这些汇编代码嵌入C代码的文件中。多数开发工具都有一种被称作内联汇编的特性,而ARM工具链则采用了另外一种特性“嵌入汇编”。

通过嵌入汇编,我们可以在C文件中实现汇编函数。例如,将4个参数相加的函数可以如下写法:

_asm int my_add(int x1,int x2,int x3,int x4)

{

ADDS R0,R0,R1

ADDS R0,R0,R2

ADDS R0,R0,R3

BX LR ;返回值在R0中

}

可以在C代码中像普通C函数一样调用这个函数:

y = my_add(1,2,3,4);

嵌入汇编允许你在异常处理中定位栈帧,这也是嵌入汇编的一个优势。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144559
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66814

原文标题:C语言与汇编混合工程

文章出处:【微信号:gh_e7f294a514ca,微信公众号:单片机匠人】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C语言和单片机C语言有什么差异

    的目标代码短、运行速度高、存储空间小、符合C语言的ANSI标准,生成的代码遵循Intel目标文件格式,而且可与A51汇编语言PL/M51
    发表于 11-14 07:55

    控制流和函数调用的精细调整

    特性,避免不必要的计算。 函数调用涉及开销,因为它需要保存当前执行环境并跳转到新的执行环境。减少函数调用,尤其是在频繁执行的循环中,可以显著
    发表于 11-14 06:32

    RVMCU课堂「7」: 手把手教你玩转RVSTAR—汇编程序篇

    汇编程序而言,在汇编程序调用C/C++语言
    发表于 10-31 08:46

    通过内联汇编调用乘法指令mulh\\mulhsu\\mulhu

    mulh、mulhu与mulhsu指令,不能直接验证,需要其他方法。因此,我们想到了在C语言中嵌入内联汇编,分别生成三条指令的接口函数,之后
    发表于 10-24 06:52

    GCC编译器,怎么才能实现c文件未被调用函数,不会被编译呢?

    GCC编译器,怎么才能实现c文件未被调用函数,不会被编译?有什么编译选项可以设置吗? 移植代码,有些
    发表于 09-28 12:25

    【上海晶珩睿莓1开发板试用体验】将TensorFlow-Lite物体归类(classify)的输出图片移植到LVGL9.3界面

    既然调通了TensorFlow-Lite物体归类(classify)和LVGL9.3代码,那么把这两个东西结合起来也是没问题的,需要注意的是,TensorFlow-Lite是C++代码
    发表于 09-21 00:39

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数main函数
    的头像 发表于 07-25 15:34 1654次阅读

    C语言中的内联函数与宏

    C编程,内联函数和宏都用于避免函数调用的开销并编写可复用的逻辑部分,但它们在工作方式和安全性方面存在显著差异。
    的头像 发表于 07-25 15:10 1706次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中的内联<b class='flag-5'>函数</b>与宏

    深入理解C语言函数—编程的“积木块”艺术

    在编程的世界里,函数就像建筑的“积木块”——它们是构建复杂程序的基石。通过灵活组合这些模块,开发者能打造出功能强大且结构清晰的代码函数之所以成为
    的头像 发表于 06-30 17:26 1480次阅读
    深入理解<b class='flag-5'>C</b><b class='flag-5'>语言</b>:<b class='flag-5'>函数</b>—编程<b class='flag-5'>中</b>的“积木块”艺术

    稳压器在安装接线前需要注意哪些

    稳压器是一种非常重要的电气设备,它可以有效地解决电压不稳定、波动过大等问题,保证设备的正常运行,然而,稳压器接线并非简单地将线接好就行,而是需要注意一些事项,以确保其能够安全、有效地发挥应有的作用,下面小编来说说稳压器在安装接线前需要注意哪些。
    的头像 发表于 04-03 15:20 651次阅读
    稳压器在安装接线前<b class='flag-5'>需要注意</b>哪些

    分析C语言代码结构的设计问题

    来分析一个C语言代码结构的设计问题。 这段代码,使用了两次malloc,分别给 p1 和 p2 申请了内存。用完后,内存释放,防止内存泄漏。 大家觉得,这样的
    的头像 发表于 02-11 09:31 658次阅读

    速度探头在使用过程需要注意哪些问题呢

    速度探头在使用过程需要注意安装与维护、参数设置与校准、使用注意事项以及安全注意事项等多个方面。只有做好这些工作,才能确保探头的正常工作、测量精度和安全性。
    的头像 发表于 02-06 15:11 761次阅读

    C语言如何处理函数的返回值

    当你在函数的最后写上 return 0 的时候,它是如何返回给调用函数的? 比如 test 函数,为了待会更好的看懂汇编
    的头像 发表于 01-16 09:21 747次阅读

    EE-128:C语言中的DSP:从C调用汇编类成员函数

    电子发烧友网站提供《EE-128:C语言中的DSP:从C调用汇编类成员函数.pdf》资料免费下载
    发表于 01-07 13:48 0次下载
    EE-128:<b class='flag-5'>C</b><b class='flag-5'>语言</b>中的DSP:从<b class='flag-5'>C</b><b class='flag-5'>调用汇编</b>类成员<b class='flag-5'>函数</b>

    AKI跨语言调用库神助攻C/C++代码迁移至HarmonyOS NEXT

    /C++代码快速迁移至HarmonyOS NEXT。凭借卓越的兼容性,AKI已成为厂商与开发者打造鸿蒙原生应用过程中广泛使用的跨语言调用解决方案。 AKI是一款专为鸿蒙原生开发设计的
    发表于 01-02 17:08