内联汇编总结

内联汇编是指在高级语言中嵌入汇编语言片段,通常和C/C++语言连用。格式如下所示:
__asm__ __volatile__
(
       “汇编语句
…………
:输出参数列表:输入参数列表:使用的寄存器列表
);
注意:
1.使用的寄存器列表,不包含输入输出列表中的寄存器.
2.使用的寄存器应该用双%号表示。
3.每一行结束使用/n/t分隔。
4.一些常用的寄存器加载代码:a(eax),b(ebx),c(ecx),d(edx),S(esi),D(edi),m(memory),r(任意分配寄存器).
5.输出输入寄存器统一编号:%0,%1,%2……%9

__volatile__关键字表示防止编译器优化修改代码或者代码无返回,告知GCC,以致产生更好的代码。一般内联汇编都会加上此关键字。
内联汇编一般用在宏定义中。
下面举个例子:
把十进制数转化成十六进制字符串。
#include <stdio.h>
#define dec2hex(dec,hex) /
({ /
        __asm__ __volatile__("movl $8 , %%ecx/n/t" /
                             "xorl %%edi , %%edi /n/t" /
                             "_again:/n/t" /
                             "pushl %%eax/n/t" /
                             "andl $0x0000000f , %%eax/n/t" /
                             "addb $0x30 , %%al/n/t" /
                             "cmpb $0x3a , %%al/n/t" /
                             "jl output/n/t" /
                             "addb $7 , %%al/n/t" /
                             "output:/n/t" /
                             "movb %%al , (%%ebx,%%edi)/n/t" /
                             "addl $1 , %%edi/n/t" /
                             "popl %%eax/n/t" /
                             "rorl $4 , %%eax/n/t" /
                             "loop _again/n/t" /
                             "subl $4 , %%edi/n/t" /
                             :"=m"(hex):"b"(hex),"a"(dec):"ecx", /
                          "edx","edi"); /
})
int main(int argc , char ** argv)

{
       char hexString[9] = {0};
       int dec = atoi(argv[1]);
       dec2hex(dec ,hexString);
       printf("hex:%s/n" , hexString);
       return 0;
}
如果采用C语言直接编写
int main(int argc , char ** argv)
{
       char hexString[9] = {0};
       int dec = atoi(argv[1]);
       sprintf(hexString , “%X” , dec);
       printf("hex:%s/n" , hexString);
       return 0;
}
编译器生成的汇编代码:
       .file  "test.c"
       .section   .rodata
.LC0:
       .string     "%X"
       .text
.globl main
       .type       main, @function
main:
       leal   4(%esp), %ecx
       andl $-16, %esp
       pushl       -4(%ecx)
       pushl       %ebp
       movl       %esp, %ebp
       pushl       %edi
       pushl       %ecx
       subl $48, %esp
       movl       4(%ecx), %eax
       addl $4, %eax
       movl       (%eax), %eax
       movl       %eax, (%esp)
       call  atoi
       movl       %eax, -12(%ebp)
       leal   -31(%ebp), %edi
       cld
       movl       $19, %ecx
       movl       $0, %eax
       rep
       stosb
       movl       -12(%ebp), %eax
       movl       %eax, 8(%esp)
       movl       $.LC0, 4(%esp)
       leal   -31(%ebp), %eax
       movl       %eax, (%esp)
       call  sprintf
       leal   -31(%ebp), %eax
       movl       %eax, (%esp)
       call  puts
       movl       $0, %eax
       addl $48, %esp
       popl %ecx
       popl %edi
       popl %ebp
       leal   -4(%ecx), %esp
       ret
       .size main, .-main
       .ident      "GCC: (GNU) 4.1.2 20070502 (Red Hat 4.1.2-12)"
       .section   .note.GNU-stack,"",@progbits
我们可以很清楚的看到,代码调用了libc中的用户级函数。而内联汇编直接不需要在函数调用上花销时间。并且也省去的核心态和用户态切换所花费的时间。

性能比较:
采用内联汇编执行的时间比没有采用内联汇编执行的时间少10倍。各执行1一亿次.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值