FreeRTOS内核学习记录(一)-在ARM GCC中定义汇编函数

        在keil中,汇编函数可以使用如下的方式来定义一个汇编函数

__asm void SVC_Handler(void)
{
	extern CurrentTask;
	PRESERVE8
	ldr r3, =CurrentTask
	ldr r1, [r3]
	ldr r0, [r1]
	ldmia r0!, {r4-r11}
	msr psp,r0
	isb
	mov r0,#0
	msr basepri,r0
	orr r14,#0xd
	bx r14
}

        这个函数在ARMCC中编译的时候是不会报错的,但是在使用ARM GCC的时候,这种定义方式会报出类似如下的错误:

../project/src/cx_task.c:54:9: error: stray '#' in program
   54 |  mov r0,#0

        也就是这些符号编译器无法识别,__asm void func(void)中的__asm也无法识别。我们参照cmsis_gcc.h中操作PSP指针的一个函数来看看在GNU里面要如何进行操作。

#define __STATIC_FORCEINLINE  __attribute__((always_inline)) static inline
__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
{
  __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
}

        可以看到在这里使用的是内联汇编的形式,__ASM 其实就是asm,是一个宏,asm内联汇编的用法是这样的:

asm(
"asm1\n"
"asm2\n");

或者就是像cmsis_gcc.h这样子用:隔开每一个asm字符串。

        那么这里要清楚一个就是问什么我们的汇编函数需要加上__asm在函数定义开头。这里就要区分我们一般的普通函数在编译的时候是会有标准的压栈lr的过程,但是对于我们这种不存在层级调用的函数而言这么做会浪费数个周期的时间,因此需要把函数设置为裸函数或者内联函数,方式有两种:

// Methon1:
__attribute__((always_inline)) void func(void){
    // function code
}
// Methon2:
void func(void) __attribute__((naked));
void func(void)
{
    //function code
}

        在Keil的汇编函数中还可以使用汇编伪指令,比如"PRESERVE8"对齐控制指令,这个显然在GCC中也是无法识别的,为了达到同样的效果,可以在上述的两个属性中加入aligned(8)来实现。如:

// Methon1:
__attribute__((always_inline,aligned(8))) void func(void){
    // function code
}
// Methon2:
void func(void) __attribute__((naked, aligned(8)));
void func(void)
{
    //function code
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值