GCC Inline ASM GCC内联汇编

GCC Inline ASM GCC内联汇编

GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM——GCC内联汇编。这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码。

1.GCC中基本的内联汇编非常易懂,我们先来看两个简单的例子:__asm__(\看起来很熟悉吧!或者是__asm__(\movl $1,êx // SYS_exit xor ?x,?x int $0x80 \或__asm__( \\\

);基本内联汇编的格式是__asm__ __volatile__(\List\

1、__asm____asm__是GCC关键字asm的宏定义:#define __asm__ asm__asm__或asm用来声明一个内联汇编表达式,所以任何一个内联汇编表达式都是以它开头的,是必不

可少的。2、Instruction ListInstruction List是汇编指令序列。它可以是空的,比如:__asm__ __volatile__(\或__asm__ (\都是完全合法的内联汇编表达式,只不过这两条语句没有什么意义。但并非所有Instruction List为空的内联汇编表达式都是没有意义的,比如:__asm__ (\就非常有意义,它向GCC声明:“我对内存作了改动”,GCC在编译的时候,会将此因素考虑进去。我们看一看下面这个例子:$ cat example1.cint main(int __argc, char* __argv[]) {

int* __p = (int*)__argc;(*__p) =

9999;//__asm__(\ return 5;return (*__p);

}在这段代码中,那条内联汇编是被注释掉的。在这条内联汇编之前,内存指针__p所指向的内存被赋值为9999,随即在内联汇编之后,一条if语句判断__p 所指向的内存与9999是否相等。很明显,它们是相等的。GCC在优化编译的时候能够很聪明的发现这一点。我们使用下面的命令行对其进行编译:$ gcc -O -S example1.c选项-O表示优化编译,我们还可以指定优化等级,比如-O2表示优化等级为2;选项-S表示将C/C++源文件编译为汇编文件,文件名和C/C++文件一样,只不过扩展名由.c变为.s。我们来查看一下被放

在example1.s中的编译结果,我们这里仅仅列出了使用gcc 2.96在RedHat 7.3上编译后的相关函数部分汇编代码。为了保持清晰性,无关的其它代码未被列出。$ cat example1.smain: pushl ?p movl %esp, ?p

movl 8(?p), êx # int* __p = (int*)__argc movl $9999, (êx) # (*__p) = 9999 movl $5, êx # return 5 popl ?p

ret参照一下C源码和编译出的汇编代码,我们会发现汇编代码中,没有if语句相关的代码,而是在赋值语句(*__p)=9999后直接return 5;这是因为GCC认为在(*__p)被赋值之后,在if语句之前没有任何改变(*__p)内容的操作,所以那条if语句的判断条件(*__p) == 9999肯定是为true的,所以GCC就不再生成相关代码,而是直接根据为true的条件生成return 5的汇编代码(GCC使用eax作为保存返回值的寄存器)。我们现在将example1.c中内联汇编的注释去掉,重新编译,然后看一下相关的编译结果。$ gcc -O -S example1.c$ cat example1.smain: pushl ?p movl %esp, ?p

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4