http://blog.csdn.net/yrj/article/details/492404

1、GCC的编译和安装
2、预处理
    #define 可以支持不定数量的参数。
    例子如下:
    #define err(...) fprintf(stderr,__VA_ARGS__)
    err("%s,%d/r/n","The error code:",48);
    扩展为:
    fprintf(stderr,"%s,%d/r/n","The error code:",48);

gcc的命令行参数“-E”的作用是,只执行预处理,并不执行编译和链接。命令行参数“-M”则对一个源代码生成makefile中使用的目标,依赖规
则,这个也是预处理程序(cpp)做的。所以我们为了获得目标,依赖规则可以调用“gcc -E -M main.c”

__USER_LABEL_PREFIX__是编译器内部定义的一个宏,用于作为汇编语言符号的前缀,视不同的系统而定,通常使用"_"字符。

3、C语言编译

gcc能够自动分析源代码文件的扩展名(.c),可以直接将源代码文件编译成可执行文件。“-c”选项则指定gcc将源代码文件编译成二进制文件(objective file)。如果源代码文件的扩展名不是".c",则使用"-x"选项指定。

gcc的"-aux-info"选项可根据源代码文件生成包含函数原型声明的头文件(.h)。例如:

gcc hello.c -aux-info hello.h

gcc *.c -aux-info hello.h    #根据当前目录下的所有C源代码文件中的函数,生成函数原型声明头文件hello.h。

(1)、GCC中的C语言扩展

使用"-pedantic"选项,gcc在编译带有gnu c语言扩展的源代码的时候会发出警告,可以在源代码的扩展表达前使用“__extension__.”关键字,禁止发出警告。

__alignof__关键字用于数据类型(data type)或特定的数据项(specific data
item)的边界对齐操作。在不同的硬件系统上,__alignof__关键字所获得的结果是不同的,结果是硬件访问数据的边界。举例如下:

int i=__alignof__(char); //在X86平台上i== 1

匿名联合(Anonymous Unions),可以不为数据结构(struct)中的联合变量声明名称而可以直接使用。

struct {
     char code;
     union {
          char chid[4];
          int numid;
     };
      char *name;
} morx;

可以这样访问数据:morx.code, morx.chid,morx.numid, and morx.name.

可变长度的数组(Arrays of Variable Length):声明数组的时候可以根据运行时的情况动态决定。

char sample[strlen(inputstr)];

重点部分:__attribute__关键字扩展

GCC使用__attribute__关键字来描述函数,变量和数据类型的属性,用于编译器对源代码的优化。

GCC使用__attribute__关键字来描述函数,变量和数据类型的属性,用于编译器对源代码的优化。

描述函数属性的几个重要的关键字:

void noreturnfun() __attribute__((noreturn));//函数不会返回。

void centon() __attribute__((alias("__centon")));//设置函数别名,函数是__cencon,别名是centon.

void main_enter() __attribute__((constructor));//main_enter函数在进入main函数前调用

void main_exit() __attribute__((destructor));//main_exit函数在main函数返回后调用

void fun() __attribute__ ((noinline));//fun函数不能作为inline函数优化

void fun() __attribute__ ((section("specials”)));//将函数放到specials段中,而不是通常的text段中

no_instrument_function、constructor和destructor关键字主要用于剖析(profiling)源代码的。

在调某个用函数之前和退出某个函数之后调用这些剖析函数,配合addr2line工具可以统计程序的运行状态。
__cyg_profile_func_enter和__cyg_profile_func_exit是GCC指定的进入和返回调用的函数名。配合
no_instrument_function关键字属性可以使用它记录剖析数据,在编译这样的代码的时候,需要在gcc的命令行中加入
-finstrument-functions选项,如果要使用addr2line工具分析源代码,则还要加上-g的gcc命令行选项使得源代码中的符号
可以保留。这2个函数需要2个参数,void *func_address是将要调用的函数地址,void *call_site是调用该函数的地址。

void __cyg_profile_func_enter( void *func_address, void *call_site )
                                __attribute__ ((no_instrument_function));

void __cyg_profile_func_exit ( void *func_address, void *call_site )
                                __attribute__ ((no_instrument_function));

constructor和destructo是对main函数做上述剖析的关键字,不过这个函数的名称就可以不特定了,而且这样的函数没有参数。如下:

void __main_enter(void) __attribute__ ((constructor));

void __main_exit(void) __attribute__ ((destructor));

描述变量属性的几个重要的关键字:

int alivalue __attribute__ ((aligned(32)));//变量所存放的内存地址32字节边界对齐

struct zrecord {
char id;
int zar[32] __attribute__ ((packed));
};//紧凑安排数据结构中的成员元素。如果不使用packed属性则将zar数组按最小的对齐方式在内存中安排空间,X86平台为4,这样在id和zar之间将会有3个字节的空洞存在。而使用了packed属性后,将不会存在这样的空洞。这次属性是依赖与硬件平台的。

struct domx __attribute__ ((section(“domx”))) = { 0 };
int trigger __attribute__ ((section(“MONLOG”))) = 0; //不将全局变量放在默认的data或bss段中。而指定特定的段中。

描述数据类型的几个重要的关键字:

struct blockm{

char j[3];

}__attribute__((aligned(32)));//此数据类型的变量的内存地址32字节边界对齐

复合声明返回值(Compound Statements Returning a Value):

在一对圆括号中的最后一个表达式所计算的值为返回值。如:

int rslt = ({

int a=5;

a+3;

});//rslt所获得的返回值为8

这个特性的通常用处可书的P87(文档P112)参考。

函数参数构造(Function Argument Construction):

GCC内建了3个函数,用于对某一函数的参数构造,调用相关函数,获得相关函数的返回值。

void *__builtin_apply_args(void);//构造调用此函数的父函数的参数,这些参数都是保存在函数栈(stack)中的。

void *__builtin_apply(void (*func)(), void *arguments, int size);//调用相关函数,第一参数是相关函数的执政,第二个参数是刚才构造参数的函数的返回的指针,第三个参数是建立一个新的栈(stack)而从旧栈中复制数据的尺寸。

__builtin_return(void *result);//获得相关函数的返回。参数是刚才调用相关函数的函数的返回指针。

如:

#include <stdio.h>

int passthrough();

int average();

int main(int argc,char *argv[])

{

int result;

result = passthrough();

printf(“result=%d/n”,result);

return (0);

}

int passthourgh(int a,int b,int c)

{

void *record;

void *playback;

void (* fn)() = (void (*) ()) average;

record = __builtin_apply_args();

playback = __builtin_apply(fn,record,128);

__builtin_return(playback);

}

int average(int a,int b,int c)

{

Return ((a+b+c)/3;

}

内联函数(Inline function):

内联函数在某些情况下类似与宏(macro)。

在一定条件下编译,内联函数将直接将代码内嵌到调用它的父函数中,编译时指定-O选项才可能被内嵌。也可以指定内嵌函数一个属性“always_inline”强制内嵌。

有几种情况将不内嵌,而作为普通函数调用:

1、  不确定数量参数的函数

2、  调用alloca类库函数的

3、  有可变尺寸数组声明的。

4、  非本地goto的。

5、  嵌套调用的。

使用ISO C标准的时候,可以使用__inline__关键字代替inline关键字。

内嵌函数(Function Nesting)

嵌入式汇编:
格式:
asm (“汇编语句”
        :输出部
        :输入部
        :错误输出部
       );
1、汇编语言部分应在替一行内书写,可以使用"/"符号链接多行,每句之间用分号分隔。

2、.在访问寄存器的时候,需要使用2个百分号,因为嵌入式汇编的语法,使用一个百分号指定相关联的从C中输入输出的变量。例:movl %%eax,%1
3、.关联C中输入输出的变量,在嵌入式汇编的语法中,输出部和输入部是统一编索引的。如输出部中有2个关联,则第一个是%0,第二个是%1,而输入部中的第一个关联是%2,依次例推。
4、间接寻址,使用括号,例子: movb (%%esi), %%al
5、立即数用“$”符合制定,例子:$86   $0xF35A

GNU Assembler 伪指令:

.align boundary [,filler][,maximum]

在当前位置插入filler所指定的值并且地址对齐与指定的边界。这3个值都是绝对数。如果filler没有指定,则数据段中默认填充0,指令段中默认填充noop操作码。如果指定maximum,表示最多填充filler的数量,如果这个的值加上当前地址大于当前第一个边界,则只填充到第一个边界。如果小于当前第一个边界,则忽略这个伪指令。

filler参数和maximum参数是可选的,如果指定maximum而不指定filler,使用二个逗号直接指定maximum。例子:.align 32,,100

各个系统上在使用这个伪指令的时候可能由不兼容的现象。例如,在一些系统上,指定地址8字节对齐使用“.align 8”的格式。而另外的一些系统上,指定地址8字节对齐则使用“.align 3”的格式,这个格式的含义是地址值的最后0的最少数量。相同的语法也用于“.balign”和“p2align”伪指令。

.ascii [string][,string…]

声明一个或多个可以引用的ASCII字符串。字符串不带“/0”字符串结束符。

.asclz [string][,sting…]

声明一个或多个可以引用的ASCII字符串。字符串带“/0”字符串结束符。

.balign boundary [,filler][,maximum]

类似与“.align”。但filler为8位的值

.balignl boundary [,filler][,maximum]

类似与“.balign”,但filler是32位的值

.balignw boundary [,filler][,maximum]

类似与“.balign”,但filler是16位的值

.byte expression [,expression]

为每个表达式分配一个字节,每个表达式的值赋值到分配的字节中。

.comm symbol, length

在当前位置分配一块未初始化的内存,名字为“symbol”,大小为“Length”。如果一个模块中定义了多于一个的名字相同的符号,则合并他们。如果他们的大小不一样,则使用最大的那个。

在ELF系统中,第三层优化参数将指定对齐。在HPPA系统中,这个伪指令的语法是:

“symbol .comm, length”。

.data subsection

什么一个数据段的子段,subsection是一个绝对值,它的默认值为0。

.def name

一个debugging信息块的开始,name是标签符号名,将被插入到COFF格式的二进制文件中。这个信息块结束于一个“endef”伪指令。可以参考“.dim”“.scl”“.tag”“.val”“.type”“.size”。

.desc symbol, value

给一个符号赋值。这个值必须是一个绝对值的表达式。这个伪操作不为COFF格式输出。

.dim

这个伪指令只能使用在“.def”和“.endef”对之间。编译器用它使符号表(symbol table)包含辅助信息。这个伪指令只在COFF的二进制格式中有效。

.double value [,value…]

在当前位置的内存中存储一个或多个浮点数。浮点数的表达方式,大小和范围,各个平台各不相同。可参考“.float”。

.eject

插入一个分页符。

.else

参考“.if”。

.endef

参考“.def”。

.endif

参考“.if”。

.equ symbol, value

为符号赋值,这个值可以是绝对值也可以是相对值。“.equ”可以对一个符号使用多次,使用一次,则改变一个符号的值。在HPPA系统上,这个伪操作的语法是“symbol .equ value”。

这个伪操作和“.set”伪操作相同。可参考“.equiv”。

.equiv symbol, value

这个伪操作类似与“.equ”。唯一不同的地方就是如果对一个已经定义的符号做操作则发出一个错误信息。

.err

这个伪指令产生一个错误,如果使用-Z选项则禁止这类信息。它一般用于条件代码中指定一个错误。下面这个例子如果没有定义BLACKLINE符号则发出一个错误:

.ifndef BLACKLINE

.err

.endif

.fill repeat, size, value

填充一段内存,这段内存的内容重复填充为value,每个位置填充size字节数,这段内存有repeat块连续的同样内容的填充区域。如果size大于8,则强制为8。

.float value [,value…]

同“.double”伪指令。

.global symbol

这个symbol,必须已经定义,这个伪操作将这个symbol作为全局符号暴露给连接器(linker),这个符号可以是定义的一个独立的模块。在HPPA系统上也可以使用作用相同的“.EXPORT”伪指令。

.globl

同“.global”

.hword value

在当前位置存储一个16位的数。和“.short”,“.word”相同。这些伪操作和平台相关的。

.if expression

条件编译伪指令,expression表达式的值非0,则编译下面的代码。条件编译的代码在“.endif”终止。“.else”伪指令下面的代码在expression表达式的值为false时编译。“.ifdef”,“ifndef”和“.ifnotdef”测试符号是否已经定义。

.ifdef symbol

条件编译伪指令,符号如果已经定义则为真。

.ifndef symbol

条件编译伪指令,符号如果没有定义则为真。

.ifnotdef symbol

条件编译伪指令,符号如果没有定义则为真。

.include “filename”

插入指定文件名的文件到当前位置并且编译, -I选项指定搜索的目录。

.int value [,value…]

在当前位置存储一个整数。字节数和字节顺序取决与不同的平台。

.irp tag,str[,str…]

位于“.irp”和“.endr”之间的代码将根据list中的值各执行一遍。值代替跟在反斜线后面的tag。例子

.irp tag,esp,ebp.eax

subl $1,%/tag

.endr

相同于:

subl $1,%esp

subl $1,%ebp

subl $1,%eax

可以参考“.macro”,“.rept”和“.irpc”伪指令。

.irpc charlist

GCC的编译和安装 很好的资料的更多相关文章

  1. windows下编译和安装boost库

    boost是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库. 获取方式 boost提供源码形式的安装包,可以从boost官方网站下载,目前最新版本是1.59.0. 本机上正好有boos ...

  2. 在centos6.6中mysql5.5的编译、安装、配置

    今天根据需求要在centos6.6上编译安装mysql5.5,因为以前编译安装过感觉很简单,但是今天还是出现了点小问题,所以把过安装过程总结了一下: 好像从mysql5.5开始编译安装mysql需要用 ...

  3. redis编译和安装出现错误

    redis编译到时候出现错误,记录一下原因 1.下载redis,https://redis.io/download ,一般选择稳定版本,稳定版的版本号是偶数,当前最新版本是5.0.4,Linux可直接 ...

  4. nginx学习(1):编译、安装、启动

    一.下载 从官网http://nginx.org/en/download.html 下载稳定版(目前最新稳定版是1.6.2) 二.解压 tar zxf nginx-1.6.2.tar.gzcd ngi ...

  5. 在Linux CentOS上编译并安装Clang 3.5.0

    编译CoreCLR需要Clang 3.5,而CentOS上安装的是Clang 3.4.2(yum repos中最新版也是这个),只能自己手工编译LLVM的源代码进行安装. (注:CentOS的版本是6 ...

  6. [vim配置]windows下在vim中使用gcc/g++编译调试c/cpp文件

    在Linux里面混了一个多月,vim编程用得甚爽.无奈前天将Linux里面的编程文件夹误删,而技术不精无法找回,悲痛欲绝.再者,无限怀念windows里面的游戏,并觉得现在在Linux里面也学不到什么 ...

  7. Linux中编译、安装nginx

    Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP 代理服务器. Nginx 是由Igor Sysoev为俄罗斯访问 ...

  8. Apache编译与安装 RedHat enterprises 6.2

    引自:http://blog.chinaunix.net/uid-26881541-id-3336614.html http://apr.apache.org/download.cgi 命令: yum ...

  9. Linux 下编译、安装、配置 QT

    转自Linux 下编译.安装.配置 QT 注意:编译安装耗时费力,且很容易出错,要不断调整编译参数,不推荐使用,否则这将会是一个纠结痛苦的过程. 打算做嵌入式图像处理,计划方案嵌入式Linux+Ope ...

随机推荐

  1. Angularjs总结(四)$on、$emit和$broadcast的使用

    开发中有时候会需要控制器之间的传值操作:下面几个操作可以达到所需, 注:无平级之间的操作 $emit只能向父 controller传递event与data$broadcast只能向子 controll ...

  2. ios 将状态栏改为白色方法!

    1在Info.plist中设置UIViewControllerBasedStatusBarAppearance 为NO2 在需要改变状态栏颜色的ViewController中在ViewDidLoad方 ...

  3. Python:列表

    #!/usr/bin/python3 #列表 是可变的,可修改的 listDemo = ["one","two","three"," ...

  4. javascript 中的数据驱动页面模式

    前段时间一直在想前端MVC的意义.这个话题仁者见仁,但是MVC的使用方法给我提了一个管理数据的有意思的想法--数据管理和数据驱动页面.我们以前的思路一直是事件驱动页面,事件驱动页面合乎逻辑而且节约代码 ...

  5. jquery中mouseout和mouseleave 事件的区别

    今天用jQuery写了一个选项卡的效果,用mouseout事件控制了鼠标的移出,结果发现在移出时div会发生闪动,于是网上各种查资料觉得用mouseleave更合适一些,

  6. Kafka源码分析-序列2 -Producer

    在上一篇,我们从使用方式和策略上,对消息队列做了一个宏观描述.从本篇开始,我们将深入到源码内部,仔细分析Kafka到底是如何实现一个分布式消息队列.我们的分析将从Producer端开始. 从Kafka ...

  7. CentOS如何查看端口是被哪个应用/进程占用

    有时启动应用时会发现端口已经被占用,或者是感觉有些端口自己没有使用却发现是打开的.这时我们希望知道是哪个应用/进程在使用该端口. CentOS下可以用netstat或者lsof查看,Windows下也 ...

  8. 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader

    20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...

  9. "git add -A" is equivalent to "git add .; git add -u".

    git add -A stages All git add . stages new and modified, without deleted git add -u stages modified ...

  10. (三大框架SSH)面试题锦集

    http://www.cnblogs.com/dieyf/p/4109233.html