单片机开发或多或少都会接触一些汇编代码,今天就来说说关于汇编在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中嵌套汇编代码
常见的两种定义: • 在c函数中定义一段汇编代码 • 在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}
基于骁龙820A,纵目将与高通在CES联合展示ADAS原型产品
利用NI平台构建面向5G无线通信技术的Mini Massive MIMO原型验证系统
工程师制作:耳机放大器制作历程全解
荣耀V9怎么样?荣耀V9评测:华为荣耀V9外观、配置、拍照汇总,价格3000值得购买
收藏!2023年全球智能传感器技术市场现状及竞争格局分析(技术专利)
单片机C代码嵌套汇编案例
物联网网关设备在环境监测中应用实现对环境状况的全方位监测和管理
一种「个性化」的文本到图像扩散模型 DreamBooth
基于CAN总线的旋转编码器采集模块设计
增益大于1的正反馈很难稳定存在?
未来5G用户拿着联通的号,用着电信的网,靠移动基站实现漫游
Apple Watch Series 3将大变:表盘变方,或将加入检测血糖功能
基于MC33937A混合和电动汽车逆变器参考设计
怎么样才能设置电脑C盘禁止安装任何软件
iPhone8什么时候上市?iPhone8最新消息:iPhone8功能、iPhone8价格,集精华于一身最强创新与突破
华为正在申请注册盘古大模型商标
Littelfuse扩展高温TRIAC晶闸管系列以帮助设计师改善热管理
摩托罗拉手机充电器
【技术分享】如何提高多路热电偶测量的通道一致性
机器人需求拐点已经来临 2020年工业机器人有望迎来复苏