cortexM c语言和汇编嵌套编程

编程环境是:stm32cubeIde

原因:很多操作需要使用底层来做,比如中断时的上下文数据保存。也就是说用到汇编来实现。

疑问:c语言怎么才能跟汇编很好的兼容在一起呢?必将是我下一步的必经探索之路了。

一、C语言和汇编兼容格式

asm( 汇编字符串 : 输出约束字符串 : 输入约束字符串 : 可能被使用了的寄存器 );

汇编字符串:

"mov %c , r0 " "mov r0,r1" "add %c , %a, %b "

输出约束操作(可以类比函数的返回值):

c "r"(c)

输入约束操作 (可以类比函数的参数):

a "r"(a), b "r"(b)

可能被使用了的寄存器 (有的地方叫被破坏了的寄存器):

"r0" "r1"

二、解释一下约束符

  • 汇编代码字符串:包含ARM汇编指令的字符串。我们可以在该字符串中使用%[name]的形式来引用C语言变量。
  • 输入约束:用于将C语言变量映射到ARM寄存器。输入约束的形式为"约束代码"(变量名)。例如,"r"(a)表示将变量a映射到一个通用寄存器。
  • 输出约束:用于将ARM寄存器的值映射回C语言变量。输出约束的形式为"=约束代码"(变量名)。例如,"=r"(c)表示将一个通用寄存器的值赋给变量 c.
  • Clobber列表:用于列出内联汇编代码可能修改的寄存器。这有助于编译器在生成代码时正确处理这些寄存器。Clobber列表的形式为"寄存器名",多个寄存器名用逗号分隔。例如,"r0", "r1", "cc"表示内联汇编代码可能会修改r0r1寄存器和条件码寄存器。

三、操作数约束符

  • "r":表示通用寄存器。例如,"r"(a)表示将变量a映射到一个通用寄存器。
  • "l":表示一个立即数。例如,"l"(a)表示将变量a视为一个立即数。
  • "m":表示一个内存操作数。例如,"m"(a)表示将变量a视为一个内存操作数。

四、寄存器约束符

寄存器约束用于指定内联汇编代码中使用的具体寄存器。寄存器约束的形式为"约束代码(寄存器名)"。例如,"r"(r0)表示将变量映射到r0寄存器。

五、案例

1、加法

#include <stdio.h>

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指令将变量ab相加,并将结果存储在变量 c 中。我们使用输入约束"r"(a)"r"(b)将变量ab映射到寄存器,输出约束"=r"( c )将寄存器映射到变量 c

2、数组求和

#include <stdio.h>

int main(void) {

int array\[\] = {1, 2, 3, 4, 5};

int length = sizeof(array) / sizeof(array0);

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

相关推荐
番茄灭世神4 小时前
汇顶模拟前端GH3220使用备忘录
c语言·单片机·传感器·模拟芯片·电生理信号处理
Brilliantwxx7 小时前
【STM32 】把 printf 搬到串口上 —— C 标准 IO 函数重定向与多文件工程搭建(实战串口电灯)
c语言·开发语言·stm32·单片机·嵌入式硬件·架构·ecmascript
wuminyu7 小时前
Kafka利用sendfile与Page Cache实现高性能传输剖析
java·linux·c语言·jvm·c++
亮_一个嵌入式新手7 小时前
C语言Day21
c语言·开发语言
djarmy17 小时前
MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析
c语言·开发语言·mongodb
李永奉18 小时前
中科蓝讯SDK开发-BT893x 面条耳机连接vivo手机后连接APP端,最后手机端设置页面手动断开蓝牙连接,此时耳机端假断开
c语言·开发语言·嵌入式硬件·物联网·智能手机·电脑
爱吃苹果的日记本21 小时前
数据结构第一课
c语言·数据结构·数据库·学习·c#
aramae1 天前
模拟实现strstr函数(C语言)
c语言·开发语言·算法
多弗朗皮卡丘1 天前
数据结构4:链表(下)
c语言·数据结构·链表
我的小卷呀1 天前
Linux ip 命令底层逻辑与实战指南
linux·运维·c语言·网络协议·tcp/ip·网络安全