`
tempsitegoogle
  • 浏览: 864267 次
文章分类
社区版块
存档分类
最新评论

转载只为记录经典之<asmlinkage>

 
阅读更多


什么是 "asmlinkage"?


相信大家在看linux的source code的时候,都会注意到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_call achieves this feat simply by leaving its

other arguments (which were passed to it in registers) on the stack. All system calls are marked with the asmlinkage tag, so they all look to the stack for arguments. Of

course, in sys_ni_syscall's case, this doesn't make any difference, because sys_ni_syscall doesn't take any arguments, but it's an issue for most other system calls.

看一下/usr/include/asm/linkage.h里面的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数

如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数

还有一种是:

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

asmlinkage long sys_nice(int increment)
"asmlinkage" 是在 i386 system call 实作中相当重要的一个 gcc 标签(tag)。
当 system call handler 要调用相对应的 system call routine 时,便将一般用途缓存器的值 push 到 stack 里,因此 system call routine 就要由 stack 来读取 system call handler 传递的

参数。这就是 asmlinkage 标签的用意。
system call handler 是 assembly code,system call routine(例如:sys_nice)是 C code,当 assembly code 调用 C function,并且是以 stack 方式传参数(parameter)时,在 C

function 的 prototype 前面就要加上 "asmlinkage"。
加上 "asmlinkage" 后,C function 就会由 stack 取参数,而不是从 register 取参数(可能发生在程序代码最佳化后)。
更进一步的说明...
80x86 的 assembly 有 2 种传递参数的方法:
1. register method
2. stack method
Register method 大多使用一般用途(general-purpose)缓存器来传递参数,这种方法的好处是简单且快速。另外一种传递参数的做法是使用 stack(堆栈),assembly code 的模式如下:
push number1
push number2
push number3
call sum
在 'sum' procedure 里取值的方法,最简单的做法是:
pop ax
pop ax
pop bx
pop cx
Stack Top 是放 IP,我们传给 sum procedure 的参数由 stack 的后一个 entry 开始读取。
其它有关 asmlinkage
1. asmlinkage 是一个定义
2. "asmlinkage" 被定义在 /usr/include/linux/linkage.h
3. 如果您看了 linkage.h,会发现 "__attribute__" 这个语法,这是 gcc 用来定义 function attribute 的语法

http://blog.csdn.net/skywalkzf/archive/2009/12/24/5068966.aspx


分享到:
评论

相关推荐

    嵌入式系统/ARM技术中的Linux系统调用例程system_call和参数传递

    Linux定义的系统调用 例程的入口为system_call。下面具体介绍system_call所做的工作。  system_call是用汇编语言编写的,在i386体系中,其前半部分代码如下:  这部分代码的任务是传递系统调用号和参数。  ...

    linux 应用程序中的open 操作与硬件驱动之间的联系浅析

    只不过,在此内核版本中,它的定义是如下这种形式 SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int,mode)。 这个SYSCALL_DEFINE3 就是个宏定义,如果展开,到最后,其实上面这个函数就是 ...

    xitongdiaoyong.zip_unistd.h

    2.修改sys.C文件,添加extern int count 然后定义自己的函数,asmlinkage int sys_mycall(void) 3.修改entry.S和unistd.h文件,为自己定义的函数增加系统调用号。 4.自己写个函数进行系统调用。

    Linux内核中的dup系统调用

     dup系统调用的服务例程为sys_dup函数,定义在fs/fcntl.c中。sys_dup()的代码也许称得上是简单的之一了,但是是这么一个简单的系统调用,却成了linux系统的一个特性:输入/输出重定向。sys_dup()的主要工作是用来...

    Linux内核中的信号机制??信号处理

    当进程被调度时,会调用do_notify_resume()来处理信号队列中的信号。信号处理主要是调用sighand_struct结构中对应的信号处理函数。do_notify_resume()(arch/arm/kernel/signal.c)...  do_signal(&current-&gt;blocked,

    ARM_Linux启动分析.pdf

    以上这些拷贝动作都是以bootsect.S、setup.S以及vmlinux在磁盘上连续存放为前提的,也就是说,我们的bzImage文件或者zImage文件是按照bootsect,setup, vmlinux这样的顺序组织,并存放于始于引导分区的首扇区的连续...

    用户接口实验.ppt

    1、自定义函数 修改:/usr/src/linux-2.4/kernel/sys.c ...asmlinkage int sys_mycall(int x) { printk("This is my syscall!\n"); return x; } 说明:系统调用命名规则是调用函数名加sys_前缀 ······

    ARM Linux 启动过程分析

    我们当前以linux-2.6.19内核版本作为范例来分析,本文中所有的代码,前面都会加上行号以便于和源码进行对照, 例: 在文件init/main.c中: 00478: asmlinkage void init start_kernel(void) 前面的"00478:" 表示478行,...

Global site tag (gtag.js) - Google Analytics