首页
社区
课程
招聘
请教一下VC局部变量空间的一些问题
发表于: 2006-3-30 15:53 6387

请教一下VC局部变量空间的一些问题

2006-3-30 15:53
6387
第一个问题::
    在VC的子函数中,明明只有一两个变量却要分配几百个字节的堆栈空间,为什么?

第一个问题:
    在VC的子函数中分配比较大的堆栈空间然后填入0xcc(int 3)这是为什么呢?

(我试着调试过Release和Debug版本的都是这样.,微软有病么?)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
2
问题一可能是那个局部变量人家就定义了那么大。
问题二弄成CC是方便调试,CC就是int3,就是调试中断。
2006-3-30 17:28
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
你说的第一个问题应该是初始堆栈为什么需要几百个字节的空间是吧?
如果只针对某一个函数的栈空间,那么release模式只需要(临时变量+参数+返回地址)大小的空间.
2006-3-30 18:26
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
为了配合C++库运行时检查机制

Release模式可能根本不需要栈帧, 优化全开的话变量会到寄存器里, 连ebp都可以被用来存变量

说到这儿我想起以前有人问过的一个问题:

调试驱动的时候, 为什么有时SoftICE不会显示所有的局部变量?是SI的Bug吗?

猜想可能是那个驱动采用优化编译后, 变量被移入了寄存器, 所以SI无法显示所有的变量
2006-3-30 19:11
0
雪    币: 257
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
在VC的子函数中分配比较大的堆栈空间然后填入0xcc(int 3)这是为什么呢?

这是因为你的变量没有初始化。
2006-3-30 21:15
0
雪    币: 329
活跃值: (343)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
6
驱动用Free方式编译后,有的局部变量会在一个函数内重用多次,而且有的局部变量会直接使用寄存器。
2006-3-30 21:59
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
关于填入 int 3 我也想到过,不过不敢确认,如果真的是这样的话,听了以上高手的回答,我还是觉得微软有病.为啥呢?如果只是变量没有初始化就填入int 3,就是多余的了,应该说程序无意跳到没有初始化的变量的堆栈空间上执行代码的可能性小,多半都是堆栈平衡被破坏的情况下,调用了ret指令.这样的话微软有个设计的很精良的_chekesp啊.第二,所有的区段都是有属性的,不知道堆栈空间的属性是什么?(堆栈空间应该是不同于区段映射的内存空间,是另外的空间,这样的空间微软肯定是知道不是用来执行代码的三,所以可能不是EXECUTIVE),关于大家的回答,有位大哥所说的和优化有关,我下去看了看,觉得很有用,谢谢大家.

    个人观点:微软有病 ,没事吃饱了,白分配那么大堆栈 , 就是一个char类型也是分配的4个字节,而且不管有没有局部变量都分配一大块堆栈再说.每个局部变量是4个字节的倍数.这样编译器到是不用生成什么byte ptr 之类的了,不过就是浪费了堆栈,微软有病
2006-3-31 21:08
0
雪    币: 207
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
"堆栈空间应该是不同于区段映射的内存空间,是另外的空间,这样的空间微软肯定是知道不是用来执行代码的三,所以可能不是EXECUTIVE"
上传的附件:
2006-3-31 23:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
看得不是很清楚。
2006-4-1 11:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
最初由 Hitman 发布
关于填入 int 3 我也想到过,不过不敢确认,如果真的是这样的话,听了以上高手的回答,我还是觉得微软有病.为啥呢?如果只是变量没有初始化就填入int 3,就是多余的了,应该说程序无意跳到没有初始化的变量的堆栈空间上执行代码的可能性小,多半都是堆栈平衡被破坏的情况下,调用了ret指令.这样的话微软有个设计的很精良的_chekesp啊.第二,所有的区段都是有属性的,不知道堆栈空间的属性是什么?(堆栈空间应该是不同于区段映射的内存空间,是另外的空间,这样的空间微软肯定是知道不是用来执行代码的三,所以可能不是EXECUTIVE),关于大家的回答,有位大哥所说的和优化有关,我下去看了看,觉得很有用,谢谢大家.



个人观点:微软有病 ,没事吃饱了,白分配那么大堆栈 , 就是一个char类型也是分配的4个字节,而且不管有没有局部变量都分配一大块堆栈再说.每个局部变量是4个字节的倍数.这样编译器到是不用生成什么byte ptr 之类的了,不过就是浪费了堆栈,微软有病


呵,是intel的原因,看看<<组成原理>>上面有介绍为什么要4字节对齐
2006-4-1 12:59
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
可能还是对齐的原因,恩~~~忘记了,不过对齐不对齐的好象没关系,只有以前写驱动的时候的一个什么地方要求必须4字节对齐.不过执行速度可能会快点.
谢谢
哎~~以后没必要在函数定义什么short,char这些东西了.
2006-4-4 10:00
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
12
堆栈空间的代码是可以执行的,对齐也没必要对其那么大,CC我觉得还是调试中断。
2006-4-4 18:19
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
13
这个现象以前在CSDN有人问过的。

我看了一下test.rar

里面有的函数没有用CC填充的。比如sub_1001C42

而且,这个CC的问题我以前反汇编VC6编译的exe的时候没有发现过。只是在有了vc7以后才发现的。

我看那个CC就是为了检测/防止堆栈溢出的。一方面是标志,一方面,是由于cc=int3
2006-4-5 08:10
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我注意到VC里面有个_chekesp是专门检查堆栈益处问题的,但是有的函数有,有的函数又没有,我仔细瞧了瞧,没有找出 出现 _chekesp检测函数的规律,而你说0xcc是负责检测堆栈益处,然后在插入那么多0xcc的时候没有加入SEH链,就是说一旦发生执行0xcc代码的时候会调用系统的异常处理函数或者直接崩溃,从这说的话 处理和检测堆栈益处的意义并不是很大,而那么的堆栈字节用于对齐也勉强说的过去,我对这个问题还是琢磨不透,这个小问题引起那么多的回复,好感动啊
在此 真诚的谢谢每一位参与回复的人,谢谢
2006-4-6 19:42
0
雪    币: 93
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
最初由 firstrose 发布
这个现象以前在CSDN有人问过的。

我看了一下test.rar

里面有的函数没有用CC填充的。比如sub_1001C42
........


这个问题不知大虾如何解决,本人用OD加载一个VC++7.0的程序总有这个问题
2006-4-6 20:11
0
雪    币: 250
活跃值: (103)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
16
我觉得应该不是微软有病,而是他故意安排的。
至于原因,我以为除了对齐这个因素之外,更大的可能则是为了便于插入调试指令和打补丁(所谓的“热补”[hot-patch])。虽然说其他也有一些程序也可进行此类工作,但必须要suspending进程,操作起来远不如hot-patching方便、快捷。
2006-4-6 20:19
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
hot-patching是什么意思,是不是将被调试者安排在一个进程空间里呢?这位大哥分析的也有道理,微软给我们留了一个悬念,哎~~~干程序员命苦啊~~~
2006-4-9 16:33
0
游客
登录 | 注册 方可回帖
返回
//