第一种实现(纯汇编形式)
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
代码分析
__ASM
关键字:这通常是特定编译器(如 ARM GCC 等)用于嵌入汇编代码的指示符。它告诉编译器下面的代码是汇编代码。mrs r0, primask
:
mrs
是 ARM 汇编中的一条指令,用于将特殊寄存器的值传送到通用寄存器。r0
是通用寄存器,在 ARM 架构里,函数返回值一般存放在 r0
寄存器中。primask
是 PRIMASK
寄存器,该寄存器用于控制可屏蔽中断的使能或禁止。此指令的作用是把 PRIMASK
寄存器的值读取到 r0
寄存器。
bx lr
:
bx
是跳转指令,lr
是链接寄存器。在函数调用时,lr
会保存返回地址。这条指令的功能是跳转到 lr
所保存的地址,从而实现函数返回。
第二种实现(内联汇编形式)
uint32_t __get_PRIMASK(void)
{
uint32_t result = 0;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
代码分析
uint32_t result = 0;
:定义一个 32 位无符号整数变量 result
,并初始化为 0,用于存储 PRIMASK
寄存器的值。__ASM volatile ("MRS %0, primask" : "=r" (result) );
:
__ASM
:同样是用于嵌入汇编代码的指示符。volatile
:该关键字告知编译器不要对这段汇编代码进行优化,确保代码按照原样执行。"MRS %0, primask"
:这是汇编指令模板,%0
是操作数占位符,代表后面指定的第一个操作数。此指令的意思是将 PRIMASK
寄存器的值传送到 %0
所代表的寄存器。"=r" (result)
:这是输出操作数列表。"=r"
表示将结果存放到一个通用寄存器中,(result)
表示这个通用寄存器的值会被赋给变量 result
。=
表示这是一个只写操作数。
return(result);
:返回存储 PRIMASK
寄存器值的变量 result
。
两种实现方式的比较
- 纯汇编形式:代码简洁,直接使用汇编指令,性能可能稍高一些,因为没有中间变量的转换。不过,它的可移植性较差,不同编译器可能对
__ASM
关键字的支持有所不同。 - 内联汇编形式:将汇编代码嵌入到 C 语言中,代码的可读性和可维护性相对较好,同时也方便与 C 语言代码进行交互。而且,内联汇编的语法在不同编译器间的兼容性可能更好一些。
注意事项
- 两种实现方式在功能上是等价的,都是为了获取
PRIMASK
寄存器的值。但在实际使用时,要根据项目的具体需求和编译器的特性来选择合适的实现方式。 - 这两种实现都依赖于 ARM Cortex - M 架构,在其他架构的处理器上不能直接使用。