• Cortex-M3中C与汇编的交互


          以下内容摘自《ARM Cortex-M3权威指南》

          概览

          在CM3 上编程,既可以使用C 也可以使用汇编。可能还有其它语言的编译器,但是大多数人还是会在C 与汇编的世界里游弋。C 与汇编都有尺短寸长,不能互相取代。使用C 能开发大型程序,而汇编则用于执行特种任务。

          什么时候使用汇编? 

          如果工程比较小,使用纯汇编常常是可行的,而且你能随心欲地优化和控制程序。不过,你的开发周期会变长。尤其是当工程变大,需要处理比较复杂的数据结构,以及要管理函数库时,你将发现汇编会使工作量激增。各种地址和间接引用千头万绪;bug 劈头盖脸;甚至好几天都改不完,简直就是自虐。当然,如果你想成为系统开发的大虾,就必须以“我不下地狱谁下地狱”的决心,去勇敢面对,后天下乐而乐。

          不论如何,时间宝贵。我们应该以C 来实现程序的大框架,而本着好钢用在刀刃上的原则来使用汇编,因为只有在不多的特殊场合是非使用汇编语言不可的,它们是:

          无法用 C 写成的函数,如操作特殊功能寄存器,以及实施互斥访问。
          在危急关头执行处理的子程(如,NMI 服务例程)。
          存储器极度受限,只有使用汇编才可能把程序或数据挤进去。
          执行频率非常高的子程,如操作系统的调度程序。
          与处理器体系结构相关的子程,如上下文切换。
          对性能要求极高的应用,如防空炮的火控系统

          C中如何嵌入汇编?

          尽管在使用了C后,大大加速了开发,但是底层的系统控制往往还需要汇编代码。很多编译器都允许你直接在C代码中插汇编,称为“内联汇编”;另外还允许你写独立的汇编模块,与编译后的C模块一起连接。以往,使用内联汇编的作法比较多,但是在ARM编译器中,不支持对Thumb‐2指令的内联汇编。取而代之的,是从RealView C编译器的3.0版开始,新增了所谓“嵌入式汇编”的功能,它支持Thumb‐2指令。它让你可以在C程序中插入使用汇编语言编写的函数,例如:

    __asm void SetFaultMask(unsigned int new_value)
    {
    //在这里使用汇编代码实现本函数
    MSR FAULTMASK, new_value // 把new_value写入FAULTMASK中
    BX LR // 返回主程序(不可省略)
    }

          RealView C 编译器对嵌入式汇编的详细论述,在《RVCT 3.0 Compiler and Library Guide(Ref6)》中给出。

          汇编与C 的接口

          在很多情况下,都需要让C 程序模块与汇编程序模块互相交互,它们包括:
          在 C 代码中使用了嵌入式汇编(或者是在GNU 工具下,使用了内联汇编)
          C 程序呼叫了汇编程序,这些汇编程序是在独立的汇编源文件中实现的
          汇编程序调用了C程序

          在这些情况下,必须知晓参数是如何传递的,以及值是如何返回的,才能在主调函数与子程序之间协同工作。这些交互的机制在ARM中有明确的规定,由文档《ARM Architecture Procedure Call Standard(AAPCS, Ref5)》给出。

          不过,在大多数场合下的情况都比较简单:当主调函数需要传递参数(实参)时,它们使用R0‐R3。其中R0传递第一个,R1传递第2个……在返回时,把返回值写到R0中。在子程序中,可以随心所欲地使用R0‐R3,以及R12(回顾第9章,想想为什么会PUSH它们)。但若使用R4‐R11,则必须在使用之前先PUSH它们,使用后POP回来。

          可见,汇编程序使用R0‐R3, R12时会很舒服。但是如果换个立场——汇编要呼叫C函数,则考虑问题的方式就有所不同:必须意识到子程序可以随心所欲地改写R0‐R3, R12,却决不会改变R4‐R11。因此,如果在调用后还需要使用R0‐R3,R12,则在调用之前,必须先PUSH,从C函数返回后再POP它们,对R4‐R11则不用操心。在本章的示例程序中,绝大多数只是调用汇编子程序,它们只影响少量寄存器,或者会在返回前恢复寄存器的内容,所以往往没有严格遵守AAPCS。这主要是为了突出其它重点,简化程序,请读者不要钻牛角尖。

  • 相关阅读:
    初识数据库
    局域网和广域网
    面试题汇总
    SSO单点登录解决方案
    接口加密问题
    幂等性问题
    消息队列的消费失败、重复消费问题
    Redis集群搭建
    HashCode详解
    HashMap的底层原理
  • 原文地址:https://www.cnblogs.com/outs/p/5394879.html
Copyright © 2020-2023  润新知