免费注册 查看新帖 |

Chinaunix

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

[C] printf参数入栈顺序和编译器相关,还是都是从右至左? [复制链接]

论坛徽章:
0
81 [报告]
发表于 2007-11-03 11:23 |只看该作者
很不错的贴子.

论坛徽章:
0
82 [报告]
发表于 2007-11-03 22:29 |只看该作者
4楼,5楼正解
c语言的函数调用都是从右致左,pascal是从左到右

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
83 [报告]
发表于 2007-11-04 18:50 |只看该作者
呵呵,一石激起千层浪!


原帖由 scutan 于 2007-11-3 11:23 发表
很不错的贴子.

论坛徽章:
0
84 [报告]
发表于 2007-11-04 19:14 |只看该作者
原帖由 JohnBull 于 2007-11-1 10:04 发表
C语言都是从右向左入栈的。
Pascal语言是从左到右。

只能说常规是这样子的,但是从右往左还是从左往右入栈 都不是语言规范里强制规定的!

论坛徽章:
0
85 [报告]
发表于 2007-11-06 22:07 |只看该作者

回复 #1 Godbach 的帖子

《c和指针》-- 运行时环境

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
86 [报告]
发表于 2007-11-07 09:56 |只看该作者
原帖由 levinee 于 2007-11-6 22:07 发表
《c和指针》-- 运行时环境


正好有复印的,看一把

论坛徽章:
0
87 [报告]
发表于 2007-11-07 22:20 |只看该作者
对于这个问题,可以在了解调用约定(Calling Convention)概念的基础上检讨下面的叙述。

  • C 或者 C++ 标准只是规定了函数的参数是自动变量,并没有规定函数的参数是在栈内存中还是在寄存器中、如果在栈中的话其存放的先后顺序如何等。这些都属于具体的实现问题。
  • 函数参数的具体实现通常遵从于所采用的调用约定(或称调用协定)。调用约定独立于语言之外(比如多种语言有可能共用同一种调用约定)。
  • 调用约定有多种。编译器可以支持一种或者多种调用约定,在允许的范围内通常允许用户为函数指定某一调用约定。
  • 变长参数函数(简称变参函数)是参数个数可变的函数。变参函数的调用者知道调用时参数的个数和类型,而变参函数本身无从得知(虽然在实现中也可以给函数暗中增加一个额外的参数来传递信息,但这是非标准的做法)。由于变参函数的这个特点,通常依靠调用者和变参函数之间达成某种约定来解决实际参数和参数的类型未知的问题。
  • 为了便于在变参函数中遍历参数列表,变参函数的参数实现一般是按照顺序放在栈内存上。因此,对于只能通过寄存器传递参数的调用约定,通常在实现上还需要有一步向栈内存转换的过程。
  • 有入栈操作就要有相应的出栈操作。而实参个数未知意味着那些需要由函数自己来清理参数栈空间的调用约定无法适用在变参函数上——对于变参函数只能由函数的调用者负责释放参数占用的栈空间。实际上 cdecl 只是用来实现变参函数的一种常见的调用约定(这种调用约定按照从右到左的顺序对函数参数压栈),并不是唯一可行的调用约定。
  • 标准之前的 C 语言支持无固定参数(固定参数是参数列表中出现在 ... 之前的参数)的变参函数。一般在变参函数内访问参数总是从第一个参数开始的。为了便于定位第一个参数,对于变参函数通常采用从右向左的压栈方式,因为这样可以把第一个参数始终放在栈顶的位置。标准 C 或 C++ 要求变参函数至少要存在一个固定的参数,因而总可以通过最后一个固定参数以及与调用者的约定定位非固定参数,所以上面的从右向左的压栈限制就不存在了。
  • C标准库在<stdarg.h>中定义了一些宏(如va_start、va_arg等)用于遍历变参列表,形成了一个标准操作界面,以吸收因参数传递方式(栈或寄存器)、入栈顺序、栈增长方向、内存对齐等因素带来的影响。

论坛徽章:
0
88 [报告]
发表于 2007-11-08 00:51 |只看该作者
原帖由 whyglinux 于 2007-11-7 22:20 发表
对于这个问题,可以在了解调用约定(Calling Convention)概念的基础上检讨下面的叙述。
  • C 或者 C++ 标准只是规定了函数的参数是自动变量,并没有规定函数的参数是在栈内存中还是在寄存器中、如果在栈中的 ...

  • 学习

    论坛徽章:
    0
    89 [报告]
    发表于 2007-11-08 09:49 |只看该作者
    搞不懂,一个函数调用约定的问题,为什么会这么火.
    更搞不懂的是,我自己也上来添一把火

    论坛徽章:
    36
    IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
    90 [报告]
    发表于 2007-11-08 09:54 |只看该作者
    原帖由 zhongfangqing 于 2007-11-8 09:49 发表
    搞不懂,一个函数调用约定的问题,为什么会这么火.
    更搞不懂的是,我自己也上来添一把火


    呵呵,
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

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

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP