Chinaunix首页 | 论坛 | 博客
  • 博客访问: 427301
  • 博文数量: 131
  • 博客积分: 1990
  • 博客等级: 上尉
  • 技术积分: 996
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-24 12:15
文章分类
文章存档

2011年(4)

2010年(19)

2009年(108)

我的朋友

分类: 嵌入式

2009-12-07 09:42:51

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传递

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