Chinaunix首页 | 论坛 | 博客
  • 博客访问: 952269
  • 博文数量: 113
  • 博客积分: 7235
  • 博客等级: 少将
  • 技术积分: 2101
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-14 11:24
文章分类

全部博文(113)

文章存档

2013年(7)

2012年(5)

2011年(6)

2010年(8)

2009年(15)

2008年(72)

分类: LINUX

2008-07-31 18:01:07

linux i386 kernel中:

 #define fastcall __attribute__((regparm(3)))

 #define asmlinkage __attribute__((regparm(0)))
函数定义前加宏asmlinkage ,表示这些函数通过堆栈而不是通过寄存器传递参数。

     宏asmlinkage定义如下:#define asmlinkage __attribute__((regparm(0))).

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

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

Linux i386+源码中常见宏标识tag的定义

这些宏包括 __init、__initdata、__initfunc()、asmlinkage、ENTRY()、FASTCALL()等等。它们的定义主要位于 Include\linux\linkage.h和 include\asm-i386\Init.h以及其他一些.h文件中。

1) __init位置:include\asm-i386\Init.h

定义:#define __init __attribute__ ((__section__ (".text.init")))

注释:这个标志符和函数声明放在一起,表示gcc编译器在编译的时候需要把这个函数放.text.init section中,而这个section在内核完成初始化之后,会被释放掉。

举例:asmlinkage void __init start_kernel(void){...}

2) __initdata

位置:include\asm-i386\Init.h

定义:#define __initdata __attribute__ ((__section__ (".data.init")))

注释:这个标志符和变量声明放在一起,表示gcc编译器在编译的时候需要把这个变量放在.data.init section中,而这个section在内核完成初始化之后,会被释放掉。

举例:static struct kernel_param raw_params[] __initdata = {....}

3) __initfunc()

位置:include\asm-i386\Init.h

定义: #define __initfunc(__arginit) \

__arginit __init; \

__arginit

注释: 这个宏用来定义一个 __init 函数。

举例: __initfunc(void mem_init(unsigned long start_mem, unsigned long e

nd_mem)) {....}

4) asmlinkage

位置:Include\linux\linkage.h

定义:#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

注释:这个标志符和函数声明放在一起,告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。

举例:asmlinkage void __init start_kernel(void){...}

5) ENTRY()

位置:Include\linux\linkage.h

定义: #define ENTRY(name) \

.globl SYMBOL_NAME(name); \

ALIGN; \

SYMBOL_NAME_LABEL(name)

注释: 将name声明为全局,对齐,并定义为标号。

举例: ENTRY(swapper_pg_dir)

.long 0x00102007

.fill __USER_PGD_PTRS-1,4,0

/* default: 767 entries */

.long 0x00102007

/* default: 255 entries */

.fill __KERNEL_PGD_PTRS-1,4,0

等价于

.globl swapper_pg_dir

.align 16,0x90

/* if i486+ */

swapper_pg_dir:

.long 0x00102007

.fill __USER_PGD_PTRS-1,4,0

/* default: 767 entries */

.long 0x00102007

/* default: 255 entries */

.fill __KERNEL_PGD_PTRS-1,4,0

6) FASTCALL()

位置:Include\linux\kernel.h

定义:#define FASTCALL(x) x __attribute__((regparm(3)))

注释:这个标志符和函数声明放在一起,带regparm(3)的属性声明告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

举例:extern void FASTCALL(__switch_to(struct task_struct *prev, struct t

ask_struct *next));

这个例子中,prev将通过eax,next通过edx传递

阅读(2189) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

niutao.linux2008-08-22 16:01:02

#define __exit __attribute__ ((__section__(".exit.text"))) __cold

niutao.linux2008-08-22 16:00:34

define __exit __attribute__ ((__section__(".exit.text"))) __cold

lizeliang.linux2008-08-22 15:19:27

对应__init 的__exit不知是否和__init的定义一样呢。 这篇不错:-)

niutao.linux2008-08-20 11:38:51

这里是gcc里会asmlinkage的解释: The asmlinkage tag is one other thing that we should observe about this simple function. This is a #define for some gcc magic that tells the compiler that the function should not expect to find any of its arguments in registers (a common optimization), but only on the CPU's stack. Recall our earlier assertion that system_call consumes its first argument, the system call number, and allows up to four more arguments that are passed along to the real system call. system