编程环境是:stm32cubeIde
原因:很多操作需要使用底层来做,比如中断时的上下文数据保存。也就是说用到汇编来实现。
疑问:c语言怎么才能跟汇编很好的兼容在一起呢?必将是我下一步的必经探索之路了。
asm( 汇编字符串 : 输出约束字符串 : 输入约束字符串 : 可能被使用了的寄存器 );
汇编字符串:
"mov %[c] , r0 " "mov r0,r1" "add %[c] , %[a], %[b] "
输出约束操作(可以类比函数的返回值):
[c] "r"(c)
输入约束操作 (可以类比函数的参数):
[a] "r"(a), [b] "r"(b)
可能被使用了的寄存器 (有的地方叫被破坏了的寄存器):
"r0" "r1"
%[name]
的形式来引用C语言变量。"约束代码"(变量名)
。例如,"r"(a)
表示将变量a
映射到一个通用寄存器。"=约束代码"(变量名)
。例如,"=r"(c)
表示将一个通用寄存器的值赋给变量 c.
"寄存器名"
,多个寄存器名用逗号分隔。例如,"r0", "r1", "cc"
表示内联汇编代码可能会修改r0
、r1
寄存器和条件码寄存器。 "r"
:表示通用寄存器。例如,"r"(a)
表示将变量a
映射到一个通用寄存器。"l"
:表示一个立即数。例如,"l"(a)
表示将变量a
视为一个立即数。"m"
:表示一个内存操作数。例如,"m"(a)
表示将变量a
视为一个内存操作数。寄存器约束用于指定内联汇编代码中使用的具体寄存器。寄存器约束的形式为"约束代码(寄存器名)"
。例如,"r"(r0)
表示将变量映射到r0
寄存器。
#include
int main(void) {
int a = 10, b = 20, c;
asm (
"ADD %[c], %[a], %[b]"
: [c] "=r" (c)
: [a] "r" (a),
[b] "r" (b)
);
printf("The c is: %d\n", c);
return 0;
}
我们使用ADD
指令将变量a
和b
相加,并将结果存储在变量 c
中。我们使用输入约束"r"(a)
和"r"(b)
将变量a
和b
映射到寄存器,输出约束"=r"( c )
将寄存器映射到变量 c
。
#include
int main(void) {
int array[] = {1, 2, 3, 4, 5};
int length = sizeof(array) / sizeof(array[0]);
int sum = 0;
asm (
"MOV r1, #0\n" // 初始化r1(sum)为0
"MOV r2, #0\n" // 初始化r2(索引)为0
"loop:\n" // 设置循环标签
"LDR r0, [%[array], r2, LSL #2]\n" // 读取数组元素到r0
"ADD r1, r1, r0\n" // 将r0(当前数组元素)累加到r1(sum)
"ADD r2, r2, #1\n" // 增加索引(r2)
"CMP r2, %[length]\n" // 比较索引(r2)和数组长度(length)
"BLT loop\n" // 如果索引小于长度,跳回循环开始
: //若是省略也必须有冒号
: [array] "r"(array),
[length] "r"(length)
: "r0", "r1", "r2", "cc"
);
asm( "mov %[sum],r1":[sum] "=r"(r1) );
printf("The sum of the array is: %d\n", sum);
return 0;
}
使用输入约束"r"(array)
和"r"(length)
将数组指针和数组长度映射到寄存器,输出约束"=r"(sum)
将寄存器映射到变量sum
。