了解GCC内联汇编函数

问题描述 投票:0回答:2

我将在下面的问题中写下我的假设(基于我的研究),我认为我自己的疑问中存在自我问题之外的错误:

我正在研究一些为ARM编写的代码:

此函数(取自FreeRTOS端口代码):

portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI(void)
{
    uint32_t ulOriginalBASEPRI, ulNewBASEPRI;

    __asm volatile("    mrs %0, basepri                                         \n"
                   "    mov %1, %2                                              \n"
                   "    msr basepri, %1                                         \n"
                   "    isb                                                     \n"
                   "    dsb                                                     \n"
                   : "=r"(ulOriginalBASEPRI), "=r"(ulNewBASEPRI)
                   : "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY));

    /* This return will not be reached but is necessary to prevent compiler
    warnings. */
    return ulOriginalBASEPRI;
}

我在gcc中了解“ = r”是输出操作数。因此我们将值从asm保存到C变量

现在我所理解的代码等同于:

ulOriginalBASEPRI = basepri
ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY
basepri = ulNewBASEPRI

我了解我们正在返回BASEPRI的原始值,因此第一行。但是,我不明白为什么我们要分配变量ulNewBASEPRI,然后在MSR指令中使用它。

所以我查看了ARMV7 instruction set,然后看到了:enter image description here

i假定拇指指令中没有(MSR立即),并且“编码A1”表示仅在Arm指令模式下有效。因此,我们必须使用= r输出操作数来让汇编程序为变量我正确吗?

自动选择一个寄存器

编辑:忽略本节,因为我误记了冒号

: "i"(configMAX_SYSCALL_INTERRUPT_PRIORITY));

根据我对assembly template的理解:

   asm ( assembler template 
       : output operands                  /* optional */
       : input operands                   /* optional */
       : list of clobbered registers      /* optional */
       );

“ i”不是仅表示(立即)装配中的常数吗?这是否意味着第三个冒号不仅用于清除清单?如果是这样,在输入操作数中找到约束“ i”是否更合适?编辑:忽略此部分,因为我误记了冒号


我了解isb,dsb是内存屏障的东西,但我真的不了解它们的描述。他们到底在做什么?例如,如果删除dsb或isb指令,会发生什么??

我将在下面的问题中写出我的假设(基于我的研究),我认为自己的问题之外还有自己的错误:我正在研究一些为ARM编写的代码:...

c gcc assembly arm
2个回答
1
投票

关于msr上的ARM / Thumb指令集差异:您应该可以自己从文档中回答。 ;-)仅两页后。

dsb(数据同步屏障)确保在执行下一条指令之前完成所有内存访问。 这确实是简短的文字,有关阅读文档所需的全部详细信息。如果您对此操作还有其他[[specific


0
投票
我不明白为什么注释说return语句不运行:
© www.soinside.com 2019 - 2024. All rights reserved.