免费注册 查看新帖 |

Chinaunix

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

[C] c语言函数形参的地址关系 [复制链接]

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
11 [报告]
发表于 2015-01-04 17:26 |只看该作者
回复 10# zhaohongjian000


    不明白什么叫“用内存传参数”,怎么理解?

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
12 [报告]
发表于 2015-01-04 17:29 |只看该作者
回复 11# idi0t


    就是把参数放内存里啊。一般就是放在stack上,从右向左。这么做的原因是为了支持可变参数的函数,因为第一个参数的地址是在顶部。

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
13 [报告]
发表于 2015-01-05 09:14 |只看该作者
回复 12# zhaohongjian000


    那为什么说“简单的说,现在还在用内存传参数的,只有32位的x86了”,其它的是怎么传的呢,能否简单说下。

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
14 [报告]
发表于 2015-01-05 11:05 |只看该作者
回复 13# idi0t

放寄存器里。比如用8个寄存器用于参数传递,从左到右依次放到1到8号寄存器中。超过8个参数再使用内存。返回值放到第一个寄存器中。
当返回值尺寸比较大时(比如返回结构体),有的ABI规定由caller分配内存存放返回值,并把地址作为额外参数传递给callee。

有浮点运算部件的情况下,浮点参数一般是单独放在浮点部件的寄存器中的。

总体方法都大体相似,但具体细节非常多。单单调用约定这一块可能就有几十种特殊情况。你可以找个ABI规范看一下,比如AMD64的。


x86(32位)的情况比较复杂,因为在发展早期没有确定一个统一的ABI规范。各个编译器、系统遵循的ABI都可能不一样。而且由于多个编译器在
x86(32位)上都采用栈来传递参数,让很多不明所以的人误认为参数天生就是要通过栈来传递的。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
15 [报告]
发表于 2015-01-05 15:35 |只看该作者
cao627 发表于 2015-01-03 10:34
看到一个视频教程,里面用test2实现了:打印第二个参数和第三个参数的值,依据是形参的地址在内存里紧挨着的 ...

X64,前6个形参在寄存器,你上哪儿找地址?
学一下ABI。

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
16 [报告]
发表于 2015-01-05 15:53 |只看该作者
回复 14# zhaohongjian000


    恩,谢谢解释,没接触过64位的,学习了,突然之前无意中看过别人反汇编arm平台下的程序好像也是用寄存器传的。

论坛徽章:
5
戌狗
日期:2014-06-09 10:29:10酉鸡
日期:2014-12-01 16:05:27处女座
日期:2015-01-07 18:35:262015亚冠之水原三星
日期:2015-06-03 09:26:222015亚冠之布里斯班狮吼
日期:2015-06-15 10:53:54
17 [报告]
发表于 2015-01-05 16:39 |只看该作者
LZ,有结果了吗?我在我的环境下试了一下你的程序,调试如下:
  1. GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7
  2. Copyright (C) 2013 Free Software Foundation, Inc.
  3. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  4. This is free software: you are free to change and redistribute it.
  5. There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
  6. and "show warranty" for details.
  7. This GDB was configured as "x86_64-redhat-linux-gnu".
  8. For bug reporting instructions, please see:
  9. <http://www.gnu.org/software/gdb/bugs/>...
  10. Reading symbols from /root/Project/programing/C/a.out...done.
  11. (gdb) b test2
  12. Breakpoint 1 at 0x4005f3: file func_args.c, line 16.
  13. (gdb) r
  14. Starting program: /root/Project/programing/C/a.out
  15. 100
  16. 200
  17. 300

  18. Breakpoint 1, test2 (s=0x400714 "hello world") at func_args.c:16
  19. 16                p = (int *)&s;
  20. Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7.x86_64
  21. (gdb) n
  22. 17                p++;
  23. (gdb) p p
  24. $1 = (int *) 0x7fffffffdfa8
  25. (gdb) p *(p+8)
  26. $2 = 100
  27. (gdb) p *(p+10)
  28. $3 = 200
  29. (gdb) n
  30. 18                printf("%d\n", *p);
  31. (gdb) p p
  32. $4 = (int *) 0x7fffffffdfac
复制代码
真心没想明白阿
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP