工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
楼主: michael175

有请编程高手指导下!!!

[复制链接]
发表于 2008-3-20 00:53 | 显示全部楼层
vc6 下反汇编代码:
char s[]="HELLO";
mov         eax,[string "HELLO" (0042801c)]
mov         dword ptr [ebp-8],eax
mov         cx,word ptr [string "HELLO"+4 (00428020)]
mov         word ptr [ebp-4],cx
12:   return s;
lea         eax,[ebp-8]

可见,字符串"hello\0"位于一个固定的内存区域,如果你在其他地方也引用了"hello",也是编译指向该地址.我们通常称其为字符串常量.C/C++编译器会将字符串常量放于内存某个区域(通常我们称其为常量区),并用指针代替字符串引用.而不做优化的编译器有可能在内存中生成多个相同的拷贝. :0
ebp-8 是字符数组s的开始地址, 将该地址放于寄存器eax中返回. 但是堆栈指针寄存器esp在函数返回时,已经指向ebp+某常数的位置了, 亦即我们说的出栈, 但其低地址的内容是否被销毁了呢? 其实没有, 但如果又有进出栈的话, 原内存地址的内容可能被覆盖,即 s 数组可能会被覆盖. 从上面我们可以看出 s 数组的大小为dword + word =6字节 , 其实在"hello"+5处存放的是0 .
---------------------------------------------------------------------------------------------------
23:   int *p;
24:   int i = 32;
       dword ptr [ebp-8],20h
25:   p = &i;
        lea         eax,[ebp-8]
        mov         dword ptr [ebp-4],eax
26:   return p;
        mov         eax,dword ptr [ebp-4]

看第一句定义了一个指针,然而却没有对应的汇编代码.没错, 所有变量在最后其实都变成了对一个地址的引用,如ebp-8 处是i , ebp-4处是p;  但是不同的变量占有不同字节的内存, 那么我们怎么知道要操作多少字节呢? 呵呵,这就是编译器的事了, i 是int , p是int *. 所以操作都是dword . 更复杂的, 对结构体是如何处理的呢?大家有空自己上网搜一搜.
cout char * 是输出字符串, cout int *是输出地址, 为什么会有乱码和输出地址应该可以总结出来了. 大家也可以想一下cout重载<<运算符的实现,嗯,应该也是靠判断末尾0来判断一个字符串的结束吧.
=========================================================
* f() 即取s 数组第一个字符( 因为f()返回的是 s 的地址) , 其实你还可以试试,  *( f()+1) 就是e , +2 就是 l , 嗯, 这就是我们前面所说的, 函数虽然返回了, 但其原先的参数是否销毁了呢? 没有(也没有必要,难道特意增加指令去将这些内存单元置0?) .  但当cout 函数调用时, s 数组有可能要被覆盖了. 因为有新的进出栈的动作.(所以产生了乱码)   .  需要弄清楚的是函数调用的先后, cout << f()   , 先调用 f(), f()的返回值作为参数再调用operater<< 函数..

:)   以上是我的一点理解
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2024-5-31 11:47

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

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