单片机开发或多或少都会接触一些汇编代码,今天就来说说关于汇编在c中的定义和调用,以及举例说明嵌套汇编代码。
概述
有认真研究,或者说细心一点的读者应该都知道:c中定义汇编代码与编译器有关。
比如:你在core_cm4.h文件会看到如下的代码:
#if defined ( __cc_arm ) #define __asm __asm /*!< asm keyword for arm compiler */ #define __inline __inline /*!< inline keyword for arm compiler */ #define __static_inline static __inline#elif defined ( __gnuc__ ) #define __asm __asm /*!< asm keyword for gnu compiler */ #define __inline inline /*!< inline keyword for gnu compiler */ #define __static_inline static inline#elif defined ( __iccarm__ ) #define __asm __asm /*!< asm keyword for iar compiler */ #define __inline inline /*!< inline keyword for iar compiler. only available in high optimization mode! */ #define __static_inline static inline#elif defined ( __tms470__ ) #define __asm __asm /*!< asm keyword for ti ccs compiler */ #define __static_inline static inline#elif defined ( __tasking__ ) #define __asm __asm /*!< asm keyword for tasking compiler */ #define __inline inline /*!< inline keyword for tasking compiler */ #define __static_inline static inline#elif defined ( __csmc__ ) #define __packed #define __asm _asm /*!< asm keyword for cosmic compiler */ #define __inline inline /*use -pc99 on compile line !< inline keyword for cosmic compiler */ #define __static_inline static inline#endif
如果你写过keil c51,你还会发现有如下(通过预处理)嵌套汇编:
#pragma asm; assembler code here#pragma endasm 所以,你会发现,不同的编译器,汇编代码还是有差异。当然,这里主要是说c中嵌套汇编与编译器有关。
c中嵌套汇编代码
常见两种定义:
1.在c函数中定义一段汇编代码;
2.在c文件中定义一个汇编函数;
(当然,两个意思差不多,都是在c中嵌套汇编)
上面说了c中定义汇编代码与编译器有关,换句话说:不同编译器解析汇编代码的方式不同。
这里还是拿core_cm3.c来举例说明,定义一个__get_psp函数。
在keil mdk中定义:
__asm uint32_t __get_psp(void){ mrs r0, psp bx lr} 在iar ewarm中定义:
uint32_t __get_psp(void){ __asm(mrs r0, psp); __asm(bx lr);} __asm(__asm)关键字用于调用内联汇编程序,并且可在 c 或 c++ 语句合法时出现。
看到这里,推荐阅读我分享的一篇文章:单片机用汇编和c语言点灯程序的区别
举例
下面举一些常见例子。
1.freertos中portmacro.h文件下源代码:
static portforce_inline void vportraisebasepri( void ){uint32_t ulnewbasepri = configmax_syscall_interrupt_priority; __asm { /* set basepri to the max syscall priority to effect a critical section. */ msr basepri, ulnewbasepri dsb isb }} 2.freertos中port.c文件下源代码:
__asm void xportpendsvhandler( void ){ extern uxcriticalnesting; extern pxcurrenttcb; extern vtaskswitchcontext; preserve8 mrs r0, psp isb ldr r3, =pxcurrenttcb /* get the location of the current tcb. */ ldr r2, [r3] stmdb r0!, {r4-r11} /* save the remaining registers. */ str r0, [r2] /* save the new top of stack into the first member of the tcb. */ stmdb sp!, {r3, r14} mov r0, #configmax_syscall_interrupt_priority msr basepri, r0 dsb isb bl vtaskswitchcontext mov r0, #0 msr basepri, r0 ldmia sp!, {r3, r14} ldr r1, [r3] ldr r0, [r1] /* the first item in pxcurrenttcb is the task top of stack. */ ldmia r0!, {r4-r11} /* pop the registers and the critical nesting count. */ msr psp, r0 isb bx r14 nop} 3.内核复位
这是之前分享过的一篇文章《stm32复位来源》中的代码:
__asm void nvic_corereset_a(void){ ldr r0, =0xe000ed0c ldr r1, =0x05fa0001 str r1, [r0]deadloop_core b deadloop_core} 举了这些常见例子,没有说透,但相信只要认真理解了都能明白。
来源:微信公众号 | 嵌入式专栏
作者 | strongerhuang
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理
英国首个“机器人”中餐馆被迫歇业 或因缺乏缺乏相关资质许可
健身房中的智能镜面显示屏将提供科技健身的新体验
AI时代,如何赋能员工实现智慧协同?
Imagination为联网的设备提供安全保障
传感器的类型有哪些
单片机C代码嵌套汇编的一些方法
超声波色度延迟线应用电路
MPS|汽车USB Type-A/Type-C充电控制器全集成方案
汽车悬挂系统,汽车悬挂系统结构原理是什么?
DIMM DRAM 168线内存条引脚定义
区块链式共享与互联网共享究竟有何不同
MediaTek Wi-Fi 6E芯片组入选Wi-Fi联盟的Wi-Fi 6E测试平台
小米5跟5s有什么区别?关于性能提升多少的分析
中科院微系统所与携手爱发科集团共同创立“先进存储器技术联合实验室”
谷歌利用AI来监测和及时发布洪水警报,帮助人们做好抗洪工作
华为三款新机:荣耀note9,华为mate10,荣耀magic2,你最期待谁的上市?
华为斥巨资在英建芯片厂
小鹏召回部分汽车更换其逆变器
医疗AI不断进步,如何监管成难题
5G时代,5G俨然成了手机厂商的“面子”