免费注册 查看新帖 |

Chinaunix

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

[C] c语言的函数参数是在ebp+4,+8这样的位置,但我验证失败了? [复制链接]

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-09-27 11:21 |只看该作者 |倒序浏览
我在ubuntu1604的64位上面,用gcc编译一个小程序:
  1. #include<stdio.h>
  2. int main(int argc,char*argv[])
  3. {
  4.   printf("hello\n");
  5.   return argc;
  6. }
复制代码
用gcc来编译,带调试信息:
  1. gcc -g my.c
复制代码
然后gdb来调试它,带2个参数,所以argc是3
  1. gdb --args my 01 02

  2. (gdb) b main
  3. Breakpoint 1 at 0x400535: file ret.c, line 5.
  4. (gdb) r
  5. Starting program: /home/a/cpp/my 01 02

  6. Breakpoint 1, main (argc=3, argv=0x7fffffffde98) at ret.c:5
  7. 5          printf("hello\n");
  8. (gdb) n
  9. hello
  10. 6          return argc;
  11. (gdb) x $rbp
  12. 0x7fffffffddb0:        0x00400550
  13. (gdb) x $rbp+4
  14. 0x7fffffffddb4:        0x00000000
  15. (gdb) x $rbp+8
  16. 0x7fffffffddb8:        0xf7a2e830
复制代码

上面几个字节里面都没有体现出"3"这个信息。是不是我的用法有问题,还是理解的不对?

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2016-09-27 12:25 |只看该作者
回复 1# cdsfiui

main() 本身在 C/C++ 程序中是非常特殊的,另外换个函数看吧。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
3 [报告]
发表于 2016-09-27 16:39 |只看该作者
MMMIX 发表于 2016-09-27 12:25
回复 1# cdsfiui

main() 本身在 C/C++ 程序中是非常特殊的,另外换个函数看吧。

我试了一下,别的函数还真的是可以。为什么对于main不行呢,在main里面,参数argc,argv在ebp的什么偏移地址?
谢谢。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2016-09-27 17:19 |只看该作者
本帖最后由 MMMIX 于 2016-09-27 17:39 编辑

回复 3# cdsfiui

为什么对于main不行呢,

main() 特殊的地方在于它是从 CRT (C runtime)调过来的,而不同的 OS/compiler 有不同的 CRT 实现,对于函数调用之类也有不同约定(称为 ABI)。

例如在 x86-64 Linux ELF 的情况下,main() 的前两个参数就是在 rdi, rsi 中,和其他函数并没有什么区别。

在main里面,参数argc,argv在ebp的什么偏移地址?

不清楚你系统上的情况,从可执行程序的(真正)入口,例如 Linux ELF 下的 _start,开始跟一下吧。

论坛徽章:
2
2015年迎新春徽章
日期:2015-03-04 10:16:532015元宵节徽章
日期:2015-03-06 15:53:22
5 [报告]
发表于 2016-09-27 17:38 |只看该作者

嗯,在64位ubuntu上我试了一下,确实像你所说的,是在rdi,rsi里面。

但是我在32位ubuntu上也测试了一下,对于main函数而言,还是不能用ebp+8来访问到argc,别的函数参数都是ebp+8开始的。
这个32位main函数有什么特殊性吗,它的argc,argv放在ebp的什么偏移位置?

谢谢。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
6 [报告]
发表于 2016-09-27 18:10 |只看该作者
回复 5# cdsfiui

但是我在32位ubuntu上也测试了一下,对于main函数而言,还是不能用ebp+8来访问到argc,别的函数参数都是ebp+8开始的。
这个32位main函数有什么特殊性吗,它的argc,argv放在ebp的什么偏移位置?

手边没有32位的环境用来测试,不过里面的 main() 应该没什么特殊的。对于它的调用也是通过 __libc_start_main 来完成的,而这个函数是用 C 实现的,所以对其的调用也应遵循当前 ABI。

你再从栈顶顺序检查一遍,应该就能找到 main 的参数。

x86 调用约定的描述可以参考 https://en.wikipedia.org/wiki/X86_calling_conventions
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP