C中内嵌汇编入门

GNU 内联汇编:

gnu嵌入汇编,内嵌汇编详细的介绍_梦悦foundation的博客-CSDN博客_内嵌汇编

intel and gnu gas 系列之gnu内嵌汇编格式,以x86为例_memdev_新浪博客

C和汇编如何互相调用?嵌入式工程师必须掌握 - 维科号

"__asm__" 表示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。

“__volatile__” 表示编译器不要优化代码,后面的指令保留原样,“volatile”是它的别名。 括号里面是汇编指令。

基于上面的这些介绍,memory的功能主要如下

  (1)不要将该段内嵌汇编指令与前面的指令重新排序;也就是在执行内嵌汇编代码之前,它前面的指令都执行完毕

  (2)不要将变量缓存到寄存器,因为这段代码可能会用到内存变量,而这些内存变量会以不可预知的方式发生改变,因此 GCC 插入必要的代码先将缓存到寄存器的变量值写回内存,如果后面又访问这些变量,需要重新访问内存。

__asm__( 
汇编语句模板: 
输出部分: 
输入部分: 
破坏描述部分)

汇编网上查找的时候有时候会看到add,有时候会看到addl,区别介绍:gcc内嵌汇编 - KingsLanding - 博客园

linux下使用的是 AT&T语法的gcc内嵌汇编,常用如下:

在 AT&T 汇编格式中,目标操作数在源操作数的右边

在 AT&T 汇编格式中,操作数的字长由操作符的最后一个字母决定

用 '$' 前缀表示一个立即操作数, 寄存器名要加上 '%' 作为前缀

汇编指令:​​​​​​汇编指令 - lxgeek - 博客园

 测试demo如下:

  int a=100;
   int b=25;
   int c=1;
   int d=0;
   #if 0
   //置数,立即数需要加$
   asm volatile (
   "movl $111,%0\n\t"
   "movl $24,%1\n\t"
   :"=r"(b),
   "=r"(a) 
   :
   :
   );
   printf("a=%d,b=%d,c=%d\n",a,b,c);
   #endif
   
   #if 0
   asm volatile (
   "addl %0,%2\n\t"
   "addl %1,%2\n\t"
   :"+r"(a),"+r"(b),"+r"(c)
   :
   :
   );
   printf("a=%d,b=%d,c=%d\n",a,b,c);
   #endif
   
   #if 0
   asm volatile (
   "testl $64,%0\n\t"
   "je 1f\n\t"
   "0:\n\t"
   "movl $111,%1\n\t"
   "jmp 2f\n\t"
   "1:\n\t"
   "movl $222,%1\n\t"
   "jmp 2f\n\t"
   
   "2:"
   :"+r"(a),"+r"(b)
   :
   :
   );
   printf("a=%d,b=%d,c=%d\n",a,b,c);
   #endif
   
   #if 0
   /*
   testl + je循环第2遍就退出了,因为testl是位操作,参考上面的例子
   cmpl + je/jle 可以正常循环
   */
   asm volatile (
   "movl $30,%1\n\t"
   
   "0:\n\t"
   "decl %1 \n\t"
   "cmpl $0,%1 \n\t"
   "je 1f\n\t"
   "incl %0\n\t"
   "jmp 0b\n\t"
   
   "1:\n\t"
   :"+r"(c),"+r"(d)
   :
   :
   );
   printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
   #endif


版权声明:本文为qq_30503573原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。