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"`表示内联汇编代码可能会修改`r0`、`r1`寄存器和条件码寄存器。 ### 三、操作数约束符 * `"r"`:表示通用寄存器。例如,`"r"(a)`表示将变量`a`映射到一个通用寄存器。 * `"l"`:表示一个立即数。例如,`"l"(a)`表示将变量`a`视为一个立即数。 * `"m"`:表示一个内存操作数。例如,`"m"(a)`表示将变量`a`视为一个内存操作数。 ### 四、寄存器约束符 寄存器约束用于指定内联汇编代码中使用的具体寄存器。寄存器约束的形式为`"约束代码(寄存器名)"`。例如,`"r"(r0)`表示将变量映射到`r0`寄存器。 ### 五、案例 ##### 1、加法 #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 `。 ##### 2、数组求和 #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`。

相关推荐
charlie1145141911 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数
white-persist1 小时前
【攻防世界】reverse | Reversing-x64Elf-100 详细题解 WP
c语言·开发语言·网络·python·学习·安全·php
Want5951 小时前
C/C++贪吃蛇小游戏
c语言·开发语言·c++
雨落在了我的手上3 小时前
C语言入门(二十二):字符函数和字符串函数(2)
c语言
qq_401700417 小时前
嵌入式用Unix时间的优势及其C语言转换
服务器·c语言·unix
智者知已应修善业12 小时前
【51单片机普通延时奇偶灯切换】2023-4-4
c语言·经验分享·笔记·嵌入式硬件·51单片机
晚风(●•σ )13 小时前
C++语言程序设计——11 C语言风格输入/输出函数
c语言·开发语言·c++
X***489613 小时前
C源代码生成器
c语言·开发语言
合作小小程序员小小店15 小时前
桌面安全开发,桌面二进制%恶意行为拦截查杀%系统安全开发3.0,基于c/c++语言,mfc,win32,ring3,dll,hook,inject,无数据库
c语言·开发语言·c++·安全·系统安全
oioihoii18 小时前
C++语言演进之路:从“C with Classes”到现代编程基石
java·c语言·c++