我将在下面的问题中写下我的假设(基于我的研究),我认为我自己的疑问中存在自我问题之外的错误:
我正在研究一些为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,然后看到了:
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编写的代码:...
关于msr
上的ARM / Thumb指令集差异:您应该可以自己从文档中回答。 ;-)仅两页后。
dsb
(数据同步屏障)确保在执行下一条指令之前完成所有内存访问。 这确实是简短的文字,有关阅读文档所需的全部详细信息。如果您对此操作还有其他[[specific