免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4732 | 回复: 14
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-01 16:17 |只看该作者 |倒序浏览
请教mik版主:考虑IA32的ABI,像printf这样的带有可变数目参数的函数,怎么知道该从stack上取几个参数?


libc库已经编译好了, 我写个hello程序,调用printf -- 它怎么知道我传了几个参数给它呢? 难道gcc编译 library的时候,是对可变参数函数单独处理的?

谢谢!

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2008-09-01 16:29 |只看该作者
传了几个参数,完全在于调用者的指示;
如果调用者没有任何指示,可变参数函数是不知道调用者使用了几个参数的。
最常用的是在第一个参数上指示。
比如printf("%s:%d"....
根据第一个参数,知道printf还有两个参数。
再比如我们熟悉的open系统调用,可以带两个或者三个参数,这是在第二个参数上指示的。

论坛徽章:
0
3 [报告]
发表于 2008-09-01 16:31 |只看该作者
原帖由 albcamus 于 2008-9-1 16:17 发表
请教mik版主:考虑IA32的ABI,像printf这样的带有可变数目参数的函数,怎么知道该从stack上取几个参数?


libc库已经编译好了, 我写个hello程序,调用printf -- 它怎么知道我传了几个参数给它呢? 难道gcc ...

这和ABI有什么关系呢?
它是从fmt字符串解析需要几个参数,然后从栈上取相应的个数出来,你也可以传多余的参数进去,只不过不会用罢了。
例如
printf("%d\n",1,2,3);
printf("%d,%d,%d\n",1);

论坛徽章:
0
4 [报告]
发表于 2008-09-01 16:38 |只看该作者
原帖由 zx_wing 于 2008-9-1 16:31 发表

这和ABI有什么关系呢?
它是从fmt字符串解析需要几个参数,然后从栈上取相应的个数出来,你也可以传多余的参数进去,只不过不会用罢了。
例如
printf("%d\n",1,2,3);
printf("%d,%d,%d\n",1);


有关系啊, abi只规定从stack传递,但是没规定怎么指示传了几个。  因此, printf的汇编代码, 必须想办法知道自己获得了几个参数。

难道是通过分析fmt得来的?

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
5 [报告]
发表于 2008-09-01 16:43 |只看该作者
原帖由 albcamus 于 2008-9-1 16:38 发表


有关系啊, abi只规定从stack传递,但是没规定怎么指示传了几个。  因此, printf的汇编代码, 必须想办法知道自己获得了几个参数。

难道是通过分析fmt得来的?

没有任何的指示作用的话,可变参数函数是无从得知参数的个数的。
无论是很隐藏的指示,还是很显然的指示,你总是要指示的。
以下是显型指示
func(n,....)
n为参数个数

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2008-09-01 16:46 |只看该作者
机器级不像脚本级,一般来说不会直接说明参数个数。
也就是对于函数func(.....)
机器在函数调用的时候不会传一个参数个数进去(我不敢说机器级表示一定不会,原理上这样的机器是存在的,只是我没有见过)。
而脚本则不同:
比如shell
因为参数字符串里已经潜在的指示了参数的个数

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


有关系啊, abi只规定从stack传递,但是没规定怎么指示传了几个。  因此, printf的汇编代码, 必须想办法知道自己获得了几个参数。

难道是通过分析fmt得来的?

"它是从fmt字符串解析需要几个参数,然后从栈上取相应的个数出来,你也可以传多余的参数进去,只不过不会用罢了。"
前面回复已经说了啊,是从fmt分析得到的,也举了两个参数个数不对的例子。
和ABI有关系的我记得就只有x86_64的系统调用,编译后会用eax传参数个数。printf是没有关系的

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

没有任何的指示作用的话,可变参数函数是无从得知参数的个数的。
无论是很隐藏的指示,还是很显然的指示,你总是要指示的。
以下是显型指示
func(n,....)
n为参数个数



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

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

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
9 [报告]
发表于 2008-09-01 16:53 |只看该作者
原帖由 albcamus 于 2008-9-1 16:48 发表



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

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

呵呵,只能靠调用者的指示。
除非有人造出了一台机器(或者其实编译器也行),在传递参数的时候对参数个数压栈(不知道有没有这样的编译器,不敢乱说,因为原理上可以存在,在看到申明的时候就知道是可变参数,那么遇到可变参数,就多压了个数),函数用这个个数来指定其参数的个数,当然其实这也是调用者的指示

论坛徽章:
0
10 [报告]
发表于 2008-09-01 16:53 |只看该作者
http://bbs.chinaunix.net/viewthr ... 3Ddigest&page=1
看这个帖子,去年的,第二页
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP