linux内核 asmlinkage宏

来源:互联网 发布:sql server 高级查询 编辑:程序博客网 时间:2024/05/09 20:51
asmlinkage是个宏,使用它是为了保持参数在stack中

看一下/usr/include/asm/linkage.h里面的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

其中 __attribute__是关键字,是gcc的C语言扩展。

__attribute__机制是GNU C的一大特色,它可以设置函数属性、变量属性和类型属性等。可以通过它们向编译器提供更多数据,帮助编译器执行优化等。
__attribute__((regparm(0))):告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。
__attribute__((regparm(3))):告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

asmlinkage大都用在系统调用中。有一些情况下是需要明确的告诉编译器,我们是使用stack来传递参数的,比如X86中的系统调用,是先将参数压入stack以后调用sys_*函数的,所以所有的sys_*函数都有asmlinkage来告诉编译器不要使用寄存器来编译,


其他一些预编译:
#if _MSC_VER > 1000
#pragma once         微软编译器版本号 >1000,只编译一次(可能版本号小于1000不支持#pragma)

#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况

    #pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。

   方式一由语言支持所以移植性好,方式二 可以避免名字冲突


C++ 
static char THIS_FILE[] = __FILE__;
__FILE__为预编译器常量,返回当前编译的文件名,还有比较常用的几个预编译器常量,
__LINE__编译器在编译的文件的第几行;
__DATE__返回当前的日期Jul-20-2004;
__TIME__返回当前的时间hh:mm:ss;  

__TIMESTAMP__ 的预定义的编译器宏始终返回时间戳信息在太平洋标准的时间内无论本地时间和CL.EXE 的运行位置在计算机上的时区。
   
__STDC__条件编译,意思是:如果定义了标准C或c++,那么编译这句话后面直到#endif 以前的源代码。
_STDC__cplusplus这两个都是标准宏,_STDC_表示是是否符合标准C
_cplusplus表示是否是C++


如下为宏定义:
#ifdef _DEBUG //如果定义了_DEBUG
#define new DEBUG_NEW //则定义new为DEBUG_NEW
#undef THIS_FILE //反定义,即清除THIS_FILE的宏定义
static char THIS_FILE[] = __FILE__;
#endif //结束宏定义   
__FILE__标准C++推荐编译器实现时预定义的宏

看看Thinking in C++(C++编程思想)
__FILE__是由编译器定义的宏,表示当前文件名。
常用于调试。报告错误时,我们可以方便地知道是哪个文件出错

原创粉丝点击