zx_wing 发表于 2008-09-01 17:03

原帖由 albcamus 于 2008-9-1 16:48 发表 http://linux.chinaunix.net/bbs/images/common/back.gif



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

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

albcamus 发表于 2008-09-01 17:13

回复 #11 zx_wing 的帖子

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

zx_wing 发表于 2008-09-01 17:21

原帖由 albcamus 于 2008-9-1 17:13 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
能贴一份glibc的printf函数的反汇编代码出来吗? 我现在手里没有Linux
我也没有,你直接看printk的代码就好了。
不过我不明白为什么要看反汇编,我估计你什么地方想叉了,我用伪代码给你描述一下就好了,看汇编反而看不出东西

printf(char *fmt, arg ...)
{
   int num;
   void *base_addr;      
   int param1, param2, param3;   

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

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

albcamus 发表于 2008-09-01 22:02

原帖由 zx_wing 于 2008-9-1 17:21 发表 http://linux.chinaunix.net/bbs/images/common/back.gif

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

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

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

mik 发表于 2008-09-01 22:17

原帖由 albcamus 于 2008-9-1 17:13 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
能贴一份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 参数中格式来确定有多少个参数。
页: 1 [2]
查看完整版本: 请教mik版主:考虑IA32的ABI,像printf这样的带有可变数目参数的函数