在linux内核代码中,经常看到asmlinkage限定词,例如:asmlinkage long sys_getpid(void)等,介绍如下:
asmlinkage 的定义(/usr/include/asm/linkage.h里面):
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数
如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,
而是直接放到寄存器里,被调用函数直接从寄存器取参数。
汇编语言的主程序与子程序之间的参数传递方式:转载自:点击打开链接
主程序在调用子程序之前,必须要吧需要子程序处理的原始数据传递给子程序,即为子程序准备入口参数。
常见的的参数传递有4种
1.寄存器法
寄存器法就是将入口参数和出口参数存放在约定的寄存器中。
优点:数据传递书读快、编程较方便、节省内存单元。
缺点:当传递参数过多时候(PS:参数大于4个时,必须使用堆栈法),由于寄存器个数有限,及寄存器的频繁使用,将导致寄存器不足。
适用:参数较少的子程序
2。约定单元法:
约定单元法顾名思义是吧入口参数和出口参数都放在事先约定好的单元中
优点:不占用寄存器、参数个数任意、每个子程序要处理的数据和送出的结构都有独立的存储单元
缺点:但用一定数量的存储单元,增加编程中对变量定义的难度
3.堆栈法
堆栈法是利用堆栈来传递参数的。
优点:参数不占用寄存器,和存储单元。参数存放在公共堆栈区,处理完后客恢复。参数个数一般不限
缺点:由于参数和子程序混杂在一起,存取参数时候必须小心计算它在堆栈中的位置。要注意断点的保存和恢复。
4.地址表法
这种方法是把参数组成的一张参数表放在某个存储区中,然后只要主程序和子程序约定好这个存储区的首地址和存放的内容,在主程序中将参数传递给地址表,在子程序中根据地址表给定的参数就可以完成操作。
c、pascal等采用堆栈法传递参数
当汇编语言编写的程序要调用其他语言编写的子程序代码时候,或为其他语言提供子程序模块时候,汇编语言编写的程序必须遵守对应的高级语言的参数传递规则。改原则在汇编语言和其他语言混编时候必须遵守