有关GCC内嵌汇编的总结

最近可能要用到GCC内嵌汇编,因此将相关内容做一点总结,分享给大家。

还是把参考的网址分享给大家

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s2

http://www.cnblogs.com/whutzhou/articles/2638498.html  这篇文章就是对上一篇文章的翻译

https://gcc.gnu.org/onlinedocs/gcc.pdf

在GCC中共包括两种方法嵌入汇编,分别是:基本内联汇编语句(basic inline asm statement)和扩展内联汇编语句(extended inline asm statement)。基本内联汇编不包括操作数(operand),而扩展内联汇编语句一个或多个操作数(operands)。

先来看看基本内联汇编语句的形式如下:

asm("assembly code");

再给大家举一个简单的例子:

asm("movl %ecx %eax");

这个例子的形式非常简单,就是将ecx的值移入eax中。通过以上例子我们可以发现,基本内联汇编语句首先由“__asm__”或“asm”关键字开始,通过括号指明汇编语句的范围,可用双引号与\n\t的方式对汇编语句进行分隔,形式如下:

 __asm__ ("movl %eax, %ebx\n\t"
          "movl $56, %esi\n\t"
          "movl %ecx, $label(%edx,%ebx,$4)\n\t"
          "movb %ah, (%ebx)");

还可以将以上汇编语句通过“;”进行分隔,上述汇编语句还可以改写为以下形式:

 __asm__ ("movl %eax, %ebx;"
          "movl $56, %esi;"
          "movl %ecx, $label(%edx,%ebx,$4);"
          "movb %ah, (%ebx);");

但上述汇编语句在使用过程中存在问题,一个主要的问题就是GCC并不知道寄存器的值改变了, 特别是编译器对代码进行优化的时候. 编译器会认为,那些存放变量的寄存器,我们并没有改变它,然后继续自己的优化. 为了避免这种情况, 要么, 我们不改变寄存器的值, 要么, 汇编函数返回之前, 还原寄存器使用前的值, 或者 等着代码崩溃(wait for something to crash). 

正是由于上述问题的存在,才引出了我们接下来的主题:扩展内联汇编语句

首先来看扩展汇编语句的形式:

<pre name="code" class="cpp"><pre name="code" class="cpp">    asm ( assembler template   
        : output operands                  /* optional */  
        : input operands                   /* optional */  
        : list of clobbered registers      /* optional */  
        );

 
 
 
 
扩展汇编语句共包括四个参数,分别是汇编语句模板、输出操作数、输入操作数以及 被破坏寄存器的列表,其中除第一个外,后三个均可以省略。虽然参数可以不填,位置却要留在那(就像for循环那样),一个最简单的扩展内联汇编语句形式如下:

    asm ( assembler template   
        : 
        : 
        :   
        );

通过以上形式的分析可以发现,扩展内联汇编语句有些类似于函数调用,输入操作数类似于函数参数,输出操作数类似于函数返回值。

在此还要向大家提醒的一点是输入、输出操作数不需要加入被破坏寄存器列表。


你可能感兴趣的:(有关GCC内嵌汇编的总结)