【问题标题】:How to create inline assembly functions in C?如何在 C 中创建内联汇编函数?
【发布时间】:2026-01-29 03:50:01
【问题描述】:

我正在使用 MSP 432 并且必须在 C 中创建汇编函数。我尝试使用 __asm void PendSV_Handler{} 创建函数。但这不起作用,并说 Expected an Identifier.

另外,我正在尝试运行这个汇编命令cpsid i,但它说CPSID 未定义但CPSIE i 有效。在这一点上我有点困惑。我对此很陌生,我仍在学习。

下面是我正在尝试组装的代码。我尝试通过 __asm void PendSV_handler 来制作函数集。

我不确定创建一个 asm 是否更容易。包含这些说明的文件。

OSThread *volatile OS_curr;
OSThread *volatile OS_next;

void PendSV_Handler(void){


__asm__("cpsid      i"

//if(OS_curr != (OSThread *)0)
        "ldr        r0, =OS_curr"
        "ldr        r0, [r0]"
        "cbz        r0, PendSV_restore");

// Push r4  - r11
__asm__("PUSH {r4-r11}"

        "ldr        r1, =OS_curr"
        "ldr        r1, [r1]"

// OS_curr -> sp = sp;
        "str         sp, [r1]");

PendSV_restore

// sp=OS_next -> sp;
        __asm__("ldr r0, =OS_next;"
                "ldr        r0, [r0]"
                "ldr        r0, [r0]"
                "str        sp, [r13]");

// OS_curr = OS_next;
        __asm__("ldr        r0, =OS_next"
                "ldr        r1, [pc, 0xc]"
                "ldr        r0, =OS_curr"
                "str        r0, [r1]"

//Pop  r4-r11
                "POP        {r4-r11}"

//            __enable_interrupts();
                "cpsie      i"

//return to next thread
                "bx         r14");

}

【问题讨论】:

  • 是什么让您认为CPSIE i 有效?它更有可能在第一个错误后停止解析吗?您的PendSV_restore 标签缺少其:,因此解析器显然已放弃,或者这不是您正在构建的代码。
  • 这是我第一次真正深入研究组装。我从反汇编程序中得到了这个,但是当我把它带入 c 文件时,它充满了错误。

标签: embedded rtos msp432


【解决方案1】:

内联汇编语法在 C 编程语言中没有重新定义,它的支持和语法是特定于编译器的。在 GCC 中:

void PendSV_Handler(void) 
{
    __asm__("cpsid      i");

//if(OS_curr != (OSThread *)0)
    __asm__("ldr        r0, =OS_curr");
    __asm__("ldr        r0, [r0]");
    __asm__("cbz        r0, PendSV_restore");

// Push r4  - r11
    __asm__("PUSH {r4-r11}");

    __asm__("ldr        r1, =OS_curr");
    __asm__("ldr        r1, [r1]");

// OS_curr -> sp = sp;
    __asm__("str         sp, [r1]");

PendSV_restore:

// sp=OS_next -> sp;
    __asm__("ldr r0, =OS_next;");
    __asm__("ldr        r0, [r0]");
    __asm__("ldr        r0, [r0]");
    __asm__("str        sp, [r13]");

// OS_curr = OS_next;
    __asm__("ldr        r0, =OS_next");
    __asm__("ldr        r1, [pc, 0xc]");
    __asm__("ldr        r0, =OS_curr");
    __asm__("str        r0, [r1]");

//Pop  r4-r11
    __asm__("POP        {r4-r11}");

//            __enable_interrupts();
    __asm__("cpsie      i");

//return to next thread
    __asm__("bx         r14");
}

【讨论】:

  • 我能够修复 CPSID 问题。我面临 OS_curr 和 OS_next 的另一个问题。我想使用这些并将它们加载到寄存器中,但是这样做时会遇到很多错误。错误:表达式中的错误术语、非法符号、意外的尾随操作数。我一直在环顾四周,但没有找到任何可以解决此问题的方法。
  • @Mperez 你修好了吗?你做了什么?如果你照我说的做,那我想我修好了。如果您有其他问题,则需要发布另一个问题。我不是专家,我google了一下。 t.b.h through 看起来像是 X-Y 问题。
【解决方案2】:

参考

C 编程语言中没有重新定义内联汇编语法

我过去曾为大学项目做过

inline void function(param1,param2)
{
   asm volatile ("param1");
   asm volatile ("param2");
}

但是,如果你在 ARM 上工作,请查看指令集以了解可能的哪些命令

例如: 如果你想写一些时间紧迫的东西,需要按照书面顺序你可以做这样的事情

inline void COLOUR_GLCD_write_address_data(uint8_t address, uint16_t data)
{
  asm volatile ("DMB");
  *(volatile uint16_t*)LCD_CMD_ADDRESS = address; 
  asm volatile ("DMB");
  *(volatile uint16_t*)LCD_DATA_ADDRESS = data; 
}

这是用于通过 Atmel SAME70 上的 BUS 接口将数据发送到外部液晶显示器。 希望有所帮助=)

【讨论】:

    最近更新 更多