免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2291 | 回复: 8

同样的代码为什么生成不同的结果?【DONE】 [复制链接]

论坛徽章:
0
发表于 2009-12-29 12:39 |显示全部楼层
太崩溃了,竟然一直没发现其实两条指令是完全不一样的....多谢mik老大的提醒....同时咒诅GUN assember的语法...

问题来自之前zx_wing那个帖子(http://bbs.chinaunix.net/viewthr ... p;extra=&page=1),帖子中程序的输出我没有什么疑问。但是当我把代码反汇编之后,就不明白了,我以前以为会生成不同的汇编代码。

源程序:
  t_arr_pointer1.c


  1. #include <stdio.h>

  2. char arr[] = "hello,world!";
  3. void print_arr(void)
  4. {
  5.     printf("arr addr:%p\n",arr);
  6. }
复制代码


  t_arr_pointer2.c

  1. #include <stdio.h>

  2. extern char *arr;
  3. extern void print_arr(void);

  4. int main()
  5. {
  6.     print_arr();
  7.     printf("illusive pointer addr:%p\n",arr);
  8.     //printf("element 1 of arr:%p\n",arr[1]); //会引起段错误
  9. }
复制代码


反汇编的结果:

[ 本帖最后由 iLRainyday 于 2009-12-30 02:03 编辑 ]
2009-12-29 12 38 21.png

论坛徽章:
0
发表于 2009-12-29 13:50 |显示全部楼层
没有问题啊,你的代码不都是arr么?
都是字符arr时你不奇怪,换成相同的数字你就觉得奇怪了?
你看到的反汇编代码属于gcc的第二阶段结果,后来还两个阶段要处理的。

论坛徽章:
0
发表于 2009-12-29 14:32 |显示全部楼层
printf("arr addr:%p\n",0x80495d8);
printf("illusive pointer addr:%p\n",0x80495d8);

这两句输出的结果不一样,难道不奇怪?:shock:
还是我有哪一点没转过来?:em16:

论坛徽章:
0
发表于 2009-12-29 17:15 |显示全部楼层
printf("arr addr:%p\n",0x80495d8);
printf("illusive pointer addr:%p\n",0x80495d8);

这两句输出的结果不一样,难道不奇怪?
还是我有哪一点没转过来?


我似乎知道原因了~~虽然push入的是同样的参数,但是在printf中,应该是做了不同的处理,尽管我现在不知道是在哪里对不同的处理进行的标记,似乎是通过传递参数的方式来标记?(一个是通过%eax,一个是直接push)


printf("arr addr:%p\n",0x80495d8); --> printf("arr addr:%p\n",(char *)0x80495d8);

printf("illusive pointer addr:%p\n",0x80495d8);  --> printf("illusive pointer addr:%p\n",* (*0x80495d8));


[ 本帖最后由 iLRainyday 于 2009-12-29 17:18 编辑 ]

论坛徽章:
0
发表于 2009-12-29 18:25 |显示全部楼层
通过%eax寄存器的是直接寻址,所以可以直接找到字符串
通过%esp+4的是间接寻址,把本来是存储的字符串却当作的新的地址
这样理解就对了吧?

论坛徽章:
0
发表于 2009-12-29 22:13 |显示全部楼层
把 array 当作 pointer 进行 dereference 操作,当然会出错了。
不能理解 pointer 的 dereference 行为,就永远学不好 pointer
char *p;
*p = 'a';
---------------------------------
mov eax, [p]
mov byte ptr [eax], 'a'         <----- dereference
--------------------------------

1.c
char s[] ="xxx";

2.c
extern char *s;        // 用 s 里的值来解引用
*s = 'a';                  


gnu assember 语法令人容易迷惑。

movl 0x80495d8, %eax             ---> mov eax, [0x80495d8]
mov $0x80495d8, %eax            ---> mov eax, 0x80495d8

论坛徽章:
0
发表于 2009-12-29 22:52 |显示全部楼层
膜拜LS 学习了

论坛徽章:
0
发表于 2009-12-29 22:55 |显示全部楼层

回复 #6 mik 的帖子

小站内容有料
界面也太简洁了吧

论坛徽章:
0
发表于 2009-12-30 01:58 |显示全部楼层
movl 0x80495d8, %eax             ---> mov eax, [0x80495d8]
mov $0x80495d8, %eax            ---> mov eax, 0x80495d8


晕死!!!怪不得我一直没反应过来,看惯intel x86的语法,老大要是不说,我到现在还没发现这两条指令竟然不一样....
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP