GNU 内联汇编:
gnu嵌入汇编,内嵌汇编详细的介绍_梦悦foundation的博客-CSDN博客_内嵌汇编
intel and gnu gas 系列之gnu内嵌汇编格式,以x86为例_memdev_新浪博客
"__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版权协议,转载请附上原文出处链接和本声明。