LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 809|回复: 7

一个难度很大的问题!

[复制链接]
发表于 2003-3-13 18:38:57 | 显示全部楼层 |阅读模式
int plus(int b)
{
if (b>3) return b;
int c=1;
b=b+c;
return plus(b);
}

main(void)
{
int a=1;
plus(a);
}

当编译时,假设a的virtual address 是0x10; b的virtual address 是:0x11;c的virtual address 是:0x12;(如果不是这样的话,那么应该如何处理不同模块之间的编址?)

现在,call plus(1),在队栈中要为b and c 分配三次;那么怎样对处在不同空间的a(or b)寻址?

a=1                           -------------------------------virtual address?
b=1                          -------------------------------virtual address?

a=2                          -------------------------------virtual address?
b=1                          -------------------------------virtual address?

a=3                          -------------------------------virtual address?
b=1                          -------------------------------virtual address?


What can compiling program and os perform?
发表于 2003-3-14 02:37:26 | 显示全部楼层
不好意思,难度太高了,我都没有看明白问题是什么?
为什么要在“不同空间”“对a (or b) 寻址”?
你打算要访问其他的 stack frame 吗?
发表于 2003-3-14 06:31:52 | 显示全部楼层
  1. int plus(int b)
  2. {
  3.    int c=1;
  4.    if (b>3) return b;
  5.    b=b+c;
  6.    return plus(b);
  7. }
复制代码

我不知道你这个函数是做什么用的,如果只是简单的相加,
递归的算法是不可取的,完全可以用while语句代替。
还有,你这个程序无输出啊。

就你这个程序来看,好象不需要寻址吧,
函数是通过传值调用, 传值调用是把参数的一份拷贝传给调用函数。

我是菜鸟,这只是我的看法和理解,请高手指点。
发表于 2003-3-14 09:06:32 | 显示全部楼层
没看懂是什么问题.
发表于 2003-3-16 00:17:08 | 显示全部楼层
没有分配三次,a and b在使用的时候各分配一个地址,并不需要预先分配三个地址。
发表于 2003-3-16 01:57:12 | 显示全部楼层

Re: 一个难度很大的问题!

最初由 WanderMan 发布
int plus(int b)
{
if (b>3) return b;
int c=1;
b=b+c;
return plus(b);
}

main(void)
{
int a=1;
plus(a);
}

当编译时,假设a的virtual address 是0x10; b的virtual address 是:0x11;c的virtual address 是:0x12;(如果不是这样的话,那么应该如何处理不同模块之间的编址?)

现在,call plus(1),在队栈中要为b and c 分配三次;那么怎样对处在不同空间的a(or b)寻址?

a=1                           -------------------------------virtual address?
b=1                          -------------------------------virtual address?

a=2                          -------------------------------virtual address?
b=1                          -------------------------------virtual address?

a=3                          -------------------------------virtual address?
b=1                          -------------------------------virtual address?


What can compiling program and os perform?


你这函数有着非常大的问题!!!
plus(int b)
{
  ...
  b = b + c ; // 看!这里竟然改变了参数本身,那参数用来还有什么意义呢?
}


就按照漏洞分析这个东西,下面的栈的内容

1. main 函数一开始,栈先压如变量 a:
栈内容:栈底(1)栈顶

2. 第一次调用 plus,参数压栈,并且压入 plus 内定义的 c,同时又改变了参数 b 本身的值
栈内容:栈底(1 | 2, 1)栈顶

3. 第二次调用 plus,参数压栈,再压入定义的 c,但函数本身又改变了b 的值
栈内容:栈底(1 | 2, 1 | 3, 1)栈顶

4. 第三次调用 plus,同样执行上一步操作
栈内容:栈底(1 | 2, 1 | 3, 1 | 4, 1)栈顶

5. 第三次调用 plus 的返回,b 的值是 4,然后将本次plus 里定义的变量和参数弹出栈
栈内容:栈底(1 | 2, 1 | 3, 1)栈顶

6. 第二次调用 plus 的返回,返回值是直接用第三次返回的结果,所以仍然返回4,然后是出栈
栈内容:栈底(1 | 2, 1)栈顶

7. 第一次调用 plus 的返回,返回值为第二次返回结果:4
栈内容:栈底(1)栈顶

结论:
1. plus 一直返回 4
2. 从上述栈的分析情况,如果知道栈底的地址,其他地址就是可以知道了。不过楼主犯了一个小小的错误,参数是放在栈里面的,所以参数存放的地址应该是递减而不是递增:如果 a 是 0x10,那么 b 就是 0x0F,c 是 0x0E,如此类推。


不知道我这样表达有没有问题,请大家指教。
发表于 2003-3-16 02:00:57 | 显示全部楼层
修正:上述提到的“如果 a 是 0x10,那么 b 就是 0x0F,c 是 0x0E,如此类推”是一个错误,因为忽略了整数占用四个字节,应该改成:“如果 a 是 0x10,那么 b 就是 0x0C,c 是 0x08,如此类推”
发表于 2003-4-23 21:54:42 | 显示全部楼层

WanderMan:可这样理解

在函数中或不同的{}块中,同名变量是不相互影响的,
下面的代码等效你的

代码:

main(void)
{
   int a=1;
   int tmp=a; //tmp 可视为传值调用的临时变量
   {          //push(b)第一次调用
      int b=tmp;//传值
      if(b>3)  retutn;//return b;
      int c=1;
      b=b+c;
      tmp=b;//为下次调用push(b)准备临时变量 tmp=2
      {     //第二次调用push(b)
          int b=tmp;//传值
          if(b>3)  retutn;//return b;
          int c=1;
          b=b+c;
          tmp=b;//tmp=3
          {     //第三次push(b)
              int b=tmp;//传值
              if(b>3)  retutn;//return b;
              int c=1;
              b=b+c;
              //tmp=b;
           }//第三次push() 结束
       }//第二次push()结束
   }//第一次push()结束
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表