作者:黄工 公众号:strongerhuang 做底层软件开发的,或多或少都会接触一些汇编代码,今天就来说说关于汇编在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_inlinestaticinline#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++ 语句合法时出现。 三、更多举例下面举一些常见例子。 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} 举了这些常见例子,没有说透,但相信只要认真理解了都能明白。
新发声&强阵容|齐聚 IBM 企业数据合规治理研讨会
IDC报告前瞻:未来智能手表增幅 手环不容乐观
科创板安集科技董事陈大同介绍、履历信息
一个优秀的算法工程师必须具备哪些素质?
牛人DIY高精度六位半数字万用表(图文)
关于C中嵌套汇编代码难吗?
自动驾驶芯片,马斯克说“我们最强”
TomskSoft :价格实惠的专业网络开发机构
LED芯片新兴应用快速发展,LED封装市场寻找“新蓝海”
三大运营商严控成本费用,如何为用户创造更多价值
锂离子动力电池回收利用行业政策利好 梯次利用已形成试点效应
无人机技术的应用深入,保险业迎来新生力量
网络机顶盒怎么选?工程师分享2022网络机顶盒排行榜!
飞利浦进一步剥离家电业务 海尔、美的看好其全球品牌渠道
诺基亚8强势回归!10月19日上海发布,首发3999元起,这次不再为情怀买单
lg发布2017年旗舰产品lg G6和新款OLED电视
基于Rust开发的编程语言
服务器迁移数据时数据丢失的数据恢复案例
连拓精密科技LTM多通道气密性测试仪的优势有哪些?
三星Galaxy S8新配色:罗兰紫,靓得不行