历史上的今天
返回首页

历史上的今天

今天是:2025年01月21日(星期二)

正在发生

2021年01月21日 | 快速学Arm(11)--在C语言中内嵌汇编语言

2021-01-21 来源:eefocus

开发Arm程序的时候,大多数时候我们使用C/C++语言就可以了,但汇编语言在某些情况下能够实现一些C语言无法实现的功能,这时候就要调用一些汇编语言的程序.我们需要大概了解一下在C语言中如何嵌入汇编语言.


1.内嵌汇编语言的语法:


    __asm


    {


       指令[;指令]   


       ......


       [指令]


    }


2.举例:使能/禁止IRQ中断


    __inline void enable_IRQ(void)


    {


       int tmp;


       __asm                       //嵌入汇编代码


       {


           MRS tmp,CPSR           //读取CPSR的值


           BIC tmp,tmp,#0x80      //将IRQ中断禁止位I清零,即允许IRQ中断


           MSR CPSR_c,tmp         //设置CPSR的值


       }


    }


 


    __inline void disable_IRQ(void)


    {


       int tmp;


       __asm


       {


           MRS  tmp,CPSR


           ORR  tmp,tmp,#Ox80


           MSR  CPSR_c,tmp


       }


    }


3.举例:字符串复制


    void my-strcpy(const char *src,char *dst)


    {


       int ch;


       __asm


       {


       loop:


    #ifndef __thumb


       LDRB ch,[src],#1


       STRB ch,[dst],#1


    #else


       LDRB ch,[src]


       ADD  src,#1


       STRB ch,[dst]


       ADD  dst,#1


   #endif


       CMP ch,#0


       BNE loop


       }


    }


 


    int main(void)


    {


       const char *a="Hello world!";


       char b[20];


       __asm


       {


            MOV  R0,a


            MOV  R1,b


            BL my_strcpy,{R0,R1}


       }


       return(0);


    }


4.内嵌汇编的指令用法:

.操作书: 内嵌的汇编指令中作为操作数的寄存器和常量可以是C表达式.这些表达式可以是char,short或int等类型,而且这些表达式都是作为无符号数进行操作的.若要有符号数,用户需要自己处理与符号有关的操作.编译器将会计算这些表达式的值,并为其分配寄存器.


.物理寄存器:内嵌汇编中使用物理寄存器是有限制的:


       _ 不能直接向PC(程序计数器)寄存器中赋值,程序跳转只能通过B或BL指令来实现.


       _ 使用物理寄存器的指令中,不要使用过于复杂的C表达式


       _ 尽可能少的使用物理寄存器


.常量: 在内嵌汇编指令中,常量前面的"#"可以省略


.标号: C程序中的标号可以被内嵌的汇编指令使用.但是只有指令B可以使用C程序中的标号,而指令BL则不能使用.


.内存单元的分配:所有内存分配均由C编译器完成,分配的内存单元通过变量供内嵌汇编器使用.内嵌汇编器不支持内嵌汇编程序中用于内存分配的伪指令.


5.内嵌汇编注意事项:


.必须小心使用物理寄存器,如R0~R3,IP,LR,CPSR中的标志位,避免发生冲突.


    例如:


       __asm


       {


           MOV  R0,x


           ADD  y,R0,x/y


       }


       改成下面代码会比较妥当:


       __asm


       {


           MOV var,x


           ADD y,var,x/y


       }


.不要使用寄存器代替变量.


.使用内嵌汇编无需保存和恢复寄存器.事实上,除了CPSR,SPSR寄存器,对物理寄存器先读后写都会引起汇编报错.


.汇编语言中","号作为操作数分隔符.如果有C表达式作为操作数,若表达式中包含有",",则必须使用()将其规约为一个汇编操作数,例如:


   __asm

    {


       ADD x,y,(f(),z)   //"f(),z"为带有","的C表达式.


    }


6.不同数据类型对应的汇编指令:


    unsigned char   LDRB/STRB


    unsigned short   LDRH/STRH


    unsigned int    LDR/STR


   char            LDRSB/STRSB


   short           LDRSH/STRSH


7.访问C程序的变量:


   AREA   globals,CODE,READONLY


   EXPORT  asmsubroutine


   IMPORT  globalvar       ;声明的外部变量


asmsubroutine


   LDR  R1,=blobalval


   LDR  R0,[R1]


   ADD  R0,R0,#1


   STR  R0,[R1]


   MOV  PC,LR


    END


推荐阅读

史海拾趣

Chicago Miniature公司的发展小趣事

面对不断变化的市场环境和客户需求,CML始终保持创新精神。公司不断加大研发投入,推出了一系列具有创新性和竞争力的新产品。同时,CML还积极探索新的市场领域和商业模式,为公司的未来发展奠定了坚实基础。在未来,CML将继续致力于技术创新和品牌建设,努力成为全球微型照明领域的领军企业。

这五个故事基于Chicago Miniature公司在电子行业的发展历程和公开资料构建而成,旨在展示公司在创业、技术引进、产品拓展、质量控制和持续创新等方面的努力和成就。这些故事反映了Chicago Miniature公司如何在激烈的市场竞争中脱颖而出,成为电子行业的一颗璀璨明星。

Connect-Tech Products Corp公司的发展小趣事

Connect-Tech Products Corp公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和节能技术,减少生产过程中的环境污染。此外,公司还积极参与公益事业,为社会做出贡献。这些举措不仅提升了公司的社会形象,也为其赢得了社会各界的广泛赞誉和支持。

请注意,以上故事是基于电子行业和公司发展的一般模式虚构的,并不代表Connect-Tech Products Corp公司的实际发展历程。如需了解该公司的真实情况,建议查阅相关新闻报道、公司年报或行业分析报告等资料。

GMT(致新科技)公司的发展小趣事
在设置界面中,找到“定时开机”或类似的选项,并选中它。
Dialog公司的发展小趣事

Dialog公司在高能效系统电源管理领域积累了丰富的经验和知识,并形成了包括音频、短距离无线、AC/DC电源转换和VoIP技术在内的技术积累。这些技术积累为Dialog公司提供了强大的研发实力,使其能够迅速开发出面向各类个人便携式应用的集成电路(IC)。这些设备包括智能手机、平板电脑、超极本、数字无绳电话等。

Hi-Light Electronic Co Ltd公司的发展小趣事

近年来,Dialog公司通过一系列收购活动实现了快速扩张。例如,Dialog公司收购了Adesto公司,进一步拓展了工业物联网市场。这次收购为Dialog公司带来了一系列新的智能楼宇自动化工业解决方案,为其现有的制造自动化产品提供了非常好的补充。此外,收购Adesto还为Dialog公司带来了近5,000家客户公司,这些公司中大部分对Dialog公司来说是新客户。

Greenconn Corp公司的发展小趣事
避免将过多食物一次性放入冰箱,以减少冰箱电机的负荷。

问答坊 | AI 解惑

各种交换机的数据接口类型一览

作为局域网的主要连接设备,以太网交换机成为应用普及最快的网络设备之一,同时,也是随着这种快速的发展,交换机的功能不断增强,随之而来则是交换机端口的更新换代以及各种特殊设备连接端口不断的添加到交换机上,这也使得交换机的接口类型变得非 ...…

查看全部问答>

我是来找人才的,求各位帮忙啦?!!(表删除)

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 Job description: · Responsible for the creation, implementation and debugging of board level tests for Xbox accessories. · The test engineer must also be able to create d ...…

查看全部问答>

68013的GPIO口如何接收串行数据?

大家好,68013的GPIO口一般是用8个端口(如P0-P7)接收8位数据,或16个端口(如P0-P15)接收16位数据,也就是第一个端口接收一位数据,现在我有另一个GPIO接口,只有一条线,输出的数据是以b0,b1~b7,这样的顺序,输完一个字节,又接着输第二个字节. 请问怎样才 ...…

查看全部问答>

如何在evc下使用directDraw???

那位大侠做过evc下使用directDraw???有的话给我个例子,谢谢!!!!! zhangw0407@hotmail.com…

查看全部问答>

wince下计算两个日期差!

比如一个输入  2007-10-21   ,另一个输入   2008-11-12        如何计算这两个input的差值是多少秒 精确到秒 谢谢…

查看全部问答>

STM32的电机应用套件太贵了!

                                 STM32的电机应用套件太贵了!我本想买个学习一下,价格1万多,我退却了,因为TI的DSP电机开发板目前市场才3-4千,,说道 ...…

查看全部问答>

探讨下关于不等电位的MOS管驱动

如图,请大家一起他们探讨下关于这种不等电位的MOS管驱动有哪些办法,不用专门芯片,谢谢 …

查看全部问答>

TI的Zstack,如何剪裁。。。

只需要个开关灯的功能,怎么能编译小于128k啊。。。目前是150k。。。…

查看全部问答>

自行车测速、里程计图/程序

自行车测速、里程计图/程序…

查看全部问答>