在阅读Linux内核源代码的时候,发现start_kernel函数定义的最前面是一个asmlinkage.虽知它是
GNUC的扩展,但并不知其意.所以决定对其做一些研究.
i386的linkage.h里有这样的宏定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
CPP_ASMLINKAGE我们暂时不管,只看asmlinkage,它的主要起作用的部分是__attribute__,它在内核
代码里随外可见,我想应该是对GNU编译器的一种指示操作.
在说明__attribute__((regparm(0))用处之前,我们先来看看程序在调用时的参数传递.
不同的硬件平台在默认情况下,参数调用时的参数传递机制是不一样的.如MIPS,SH4等精简指令处理器在
进行子程序调用时先从寄存器里取得前几个参数,至于是几个视硬件平台而定.如SH4默认就是使用
r4,r5,r6,r7作为前四个整参数的传递寄存器,同时用fr4~fr11传递前四个浮点参数,其他参数都压入栈.当
然关于SH4的参数传递还有更多的细节,这里就不多说.而在i386平台上,函数的调用是基于栈的,也就是说,默
认情况下,编译器在进行
函数编译的时候会从栈里取得函数体需要使用的参数,而不是寄存器.
然而,参数直接从寄存器里取而不是从栈里取,前者相对来说速度要快,所以在linkage.h里也有这样的定
义:
#define fastcall __attribute__((regparm(3)))
意思是,最多可以使用3个寄存器(或许是eax,edx,ecx)来传送前3个参数,其他参数则压入栈中,那么
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
的意思就是使用0个寄存器来进行参数传递,顾名思义它是想使得调用这个函数时的所有参数都压入栈中,
相
对于fastcall的使用方式当然是要慢一些了.
阅读(2189) | 评论(1) | 转发(0) |