为了账号安全,请及时绑定邮箱和手机立即绑定

C指针原理(6)-C内嵌汇编

标签:
C++


内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来。因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口。简单得说,内联汇编,就是可以让程序员在C语言中直接嵌入汇编代码,并与汇编代码交互C程序中的C表达式,享受汇编的高运行效率。

 

 

内联汇编的格式是直接在C代码中插入以下格式:

asm(

....

....

)

其中的"..."为汇编代码,比如下面例子中,在 result=a*b和printf("%d\n",result)之间插入一段汇编,

     下面的这段汇编什么都不做,每个nop指令占用一个指令的执行时间

  result=a*b;

    asm("nop\n\t"

    "nop\n\t"

    "nop\n\t"

    "nop");//4个nop指令,\n\t表示换行,然后加上TAB行首空,因为每个汇编指令必须在单独一行,需要换行,加上制表符是为了适应某些编译器的要求。    

    printf("%d\n",result);

可以很明显地看到:

    汇编代码之间用“\n\t”间隔,并且每条汇编代码单独占用一行,共有4个nop指令,每个指令后的“\n\t”表示换行,然后加上TAB行首空,因为每个汇编指令必须在单独一行,需要换行,加上制表符是为了适应某些编译器的要求。

 下面是一个完整的例子,内嵌的汇编完成对2个C程序定义的全局变量c和d的相加,并将相加结果存入全局变量addresult中:

#include <stdio.h>

int c=10;

int d=20;

int addresult;

int main(void){

    int a=6;

    int b=2;

    int result;

    result=a*b;

    asm("nop\n\t"

    "nop\n\t"

    "nop\n\t"

    "nop");//4个nop指令,\n\t表示换行,然后加上TAB行首空,因为每个汇编指令必须在单独一行,需要换行,加上制表符是为了适应某些编译器的要求。    

    printf("%d\n",result);

    asm("pusha\n\t"

    "movl c,%eax\n\t"

    "movl d,%ebx\n\t"

    "add %ebx,%eax\n\t"

    "movl %eax, addresult\n\t"

    "popa");//使用全局C变量c和d    

    printf("%d\n",addresult);    

    return 0;

}

编译上述代码

$ gcc -o test test.c

$ ./test

12

30

在汇编代码中可以直接使用变量名称操作C程序定义的全局变量,比如c、d和addresult就是全局变量:

    "movl c,%eax\n\t"

    "movl d,%ebx\n\t"

    "movl %eax, addresult\n\t"

   内联汇编部分如果不需要编译器优化( 优化可能破坏汇编代码的内部结构,因为汇编代码直接操作寄存器,而寄存器使用优化是编译器提供的功能), 可以在 "asm" 后使用关键字 "volatile"。

asm volatile(

....

....

)

如果程序必须与 ANSI C 兼容,则应该使用 asm 和 volatile。

  __asm__ __volatile__(

   .........

    .........

 )

    下面的代码和刚才代码功能一样,唯一的区别是不需要优化

 #include <stdio.h>

int c=10;

int d=20;

int addresult;

int main(void){

    int a=6;

    int b=2;

    int result;

    result=a*b;

    //ansi c标准的asm有其它用,所以用__asm__,__volatile__表示内联汇编部分不用优化(可以用volatile,但是ansi c不行),以防优化破坏内联代码组织结构

    __asm__ __volatile__("nop\n\t"

    "nop\n\t"

    "nop\n\t"

    "nop");//4个nop指令,\n\t表示换行,然后加上TAB行首空,因为每个汇编指令必须在单独一行,需要换行,加上制表符是为了适应某些编译器的要求。    

    printf("%d\n",result);

    __asm__ __volatile__("pusha\n\t"

    "movl c,%eax\n\t"

    "movl d,%ebx\n\t"

    "add %ebx,%eax\n\t"

    "movl %eax, addresult\n\t"

    "popa");//使用全局C变量c和d    

    printf("%d\n",addresult);    

    return 0;

}

©著作权归作者所有:来自51CTO博客作者myhaspl的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消