文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>反汇编查看gcc的行为

反汇编查看gcc的行为

时间:2010-07-23  来源:wwwzyf

那天遇到了一个问题,王聪学长建议使用反汇编查看GCC的行为,上网看了看这方面的知识,毕竟自己汇编很菜,
就找到了了这样一篇文章,发现竟然是小组以前的文章,可是小组以前的网站www.xiyoulinux.cn这个域名不能
用了,所以保存下这篇文章,顺便推介下我们西邮linux兴趣小组的最新域名:www.xiyoulinux.org 。欢迎大
家访问,由于是新建设的网站,瑕疵之处在所难免,所以请大家给出建议,好了,扯远了。。来看我转载的这篇文章吧:
int i = 3;

printf(”%d\n”, i++ * ++i + i– * –i);

在吉林大学的视频c教程中, 上式值为18.她的解法是前缀优先于后缀,所以就是3 * 4 + 3 * 2。在gcc中得到的结果是25。

这种行为是标准未定义的。

可以通过反汇编来查看gcc的行为。如下,我们看看调用printf之前gcc是如何操作i。

80483b5: c7 45 f8 03 00 00 00 movl $0×3,0xfffffff8(%ebp)

给i赋值3。

80483bc: 83 45 f8 01 addl $0×1,0xfffffff8(%ebp)

加1。i==4

80483c0: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80483c3: 89 c2 mov %eax,%edx
80483c5: 0f af 55 f8 imul 0xfffffff8(%ebp),%edx

计算此时的i*i。 16

80483c9: 83 6d f8 01 subl $0×1,0xfffffff8(%ebp)

把i减1,即i==3。

80483cd: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
80483d0: 0f af 45 f8 imul 0xfffffff8(%ebp),%eax

计算i*i,即9。

80483d4: 8d 04 02 lea (%edx,%eax,1),%eax

把上面两个乘的结果加起来,放入%eax。

80483d7: 83 45 f8 01 addl $0×1,0xfffffff8(%ebp)
80483db: 83 6d f8 01 subl $0×1,0xfffffff8(%ebp)

把i加1,再减1。

80483df: 89 44 24 04 mov %eax,0×4(%esp)

%eax就是最后结果,即25

80483e3: c7 04 24 d0 84 04 08 movl $0×80484d0,(%esp)
80483ea: e8 c9 fe ff ff call 80482b8 <printf@plt>

另外,如果你把gcc的优化级别调高一些,你会发现结果也是18。
如果你把i类型改成volatile int,结果是24。(3 * 4 + 4 * 3)

这个问题的关键是看编译器怎么处理寄存器和内存之间的关系,已经超出了
标准所规定的范围。实际中这种代码是应该避免的。


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载