中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
关于stack 的一个弱弱的问题,望大虾指点
作者:未知 时间:2005-09-13 19:30 出处:ChinaUnix.net 责编:chinaitpower
              摘要:关于stack 的一个弱弱的问题,望大虾指点

void fun1(int a, int b)
{
   char buf_fun1[4];
   ......
}

void fun2(int a, int b , int c)
{
    char buf_fun2[100];
    ...
}

在调用fun1,fun2时它们的stack分布有一些差异.

fun1:
           stack(低地址)  top of buf_fun1
                           fsp
                           ret
                           a
                           b
            stack(高地址)  ..
fun2:
           stack(低地址)  top of buf_fun2
                           有其他在top of buf_fun2和fsp之间??why????
                           fsp
                           ret
                           a
                           b
                           c
            stack(高地址)  ..

                          

      望大虾指点

 bmw1981bmw 回复于:2004-09-25 09:32:12
急啊

 whyglinux 回复于:2004-09-25 11:03:09
这可能是由于内存对齐的原因。如果不知道关于内存对齐的概念,可以在网上搜索。象你上面的栈中的内存对齐是由编译器决定的,用户没有办法控制。如果你写的程序倚赖于内存对齐特性,则程序不具兼容性。应该避免这样做。

 bmw1981bmw 回复于:2004-09-25 13:23:07
我考虑过这个原因

但是当我把所有的char改成int的时候还是会出现同样的情况

我是i386的机器 32位 应该没有内存对齐的因素了

我看过这两段程序的汇编.当buf的size超过8(字节)时 有多余的stack被分配

望指教!

 whyglinux 回复于:2004-09-25 14:28:50
将 char buf_fun2[100]; 改为 char buf_fun2[128]; 或者 char buf_fun2[256];试试还有多余的 stack 被分配吗?

 THEBEST 回复于:2004-09-25 20:42:20
[quote:d20ac77066="whyglinux"]将 char buf_fun2[100]; 改为 char buf_fun2[128]; 或者 char buf_fun2[256];试试还有多余的 stack 被分配吗[/quote:d20ac77066][quote:d20ac77066]但是当我把所有的char改成int的时候还是会出现同样的情况 [/quote:d20ac77066]改成了解int应该和你说的把char[100]改成char [128]效果一样吧?这种机器上应该sizeof int 是4的呀.why?

 bmw1981bmw 回复于:2004-09-25 21:20:55
而且当栈中数据超过 8字节后 多分配的都是8字节打

困惑ing

怀疑与gcc有关 我用的是 gcc 3.2.2

有没有大虾可以证实啊或者解释啊

 mfmain 回复于:2004-09-25 22:31:45
这个问题我碰见过,通过我的试验,结论是这样的:
栈frame的地址(注意不是大小)缺省是节(16bytes)对齐方式的,这一点在gcc的各个版本之间都是一样的,但是在gcc 3.x的某个版本以后(我不知道是哪个,总之2.95和最新版本是不同的),我猜是为了减小stack overflow带来的危害,把栈中自动变量的空间位置进行了向低字节对齐处理,比如栈frame大小是24字节,有自动变量char s[17],则空间分配如下:
高7字节不用,低17字节为s
而对于2.95是:
高17字节为s,低7字节不用。

 bmw1981bmw 回复于:2004-09-25 22:45:42
但是好像还是不能解释

多分配的8字节

不过感觉,有些道理

实验ing

 bmw1981bmw 回复于:2004-09-25 22:53:55
感觉还是不对

如果您说的成立 那么 int buf[40](或者char buf[160]);

应该不会出现多余的stack

但是还是多了 8 字节的多余空间

 mfmain 回复于:2004-09-26 00:20:17
[quote:0659c52632="bmw1981bmw"]
如果您说的成立 那么 int buf[40](或者char buf[160]); 

应该不会出现多余的stack [/quote:0659c52632]

我一直都强调是地址对齐,不是大小对齐,还特意举了一个size=10的例子, 好好体会一下两种对齐的差别再说

 bmw1981bmw 回复于:2004-09-26 10:22:50
明白了

您强调的是地址对齐;和向后对齐;

但是

这怎么解释多余的stack分配呢? (而且当stack超过8byte时总是多分配8byte,至少在我做的实验是这样.不好意识很苯!! ^_^)

 mfmain 回复于:2004-09-27 11:09:12
sorry, 更正几个说法:
1 举了一个错误的例子,frame size肯定是4的倍数,不可能为10,改为24吧
2 关于地址对齐,可能是我记错了,今天又试了一下,似乎还是用的大小对齐方式,分配frame中自动变量空间sub    $frsize,%esp时,frsize似乎是0x18, 0x28, 0x38,0x48这样每次递增16字节,不过FreeBSD 521带的gcc version 3.2.2 [FreeBSD] 20030205 (release)的这个版本更为古怪, 当自动变量大小为3和4时,frsize居然分别为0x18和4,我ft,可能是这个版本的一个小bug,但不会影响代码的正确运行,不管怎么说,frsize总是>=自动变量占用的总字节数,不必深究frsize到底是怎么决定的。
3 前贴中用“前/后”,容易引起误解,还是改为"高地址/低地址"比较好,我一会儿重新编辑一下

 bmw1981bmw 回复于:2004-09-27 16:40:17
那么请问有没有办法 准确的找到 ret 呢?

 mfmain 回复于:2004-09-27 19:11:03
是用的地址对齐,有兴趣的话可以看一下gcc的源代码calls.c,其中全局变量preferred_stack_boundary就是控制对齐的,默认是4(即16字节对齐),改成2就成了4字节对齐,这样分配的frame size正常够用,也就没有多余空间了,但不推荐这样做!
要找ret直接ebp+4不就得了

 bmw1981bmw 回复于:2004-09-28 16:37:47
谢谢

 ~嫣然一笑~ 回复于:2004-09-30 17:45:33
:D

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有