gcc 内联asm

1.基本的内联汇编

1)asm格式   http://blog.csdn.net/guzhou_diaoke/article/details/8393548

GNU的C编译器使用asm关键字指出使用汇编语言编写的源代码段落。基本格式:
asm("assembly code");
括号中的汇编格式:指令必须在引号里;指令超过一条,必须使用新行字符分隔。如:
  1. asm ( "movl $1, %eax\n\t"  
  2.       "movl $0, %ebx\n\t"  
  3.       "int  $0x80" );  

  4. 3)volatile修饰符

    编译器会试图优化生成的汇编代码以提高性能。但对内联汇编来说,优化有时并不是好事。如果不希望编译器处理内联汇编代码,可以明确地说明。用volatile修饰符可以完成这个请求:
    asm volatile ("assembly code");
  5.  gcc 内联汇编的格式如下:

    [cpp]  view plain copy
    1. asm ( 汇编语句  
    2.     : 输出操作数     // 非必需  
    3.     : 输入操作数     // 非必需  
    4.     : 其他被污染的寄存器 // 非必需  
    5.     );  

      我们通过一个简单的例子来了解一下它的格式(gcc_add.c):

    [cpp]  view plain copy
    1. #include <stdio.h>  
    2.   
    3. int main()  
    4. {  
    5.     int a=1, b=2, c=0;  
    6.   
    7.     // 蛋疼的 add 操作  
    8.     asm(  
    9.         "addl %2, %0"       // 1  
    10.         : "=g"(c)           // 2  
    11.         : "0"(a), "g"(b)    // 3  
    12.         : "memory");        // 4  
    13.   
    14.     printf("现在c是:%d\n", c);  
    15.     return 0;  
    16. }  

      内联汇编中:

    1. 第1行是汇编语句,用双引号引起来, 多条语句用 ; 或者 \n\t 来分隔。
    2. 第2行是输出操作数,都是 "=?"(var) 的形式, var 可以是任意内存变量(输出结果会存到这个变量中), ? 一般是下面这些标识符(表示内联汇编中用什么来代理这个操作数):

      • a,b,c,d,S,D 分别代表 eax,ebx,ecx,edx,esi,edi 寄存器
      • r 上面的寄存器的任意一个(谁闲着就用谁)
      • m 内存
      • i 立即数(常量,只用于输入操作数)
      • g 寄存器、内存、立即数 都行(gcc你看着办)

      在汇编中用 %序号 来代表这些输入/输出操作数,序号从 0 开始。为了与操作数区分开来,寄存器用两个%引出,如:%%eax

    3. 第3行是输入操作数,都是 "?"(var) 的形式, ? 除了可以是上面的那些标识符,还可以是输出操作数的序号,表示用 var 来初始化该输出操作数,上面的程序中 %0 和 %1 就是一个东西,初始化为 1(a的值)。
    4. 第4行标出那些在汇编代码中修改了的、又没有在输入/输出列表中列出的寄存器,这样 gcc 就不会擅自使用这些"危险的"寄存器。还可以用 "memory" 表示在内联汇编中修改了内存,之前缓存在寄存器中的内存变量需要重新读取。

      上面这一段内联汇编的效果就是,把a与b的和存入了c。当然这只是一个示例程序,谁要真这么用就蛋疼了,内联汇编一般在不得不用的情况下才使用


  6. 4)__asm__替换关键字

    ANSI C 规范把关键字asm用于其他用途,不能将它用于内联汇编语句。如果希望使用ANSI C 约定编写代码,必须使用关键字__asm__替换一般的关键字asm。汇编代码段则与asm一样。__asm__可以使用__volatile__进行修饰。


  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
GCC汇编asm格式是一种将汇编代码嵌入到C或C++源代码中的方法。它允许开发人员直接使用汇编语言来访问底层硬件或执行高性能算法。以下是GCC汇编asm格式的详细说明。 基本格式 GCC汇编asm格式基本格式如下: ```c asm (assembly code : output operands : input operands : clobbered registers); ``` - assembly code:汇编代码,可以是单行或多行代码。 - output operands:用于存储计算结果的变量,可以有多个,用逗号分隔。输出操作数是可选的,可以省略。 - input operands:用于传递参数的变量,可以有多个,用逗号分隔。输入操作数是必需的。 - clobbered registers:代码执行期间会被修改的寄存器,用于通知编译器。可以有多个,用逗号分隔。clobbered registers是可选的,可以省略。 示例 以下是一个简单的GCC汇编asm格式示例,将eax寄存器中的值加1,并将结果存储在eax中。 ```c int value = 10; asm ("addl $1, %%eax" : "=a" (value) : "a" (value)); ``` - "addl $1, %%eax":汇编代码,将eax加1。 - "=a" (value):输出操作数,将eax中的值存储在value变量中。 - "a" (value):输入操作数,将value的值传递给eax。 - 没有clobbered registers。 输出操作数 输出操作数用于将汇编代码的结果存储在变量中。输出操作数有两种类型:普通输出(通道约束)和跨约束输出。 普通输出 普通输出使用“=约束”语法表示,其中约束指定了输出操作数应存储在哪个寄存器或内存位置中。约束可以是以下之一: - "=r"(任意寄存器) - "=m"(任意内存位置) - "=a"(eax寄存器) - "=d"(edx寄存器) - "=q"(eax或edx寄存器) 示例 以下是一个使用普通输出的示例,将eax寄存器中的值加1,并将结果存储在value变量中。 ```c int value; asm ("addl $1, %%eax" : "=a" (value) : "a" (value)); ``` 跨约束输出 跨约束输出是一种将结果存储在多个输出变量中的方法。它使用“+约束”语法表示,其中约束指定了输出操作数应存储在哪个寄存器或内存位置中。多个约束可以用逗号分隔。 示例 以下是一个使用跨约束输出的示例,将eax寄存器中的值加1,并将结果存储在value1和value2变量中。 ```c int value1, value2; asm ("addl $1, %%eax" : "+a" (value1), "=r" (value2)); ``` 输入操作数 输入操作数用于将变量的值传递给汇编代码。输入操作数使用“约束”语法表示,其中约束指定了变量应该存储在哪个寄存器或内存位置中。约束可以是以下之一: - "r"(任意寄存器) - "m"(任意内存位置) - "a"(eax寄存器) - "d"(edx寄存器) - "q"(eax或edx寄存器) 示例 以下是一个使用输入操作数的示例,将value变量的值传递给eax寄存器中。 ```c int value = 10; asm ("movl %0, %%eax" : : "r" (value)); ``` clobbered registers clobbered registers是在汇编代码执行期间会被修改的寄存器列表。它用于通知编译器哪些寄存器应该被保存和恢复。clobbered registers使用“%约束”语法表示,其中约束指定了被修改的寄存器名称。多个寄存器可以用逗号分隔。 示例 以下是一个使用clobbered registers的示例,将eax寄存器中的值加1,并告诉编译器edx寄存器也被修改了。 ```c asm ("addl $1, %%eax" : : "a" (value) : "%edx"); ``` 总结 GCC汇编asm格式是一种将汇编代码嵌入到C或C++源代码中的方法。它允许开发人员直接使用汇编语言来访问底层硬件或执行高性能算法。通过输出操作数、输入操作数和clobbered registers,开发人员可以管理汇编代码与C或C++代码之间的数据流和寄存器使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Farmwang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值