C语言和汇编语言混合编程

ATPCS

ATPCS的全称是ARM-Thumb Procedure Call Standard,其核心内容就是定义了ARM子程序调用的基本规则及堆栈的使用约定等。如ATPCS规定了ARM程序要使用满递减堆栈,入栈/出栈操作要使用STMFD/LDMFD指令,只要所有的程序都遵循这个约定,ARM程序的格式也就统一了,我们编写的ARM程序也就可以在各种各样的ARM处理器上运行了。ATPCS最重要的内容是定义了子程序调用的具体规则,无论是程序员编写程序,还是编译器开发商开发编译器工具,一般都要遵守它。规则的主要内容如下。

  • 子程序间要通过寄存器R0~R3(可记作a0~a3)传递参数,当参数个数大于4时,剩余的参数使用堆栈来传递。
  • 子程序通过R0~R1返回结果。 子程序中使用R4~R11(可记作v1~v8)来保存局部变量。
  • R12作为调用过程中的临时寄存器,一般用来保存函数的栈帧基址,记作FP。
  • R13作为堆栈指针寄存器,一般记作SP。
  • R14作为链接寄存器,用来保存函数调用者的返回地址,记作LR。
  • R15作为程序计数器,总是指向当前正在运行的指令,记作PC。

在ARM平台下,无论是C程序,还是汇编程序,只要大家遵守ARM子程序之间的参数传递和调用规则,就可以很方便地在一个C程序中调用汇编子程序,或者在一个汇编程序中调用C程序。
以下图为例,
在一个C源文件main.c中定义了main()函数和sum()函数
在一个汇编源文件SUM.S中定义了一个汇编子程序SUM_ASM
在main()函数中,直接调用了汇编子程序SUM_ASM,而在SUM_ASM的汇编代码实现中,又调用了在C源文件中定义的sum()函数。使用交叉编译器arm-linux-gcc编译这两个源文件,编译没有任何问题,可以在ARM平台上正常运行。
C和汇编相互调用
为了能在C程序中内嵌汇编代码,ARM编译器在ANSI C标准的基础上扩展了一个关键字__asm。通过这个关键字,我们就可以在C程序中内嵌ARM汇编代码。在C程序中内嵌汇编代码的格式如下。
_asm
{
指令
}
这里有个细节需要注意一下,如果你想在内嵌的汇编代码中添加注释,记得要使用C语言的/**/注释符,而不是汇编语言的分号注释符。接下来我们就通过一个数据块复制的例子,给大家演示一下在C程序中内嵌汇编代码的方法
C中内嵌汇编代码
为了能在C程序中内嵌汇编代码,不同的编译器基于ANSI C标准扩展了不同的关键字,使用的汇编格式可能也不太一样。如GNU ARM编译器提供了一个_asm_关键字,它的使用方法如下。

_asm_ _volatile_
{
     指令
}

在汇编程序中调用C程序

在C程序中可以内嵌汇编代码,在汇编程序中同样也可以调用C程序。在调用的时候,我们要注意根据ATPCS规则来完成参数的传递,并配置好C程序传递参数和保存局部变量所依赖的堆栈环境,然后使用BL指令直接跳转即可。
汇编程序中调用C程序

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值