我是靠谱客的博主 瘦瘦巨人,最近开发中收集的这篇文章主要介绍有关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”关键字开始,通过括号指明汇编语句的范围,可用双引号与nt的方式对汇编语句进行分隔,形式如下:

 __asm__ ("movl %eax, %ebxnt"
"movl $56, %esint"
"movl %ecx, $label(%edx,%ebx,$4)nt"
"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内嵌汇编的总结的全部内容,希望文章能够帮你解决有关GCC内嵌汇编的总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部