当前位置:  技术问答>linux和unix

一个在Unix下的一个C程序??????????????????

    来源: 互联网  发布时间:2015-12-09

    本文导语:  请先看看下面的原程序: #include  #include  #include  using namespace std; //static void f1(int , int ,int); static void f1(int *, int , int); static void f2(void); static jmp_buf jmpbuffer; int main(void) { int count; volatile int sum; register ...

请先看看下面的原程序:
#include 
#include 
#include 

using namespace std;

//static void f1(int , int ,int);
static void f1(int *, int , int);
static void f2(void);
static jmp_buf jmpbuffer;

int main(void)
{
int count;
volatile int sum;
register int val;

count = 2; val = 3; sum = 4;
if(setjmp(jmpbuffer)!=0)
{
printf("after longjmp : count = %d,val = %d, sum = %d n", count,val,sum);
exit(0);
}

count = 96; val = 97; sum = 99;
f1(&count,val,sum);
//f1(count,val,sum);
}
/*
static void f1(int  i, int j ,int k)
{
printf("    int f1(): count = %d,val = %d , sum = %dn",i, j , k);
f2();
}
*/

static void f1(int * i, int j ,int k)
{
printf("    int f1(): count = %d,val = %d , sum = %dn",*i, j , k);
f2();
}


static void f2(void)
{
longjmp(jmpbuffer,1);
}

以下是我的问题:
     1. 当我用xlC -o temjmp temjmp.C时,输出的结果为:
              int f1(): count = 96,val = 97 , sum = 99
              after longjmp : count = 96,val = 97, sum = 99
        当我用xlC -O temjmp temjmp.C时(也就是把编译器优化打开),输出的结果为:
                  int f1(): count = 96,val = 97 , sum = 99
                  after longjmp : count = 96,val = 3, sum = 99
         不知道为什么?
     2. 当我把sum的volatile去掉后,sum也变了.但是,我要问的是为什么count不会变.而在去掉了指针属性后会变.

    请哪位高手给予帮忙!!!!!!!!!!!!!!!!!!!!!!!!!

|
应该是优化惹的祸,我记得以前看过资料,优化时慎用register变量,优化会自动使用register,而volatile变量一般不会被优化。不妨研究一下《代码大全》关于优化的部分。

你也可以分析一下汇编代码,比如
printf("after longjmp : count = %d,val = %d, sum = %d n", count,val,sum);
一句的汇编在优化后和优化前分别是下面两段,可以看出还是有区别的,有时间可以仔细查看一下参数的区别。
我试过,你这段代码在linux下也可以重现,不妨到linux下研究,用objdump可以得到汇编代码:
g++ -O -o test test.cpp
objdump -D -S test > test.S


80486da:       8b 45 f0                mov    0xfffffff0(%ebp),%eax
 80486dd:       50                      push   %eax
 80486de:       6a 03                   push   $0x3
 80486e0:       ff 75 ec                pushl  0xffffffec(%ebp)
 80486e3:       68 e8 88 04 08          push   $0x80488e8
 80486e8:       e8 bf fe ff ff          call   80485ac 


 80486f7:       8b 45 f0                mov    0xfffffff0(%ebp),%eax
 80486fa:       50                      push   %eax
 80486fb:       ff 75 ec                pushl  0xffffffec(%ebp)
 80486fe:       ff 35 e0 9b 04 08       pushl  0x8049be0
 8048704:       68 28 89 04 08          push   $0x8048928
 8048709:       e8 9e fe ff ff          call   80485ac 

|
真的是优化的问题。看看没优化的code:
0x08048437 :   movl   $0x2,0xfffffff0(%ebp)    # count = 2
0x0804843e :   movl   $0x3,0xffffffe8(%ebp)    # val =3
0x08048445 :   movl   $0x4,0xffffffec(%ebp)    # sum =4
0x0804844c :   movl   $0x80497e0,(%esp)
0x08048453 :   call   0x8048350     # setjmp()
0x08048458 :   test   %eax,%eax
0x0804845a :   je     0x8048489      # if() 判断
0x0804845c :   mov    0xffffffec(%ebp),%eax
0x0804845f :   mov    %eax,0xc(%esp)
0x08048463 :   mov    0xffffffe8(%ebp),%eax
0x08048466 :   mov    %eax,0x8(%esp)
0x0804846a :   mov    0xfffffff0(%ebp),%eax
0x0804846d :   mov    %eax,0x4(%esp)
0x08048471 :   movl   $0x8048640,(%esp)
0x08048478 :   call   0x8048330 

优化后的code:
0x08048436 :   movl   $0x2,0xffffffec(%ebp)    # count = 2
0x0804843d :   movl   $0x4,0xfffffff0(%ebp)    # sum =4
0x08048444 :   movl   $0x80497e0,(%esp)
0x0804844b :   call   0x8048350 
0x08048450 :   test   %eax,%eax
0x08048452 :   je     0x8048482 
0x08048454 :   mov    0xfffffff0(%ebp),%eax
0x08048457 :   mov    %eax,0xc(%esp)
0x0804845b :   movl   $0x3,0x8(%esp)            # val的地址被优化掉了直接用常数替换。因为count传给f1用的是指针,所有没有优化掉。
0x08048463 :   mov    0xffffffec(%ebp),%eax
0x08048466 :   mov    %eax,0x4(%esp)
0x0804846a :   movl   $0x8048640,(%esp)
0x08048471 :   call   0x8048330 
。。。。
0x08048490 :  mov    0xfffffff0(%ebp),%eax
0x08048493 :  mov    %eax,0x8(%esp)
0x08048497 :  movl   $0x61,0x4(%esp)          # 传给f1的val也用常量代替
0x0804849f :  lea    0xffffffec(%ebp),%eax
0x080484a2 :  mov    %eax,(%esp)
0x080484a5 :  call   0x80484b7 


最终解释是val的地址空间被gcc给优化掉了,都用常数替代,所有jump来jump去就出问题了。

    
 
 

您可能感兴趣的文章:

  • 刚刚接触Unix系统和Unix编程。急需Unix下多线程程序设计和网络Socket程序设计方面的资料。
  • 初学unix,想用motif来写unix下的界面程序?哪里有motif的中文资料呀?
  • 新手请教:unix下能用Jbuilder开发吗?或者Jbuilder开发的程序在unix运行?
  • 请问有10年的unix c程序设计经验,在北京、上海、广州、深圳、武汉各会有多少月薪?liunx/unix程序员的月薪比vc/bcb程序员的月薪如何?
  • 谁有可以仿真图形界面的unix仿真程序,或者说说如何安装unix的无盘工作站啊
  • UNIX 程序如何进行程序的内部跟踪调试?
  • 本人要在Unix下编写C程序,不过我从没接触过Unix,怎样办?
  • UNIX下面能否使用类似BCP的程序连接另一台UNIX下面的Sybase数据库进行数据处理
  • unix程序中调用其他程序的问题
  • 对于一个程序员来说,学习linux程序设计和unix编程到底有什么好处
  • 新手求教——windows程序移植到unix下
  • UNIX下的C程序如何调试?
  • 想学linux下程序开发,不知道买哪本书好《UNIX环境高级编程》(中文第一版)还是《UNIX环境高级编程》(英文第二版)
  • 初学unix,想用motif来写unix下的界面程序?哪里有motif的中文资料呀? iis7站长之家
  • Linux/Unix下写C程序是不是就像DOS下写程序一样呀?
  • 要开发unix下的jsp程序,请大家进来讨论一下。
  • 在SCO UNIX下如何安装CC 如何在UNIX下编写C程序(给100分)
  • 请问gdb是不是只能调试gcc编译的程序,在unix下用其它编译器编译的程序是不是不一定能用gdb调试的?
  • 小弟刚刚开始学 Unix/Linux下的C/C++编程,只能用curses写过一些终端图形程序,想问一下,现在unix/linux下都开发一些什么样的应用程序啊?不包括嵌入式开发。
  • UNIX下 wc,grep,和修改文本文件的c程序的源程序那位高人能否提供一份? zero_baby@163.net
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.util.regex类pattern的类成员方法: unix_lines定义及介绍
  • 关于UNIX的历史 : 1973年,K.Thompson和D.M.ritchie,用C改写UNIX。那么,在此之前,UNIX是用什么写的?
  • unix/Linux下c++ boost thread库读写锁介绍
  • 没有unix系统我如何学习unix
  • php将标准字符串格式时间转换成unix时间戳_strtotime
  • unix盘哪里有下载的??哪里有比较好的unix论坛??万分感谢!!!!!!!!!
  • php将unix时间戳转换成字符串时间函数(date)
  • 急!装完unix5.06,再装win2000。重启后不能进unix.
  • unix/Linux下c/c++ pthread库读写锁函数介绍
  • UNIX特急!!!digital unix问题,请专家快来!!!
  • UNIX支持中文否,请推荐UNIX好书
  • SCO UNIX 5.0用软盘启动之后无法启动UNIX
  • 散分!!unix 用户调查!!!你使用哪款unix
  • hp unix 和 sco unix的区别
  • 入门问题,我想向UNIX编程方向发展,单目前不会UNIX,我该如何做
  • 强烈建议将linux/Unix栏目放到“软件开发者”大类里面来。----Unix开发的人助威支持!!!
  • 现在那些unix比较流行?Linux和 Unix有 什么区别?
  • 小问题, Unix 如何建立一个文件 ,unix 文件有后缀名吗
  • 我想学习Unix,请高手给个下载网址,用linux来学习Unix差别大吗?
  • 请问各位unix大虾,哪有免费的unix下载?
  • 学UNIX从SOC UNIX开始好吗?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3