“svc”是否有任何gcc编译器原语?

pcrecxhr  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(274)

我正在编写一个在Cortex-m3上运行的程序。
首先我写了一个汇编文件来执行“svc”。

svc:
    svc 0
    bx lr

我决定使用gcc的内联asm,所以我将其编写如下,但是svc函数没有内联。

__attribute__((naked))
int svc(int no, ...)
{
    (void)no;
    asm("svc 0\n\tbx lr");
}

int f() {
    return svc(0,1,2);
}

------------------ generated assembly ------------------
svc:
    svc 0
    bx lr
f:
    mov     r0, #0
    mov     r1, #1
    mov     r2, #2
    b       svc

我猜它不是内联的,因为它是naked,所以我删除了naked属性,并这样写。

int svc(int __no, ...)
{
    register int no asm("r0") = __no;
    register int ret asm("r0");
    asm("svc 0" : "=r"(ret) : "r"(no));
    return ret;
}

------------------ generated assembly ------------------
svc:
    stmfd   sp!, {r0, r1, r2, r3}
    ldr     r0, [sp]
    add     sp, sp, #16
    svc 0
    bx      lr
f:
    mov     r0, #0 // missing instructions setting r1 and r2
    svc 0
    bx      lr

虽然我不知道为什么gcc增加了一些不必要的栈操作,但是svc是好的。问题是svc没有正确内联,变量参数被丢弃了。
gcc中是否有svc原语?如果gcc中没有,如何编写正确的原语?

o2rvlv0m

o2rvlv0m1#

请看一下core_cmFunc.h中使用的语法,该语法是作为Cortex-M系列ARM CMSIS的一部分提供的。下面是一个向优先级掩码寄存器写入值的示例:

__attribute__ ((always_inline)) static inline void __set_PRIMASK(uint32_t priMask)
{
  __ASM volatile ("MSR primask, %0"::"r" (priMask));
}

但是,创建这样的 * varadic * 函数听起来很困难。

kwvwclae

kwvwclae2#

您可以使用如下所示的宏。

#define __svc(sNum) __asm volatile("SVC %0" ::"M" (sNum))

并像使用任何编译器基元函数__svc(2);一样使用它。
因为它只是一个宏,所以它只会生成所提供的指令。

相关问题