首页
社区
课程
招聘
栈区以及常量区
发表于: 2010-3-26 13:48 3955

栈区以及常量区

2010-3-26 13:48
3955
如下定义
static int num = 56789;
char str1[] = "pretty";
char str2[3] = {'a','b','c'};
char *str3 = "efg";

.text:0040B798 mov     eax, dword ptr ds:aPretty       ; "pretty"
.text:0040B79D mov     [ebp+var_C], eax
.text:0040B7A0 mov     cx, word ptr ds:aPretty+4
.text:0040B7A7 mov     [ebp+var_8], cx
.text:0040B7AB mov     dl, byte ptr ds:aPretty+6
.text:0040B7B1 mov     [ebp+var_6], dl
.text:0040B7B4 mov     [ebp+var_10], 61h
.text:0040B7B8 mov     [ebp+var_F], 62h
.text:0040B7BC mov     [ebp+var_E], 63h
.text:0040B7C0 mov     [ebp+var_14], offset aEfg       ; "efg"

发现str1 和 str3存放在rdata段中而且位置很近,如下
.rdata:00420F7A align 4
.rdata:00420F7C aEfg db 'efg',0                         ; DATA XREF: test+40o
.rdata:00420F80 aPretty db 'pretty',0                   ; DATA XREF: test+18r
.rdata:00420F80                                         ; test+20r ...

这里是是栈区还是常量区?

另外str2存放在那呢?
.text:0040B7B4 mov     [ebp+var_10], 61h
.text:0040B7B8 mov     [ebp+var_F], 62h
.text:0040B7BC mov     [ebp+var_E], 63h

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 331
活跃值: (57)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
2
str1,str2,str13本身都是局部变量,所以都在栈中,"pretty","efg"都是字符串常量,编译器把它们放到了rdata段,还有那个字符数组特别简单,编译器直接把它们放到指令中了
text:0040B7B4 mov     [ebp+var_10], 61h
.text:0040B7B8 mov     [ebp+var_F], 62h
.text:0040B7BC mov     [ebp+var_E], 63h
如果编译器优化的好的话,其实“efg”也可以放在指令中,你可以试试最高级别的优化选项。
2010-3-26 16:06
0
雪    币: 63
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
其实对于像指针str3这样的变量的定义,在栈空间里分配的仅仅是一个指针位,如果是32位机就是4个字节的空间了,具体的指向的字符串其实是放在常量数据区的,栈空间存的只是指向对应的常量所在的地址而已。当然了在具体生成汇编代码的过程中,还会进行优化,优化的结果具体就要看所采取的优化策略了。
2010-3-26 17:28
0
雪    币: 72
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
呵呵,楼上两位好像都有道理。

总结一下:
str1,str2,在栈中存放的是一个指针,指向了字符串,而字符串存放在rdata段中,(不知这里是不是所谓的常量数据区)

better说的“还有那个字符数组特别简单,编译器直接把它们放到指令中了”,那这个指令是存放在哪呢?
2010-3-27 23:40
0
雪    币: 724
活跃值: (81)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
char str1[] = "pretty";
char str2[3] = {'a','b','c'};
char *str3 = "efg";
如果以上声明是在一个函数内部,则:
str1,str2,str3都栈中“变量”;
str1是数组,它由"pretty"初始化,sizeof(str1)=6+1=7(6个字符,结尾加上空字符\0);
str2也是数组,它由3个字符初始化,sizeof(str2)=3;
str3是指针,它指向字符串"efg";
"pretty"和"efg"是字符串常量,它们存储在常量区。
每个线程都有自己的栈,栈与PE格式的文件无关,PE文件中不会有栈区(它倒是可以控制主线程栈的大小);DOS的EXE文件中有栈区,那是因为DOS是单任务单线程系统。
2010-3-28 10:45
0
雪    币: 63
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
5l说的很正确。
比如对于str2来说,它的类型其实就是char[3],分配的时候就不必放到常量区,直接就作为局部变量放在栈区。受益了,在pe文件中的变量放在.data中,pe加载直接映射在进程的地址空间,栈是操作系统根据pe文件里的数据生成的。
2010-3-28 11:28
0
雪    币: 72
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
请教怎么能找到.data中的变量,比如说怎么找到61h, 62h 63h,还是我理解错误?如果是那么61h 62h 63h存储在什么地方呢?

.text:0040B7B4 mov     [ebp+var_10], 61h
.text:0040B7B8 mov     [ebp+var_F], 62h
.text:0040B7BC mov     [ebp+var_E], 63h
2010-3-28 21:09
0
雪    币: 63
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
我帮你把写的这几条语句分析下。。这样或许你会更清楚些:
static int num = 56789;
char str1[] = "pretty";
char str2[3] = {'a','b','c'};
char *str3 = "efg";
num这放在.data段中,pretty和efg则要放在.rdata中呢,因为他们是只读常量。这样你就可以理解
.rdata:00420F7A align 4
.rdata:00420F7C aEfg db 'efg',0                         ; DATA XREF: test+40o
.rdata:00420F80 aPretty db 'pretty',0                   ; DATA XREF: test+18r
.rdata:00420F80
这段代码了吧。他们定义的时候就定义在一块。
至于str2这个字符数组,在反汇编程序中明显可以看到:
.text:0040B7B4 mov     [ebp+var_10], 61h
.text:0040B7B8 mov     [ebp+var_F], 62h
.text:0040B7BC mov     [ebp+var_E], 63h
这就说明编译器把他们放在了指令中了,这就算是编译器的优化了。。至于这些指令存放的地方,当然放在.text指令区么,语句前面都有的。。
不好意思,我把2楼的意思理解错了,他说的也很有道理。

大家可以继续交流~~
2010-3-29 10:43
0
雪    币: 72
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
明白了,多谢各位。
2010-3-29 13:47
0
游客
登录 | 注册 方可回帖
返回
//