免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: albcamus
打印 上一主题 下一主题

请教mik版主:考虑IA32的ABI,像printf这样的带有可变数目参数的函数 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-09-01 17:03 |只看该作者
原帖由 albcamus 于 2008-9-1 16:48 发表



如果calling 和called function都是我自己写的, 那么编译器很直接就知道我传递了几个参数给called function, 从而生成汇编代码时很容易;

我现在就是糊涂, gcc编译库函数时, 怎么为它指定参数个数 ...

很奇怪的问题哦。
对于不变参的函数,当然是通过函数原形知道要要取几个参数。
对于变参函数,例如printf,是通过解析提示参数,例如这里的fmt来知道需要几个参数。并且取参数的动作不是编译器完成的,而是printf通过第一个参数的地址为基地址,按参数个数自己从栈上拿出来的

论坛徽章:
0
12 [报告]
发表于 2008-09-01 17:13 |只看该作者

回复 #11 zx_wing 的帖子

能贴一份glibc的printf函数的反汇编代码出来吗? 我现在手里没有Linux

论坛徽章:
0
13 [报告]
发表于 2008-09-01 17:21 |只看该作者
原帖由 albcamus 于 2008-9-1 17:13 发表
能贴一份glibc的printf函数的反汇编代码出来吗? 我现在手里没有Linux

我也没有,你直接看printk的代码就好了。
不过我不明白为什么要看反汇编,我估计你什么地方想叉了,我用伪代码给你描述一下就好了,看汇编反而看不出东西

  1. printf(char *fmt, arg ...)
  2. {
  3.      int num;
  4.      void *base_addr;      
  5.      int param1, param2, param3;   

  6.      num = parse_fmt(fmt); //通过解析字符串,得到参数个数,假设3个参数,并且假设都是int型的参数
  7.    base_addr = (void *)&fmt;

  8.      param1 = *(int *)(base_addr + 4);
  9.      param2 = *(int *)(base_addr + 8);
  10.       param3 = *(int *)(base_addr + 12);
  11.      //这样就得到3个参数了
  12. }

复制代码

论坛徽章:
0
14 [报告]
发表于 2008-09-01 22:02 |只看该作者
原帖由 zx_wing 于 2008-9-1 17:21 发表

我也没有,你直接看printk的代码就好了。
不过我不明白为什么要看反汇编,我估计你什么地方想叉了,我用伪代码给你描述一下就好了,看汇编反而看不出东西

printf(char *fmt, arg ...)
{
     int num;
...


我之前以为,象printf这样的函数应该是gcc生成的汇编代码里头判断参数个数,没想到是C代码判断的

论坛徽章:
0
15 [报告]
发表于 2008-09-01 22:17 |只看该作者
原帖由 albcamus 于 2008-9-1 17:13 发表
能贴一份glibc的printf函数的反汇编代码出来吗? 我现在手里没有Linux


zx_wing 说得不错,看看 printf 的实现
int
printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = vfprintf (stdout, format, arg);
  va_end (arg);

  return done;
}


主要的工作原理,就是获得第二个参数 ..... 的地址值,然后交给 vfprintf 根据格式参数 format 进行进一步处理。
当然,也就是根据 format 参数中格式来确定有多少个参数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP