网站设计会计分录怎么做,免费发布广告信息平台,江西网站建设价格,青岛seo公司网站编程环境是#xff1a;stm32cubeIde
原因#xff1a;很多操作需要使用底层来做#xff0c;比如中断时的上下文数据保存。也就是说用到汇编来实现。
疑问#xff1a;c语言怎么才能跟汇编很好的兼容在一起呢#xff1f;必将是我下一步的必经探索之路了。 一、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 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指令将变量a和b相加并将结果存储在变量 c 中。我们使用输入约束r(a)和r(b)将变量a和b映射到寄存器输出约束r( c )将寄存器映射到变量 c 。 2、数组求和
#include stdio.h
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 // 初始化r1sum为0 MOV r2, #0\n // 初始化r2索引为0 loop:\n // 设置循环标签 LDR r0, [%[array], r2, LSL #2]\n // 读取数组元素到r0 ADD r1, r1, r0\n // 将r0当前数组元素累加到r1sum 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。