用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码。另外,有些平台相关的指令必须手写,在C语言中没有等价的语法,因为C语言的语法和概念是对各种平台的抽象,而各种平台特有的一些东西就不会在C语言中出现了,例如x86是端口I/O,而C语言就没有这个概念,所以in/out指令必须用汇编来写。

C语言简洁易读,容易组织规模较大的代码,而汇编效率高,而且写一些特殊指令必须用汇编,为了把这两方面的好处都占全了,gcc提供了一种扩展语法可以在C代码中使用内联汇编(Inline Assembly)。最简单的格式是__asm__("assembly code");,例如__asm__("nop"); ,nop 这条指令什么都不做,只是让CPU空转一个指令执行周期。如果需要执行多条汇编指令,则应该用\n\t将各条指令分隔开,例如:

__asm__("movl $1, %eax\n\t"
"movl $4, %ebx\n\t"
"int $0x80");

通常 C 代码中的内联汇编需要和C的变量建立关联,需要用到完整的内联汇编格式:

__asm__(assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);

这种格式由四部分组成,第一部分是汇编指令,和上面的例子一样,第二部分和第三部分是约束条件,第二部分指示汇编指令的运算结果要输出到哪些C操作数中,C操作数应该是左值表达式,第三部分指示汇编指令需要从哪些C操作数获得输入,第四部分是在汇编指令中被修改过的寄存器列表,指示编译器哪些寄存器的值在执行这条__asm__语句时会改变。后三个部分都是可选的,如果有就填写,没有就空着只写个:号。例如:

例 19.6. 内联汇编

#include <stdio.h>

int main()
{
int a = 10, b; __asm__("movl %1, %%eax\n\t"
"movl %%eax, %0\n\t"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);
printf("Result: %d, %d\n", a, b);
return 0;
}

这个程序将变量a的值赋给b"r"(a)指示编译器分配一个寄存器保存变量a的值,作为汇编指令的输入,也就是指令中的%1(按照约束条件的顺序,b对应%0a对应1%),至于%1究竟代表哪个寄存器则由编译器自己决定。汇编指令首先把%1所代表的寄存器的值传给eax(为了和%1这种占位符区分,eax前面要求加两个%号),然后把eax的值再传给%0所代表的寄存器。"=r"(b)就表示把%0所代表的寄存器的值输出给变量b。在执行这两条指令的过程中,寄存器eax的值被改变了,所以把"%eax"写在第四部分,告诉编译器在执行这条__asm__语句时eax要被改写,所以在此期间不要用eax保存其它值。

我们看一下这个程序的反汇编结果:

        __asm__("movl %1, %%eax\n\t"
80483dc: 8b 55 f8 mov -0x8(%ebp),%edx
80483df: 89 d0 mov %edx,%eax
80483e1: 89 c2 mov %eax,%edx
80483e3: 89 55 f4 mov %edx,-0xc(%ebp)
"movl %%eax, %0\n\t"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);

可见%0%1都代表edx寄存器,首先把变量a(位于ebp-8的位置)的值传给edx然后执行内联汇编的两条指令,然后把edx的值传给b(位于ebp-12的位置)。

关于内联汇编就介绍这么多,本书不做深入讨论。

C内联汇编的更多相关文章

  1. x86平台转x64平台关于内联汇编不再支持的解决

    x86平台转x64平台关于内联汇编不再支持的解决     2011/08/25   把自己碰到的问题以及解决方法给记录下来,留着备用!   工具:VS2005  编译器:cl.exe(X86 C/C+ ...

  2. GNU C 内联汇编介绍

    GNU C 内联汇编介绍 简介 1.很早之前就听说 C 语言能够直接内嵌汇编指令.但是之前始终没有去详细了解过.最近由于某种需求,看到了相关的 C 语言代码.也就自然去简单的学习了一下如何在 C 代码 ...

  3. 最牛X的GCC 内联汇编

    导读 正如大家知道的,在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法.本文将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 ...

  4. Linux 中 x86 的内联汇编

    工程中需要用到内联汇编,找到一篇不错的文章,趁机学习下. 原文地址:http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/ 如果 ...

  5. GCC内联汇编入门

    原文为GCC-Inline-Assembly-HOWTO,在google上可以找到原文,欢迎指出翻译错误. 中文版说明 由于译者水平有限,故译文出错之处,还请见谅.C语言的关键字不译,一些单词或词组( ...

  6. C语言的本质(32)——C语言与汇编之C语言内联汇编

    用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码.另外,有些平台相关的指令必 ...

  7. VC++的内联汇编

    1.移植性差,假设是软件项目建议不要用.假设希望一段程序仅在单一设备上执行而且效率极高,能够使用内联汇编. 比方.单片机开发. 2. ......持续更新中. .... .

  8. [翻译] GCC 内联汇编 HOWTO

    目录 GCC 内联汇编 HOWTO 原文链接与说明 1. 简介 1.1 版权许可 1.2 反馈校正 1.3 致谢 2. 概览 3. GCC 汇编语法 4. 基本内联 5. 扩展汇编 5.1 汇编程序模 ...

  9. vs编写x64内联汇编

    参考自: https://www.cnblogs.com/achillis/p/5369658.html 先转过来, 等实践过了再做相应的修改, hehe 编写涉及系统特性的一些底层程序,特别是She ...

随机推荐

  1. activiti

    http://activiti.org/designer/archived/  eclipse plugin

  2. 利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)

    利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)   作者:王可利(Star·星星) 总结: 今天学习的jQ类库的使用,代码重复的比较多需要完善.严格区分大小写,在 $(" ...

  3. HDU1006

    Problem Description The three hands of the clock are rotating every second and meeting each other ma ...

  4. ED/EP系列1《简介》

    电子存折(ED:ElectronicDeposit)一种为持卡人进行消费.取现等交易而设计的支持个人识别码(PIN)保护的金融IC卡应用.它支持圈存.圈提.消费和取现等交易. 电子钱包(EP:Elec ...

  5. oracle11g 新特性 - rman自动备份控制文件延迟

    OS: Oracle Linux Server release 5.7 DB: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -6 ...

  6. ubuntu常见错误--Could not get lock /var/lib/dpkg/lock解

        通过终端安装程序sudo apt-get install xxx时出错:   E: Could not get lock /var/lib/dpkg/lock - open (11: Reso ...

  7. AMD 和 CMD as lazy as possible

    http://blog.chinaunix.net/uid-26672038-id-4112229.html AMD 与 CMD 区别到底在哪里?       看了以上 AMD,requireJS 与 ...

  8. C++ 类的前置声明

    http://www.2cto.com/kf/201311/260705.html    今天在研究C++”接口与实现分离“的时候遇到了一个问题,看似很小,然后背后的东西确值得让人深思!感觉在学习的过 ...

  9. java并发编程:如何创建线程

    原文:http://www.cnblogs.com/dolphin0520/p/3913517.html 一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也 ...

  10. ios-仿新浪微博app-第1天UI搭建

    1:不用storyboard 点击工程删除main  ui加载全部手码  >> 在application的代理方法didFinishLaunchingWithOptions中添加代码显示w ...