代码中看见:#define _fastcall

所以了解下fastcall

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Linux内核中的fastcall和asmlinkage宏

[日期:2012-12-31] 来源:Linux社区  作者:ce123 [字体:  ]
 

Linux内核版本:2.6.14

在linux内核中我们都会经常见到FASTCALL和armlinkage,它们各有什么不同呢?下面我们来具体分析一下。

在标准C系中函数的形参在实际传入参数的时候会涉及到参数存放的问题,那么这些参数存放在哪里呢?对x86比较了解的话,应该知道这些函数参数和函数内部局部变量一起被分配到了函数的局部堆栈中。linux操作系统支持多种CPU架构,比如x86、ppc和arm等,在不同的处理器结构上不能保证都是通过 局部栈传递参数的。ARM对函数调用过程中的传参定义了一套规则,即 ATPCS,规则中明确指出ARM中R0-R4都是作为通用寄存器使用,在函数调用时处理器从R0-R4中获取参数,在函数返回时再 将需要返回的参数一次存到R0-R4中,也就是说可以将函数参数直接存放在寄存器中,所以为了严格区别函数参数的存放位置,引入了两个标记,即 asmlinkage和FASTCALL,前者表示将函数参数存放在局部栈中,后者则是通知编译器将函数参数用寄存器保存起来。

1.x86平台

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
#define FASTCALL(x) x __attribute__((regparm(3)))
#define fastcall __attribute__((regparm(3)))

函数定义前加宏asmlinkage,表示这些函数通过堆栈而不是通过寄存器传递参数。gcc编译器在汇编过程中调用c语言函数时传递参数有两种方法:一种是通过堆栈,另一种是通过寄存器。缺省时采用寄存器,假如你要在你的汇编过程中调用c语言函数,并且想通过堆栈传递参数,你定义的c函数时要在函数前加上宏asmlinkage。

其中 __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来告诉编译器不要使用寄存器来编译。

2.arm平台

对于arm处理器的<asm/linkage.h>,没有定义FASTCALL和armlinkage,所以没有意义(对于ARM平台来说,要符合ATPCS过程调用标准,即通过寄存器传递的。ARM中R0-R4用于存放传入参数,所有函数的参数不应该大于5个,如果超过5个,多余的参数被存放到局部栈中。)。

#ifndef FASTCALL
#define FASTCALL(x) x
#define fastcall
#endif

#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif

3.CPP_ASMLINKAGE

#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
#define CPP_ASMLINKAGE
#endif

extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。

  (1) 被extern "C"限定的函数或变量是extern类型的extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。

  (2) 被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。

Linux内核中的fastcall和asmlinkage宏的更多相关文章

  1. Linux 内核中 likely 与 unlikely 的宏定义解析

    在 2.6 内核中,随处能够见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么差别? 首先要明白: if(likely(value)) 等价于 if(valu ...

  2. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析【转】

    转自:http://blog.csdn.net/hzn407487204/article/details/7995041 在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设 ...

  3. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析

    ref from : http://blog.csdn.net/zhuxiaoping54532/article/details/49680537 main 在驱动程序里, ioctl() 函数上传送 ...

  4. Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法

    #define _IO(type,nr)        _IOC(_IOC_NONE,(type),(nr),0) #define _IOR(type,nr,size)    _IOC(_IOC_RE ...

  5. (十)Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  6. Linux内核中的常用宏container_of

    Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址. Containe ...

  7. Linux内核中的常用宏container_of其实很简单【转】

    转自:http://blog.csdn.net/npy_lp/article/details/7010752 开发平台:Ubuntu11.04 编 译器:gcc version 4.5.2 (Ubun ...

  8. linux内核中的宏ffs(x)

    linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...

  9. 剖析linux内核中的宏---------container_of

    #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); ...

随机推荐

  1. 20135316王剑桥 linux第二周课实验笔记

    Linux中命令格式为: command [options选项] [arguments参数] //中括号代表是可选的,即有些命令不需要选项也不需要参数 ls或ls .显示是当前目录的内容,这里“.”就 ...

  2. 【java基础】IOC介绍及其简单实现

    控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. 控制反转一般分为两种类型,依赖注入 ...

  3. grootJs的vm结构

    按看这段代码生成的vm groot.view("myview", function (vm, ve) { vm.say = "hello word!"; }) ...

  4. linux下安装openssh-server

    csdn博文地址:linux下安装openssh-server   点击进入 系统是ubuntu14.04,系统默认安装了openssh-client,但没有安装openssh-server,需要手动 ...

  5. 如何添加win10命令提示符字体,美化显示效果

    如图,win10命令提示符的字体真让人难受的要死,难道就不能改成好看一点的吗?笔者开始了停不下来的百度和Google 在查找了大量零碎或者过时的资料后,终于找到了一篇看起来还是很靠谱的文章: Quic ...

  6. sql脚本比较大,sqlserver 无法导入,就用cmd命令执行

    osql简单用法:用来将本地脚本执行,适合sql脚本比较大点的情况,执行起来比较方便 1 osql -S serverIP -U sa -P 123 -i C:\script.sql serverIP ...

  7. java多线程-CyclicBarrier

    介绍 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBa ...

  8. 阿里面试回来,想和Java程序员谈一谈(转载)

    引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容 ...

  9. Maven-在eclipse中安装Maven插件

    装IDE Plugins的方法有很多. 其一:在线安装 通过Help-->Install New Software的方式,输入HTTP地址来安装,简单易操作,但是也优缺点,就是下载速度慢,或者有 ...

  10. BZOJ-3524 Couriers 可持久化线段树

    可持久化线段树,其实就是类主席树了.. 3524: [Poi2014]Couriers Time Limit: 20 Sec Memory Limit: 128 MB Submit: 1124 Sol ...