stdarg(3) variable argument lists 可变参数列表

1. 可变参数列表的实现

GCC 编译器在汇编过程中,调用 C 语言函数传递参数有两种方法:

  1. 通过堆栈
  2. 通过寄存器(默认)

若想通过堆栈传递参数,需在定义 C 函数时在函数前加上宏 asmlinkage

asmlinkage int printk(const char *fmt, ...)

正常来讲,函数原型中具有确定的参数类型和数量,保证了函数调用的准确性。

如果在调用函数时,使用不同类型的不同数量的参数进行调用,参数列表的数量和类型对于被调用函数是未知的。

我们就要想办法确定各个可变参数的类型,找到这些可变参数的地址。

头文件 <stdarg.h> 定义了 va_list 类型和用于逐个通过参数列表的三个宏。

被调用函数必须声明一个 va_list 类型的对象,用 va_list 这个指针指向这个可变参数列表的各个参数。

这个 va_list 对象由 va_start(), va_arg() 和 va_end() 使用。

2. 函数调用时的栈结构

C 函数调用时的栈结构:

栈结构 说明
栈底 高地址(入栈方向为从高地址到低地址)
…… ……
函数返回地址 ……
…… ……
函数最后一个可变参数 入栈顺序为从右向左
…… ……
函数第一个可变参数 调用 va_start 后 ap 指向这里
函数最后一个固定参数 ……
…… ……
函数第一个固定参数 ……
栈顶 低地址

3. 可变参数列表(第一个可变参数)的地址

我们需要一个基准,这个基准就是可变参数前面固定的那些参数中的最后一个,也即可变参数前面那个参数。

然后以此已知类型的参数为基准,来确定后面的可变参数。

先确定第一个可变参数的地址,方法是调用void va_start(va_list ap, last);

这样,基准有了,就是 last 指定的参数,然后由 last 计算 指向当前可变参数的指针 ap

要找到 ap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值