字符串存储位置的疑问

字符串的存储位置到底在哪儿?按照我以前编汇编代码的经验,,字符串肯定是放在数据段。但是在C/C++中,这个却不一定成立吧!昨天晚上跟群里的同学讨论,我们观点不太一样,他认为应该直接存在函数的栈空间。我可以肯定字符串常量会放在数据段,但是对字符数组我确实不太确定了。所以就分别在VC和GCC下试了试,看了个简单程序的反汇编代码。首先看看VC的吧:

main(){char a[] = “abcd”;char b[] = {‘a’,’b’,’c’,’d’};printf(“%s\n”, b);printf(“%d,%d”,strlen(a),strlen(b));getchar();return 0;}VC上的输出是: abcd烫烫烫烫abcd 4,16看看汇编代码吧! char a[] = “abcd”;002813C8 moveax,dword ptr [string “abcd” (285748h)] 002813CD movdword ptr [ebp-10h],eax 002813D0 movcl,byte ptr ds:[28574Ch] 002813D6 movbyte ptr [ebp-0Ch],clchar b[] = {‘a’,’b’,’c’,’d’};002813D9 movbyte ptr [ebp-1Ch],61h 002813DD movbyte ptr [ebp-1Bh],62h 002813E1 movbyte ptr [ebp-1Ah],63h 002813E5 movbyte ptr [ebp-19h],64h

后四行非常容易理解,就是立即数赋值,把字符’a’,’b’,’c’,’d’赋值到栈空间,也就是局部变量中。然后看前四行汇编,第一二行的作用是把“abcd”直接赋值给局部变量,因”abcd”只有四个字节。然后的两行是把’\0’赋值到数组a的尾部。然后再来看看strlen()的返回,strlen(a) = 4 这个结果是显而易见的,因为‘d’后有一个’\0’。然后strlen(b) = 8 ,这是因为b后边没有直接跟’\0’字符,然后strlen()函数一直寻找到字符数组a的末尾,然后最终返回。不知道为什么编译器在,数组a和b之间留了8个字节的空,所以strlen(b) = 16。 – 看看GCC的结果: abcdabcd 4,8 汇编代码段:

080484fd <main>: ::mov cmov %eax,0x1c(%esp) movl $0x64636261,0x17(%esp) b 00movb $0x0,0x1b(%esp) movb $0x61,0x13(%esp) movb $0x62,0x14(%esp) movb $0x63,0x15(%esp) movb $0x64,0x16(%esp) lea 0x13(%esp),%eax

这是在Ubuntu 14.04中的结果(我没注意GCC版本,在Windows下码字),感觉和VC差不多。不过在早期的GCC版本中,却不是这样的。这是一个07年的老帖子中的内容:

#include “stdio.h”int main(){char a[] = “abc”;a[1] = ‘a’;printf(“%s\n”, a);}08048394 <main>: :d:b8 mov a5:ab:c1 e0 b0:a1 bc mov fcmov %eax,0xfffffffc(%ebp) 80483b8:c6 45 fd 61movb $0x61,0xfffffffd(%ebp) mov %eax,0x4(%esp) movl $0x80484c0,(%esp) 80483ca:e8 01 ff ff ffcall 80482d0 <printf@plt> 80483cf:c9leave 80483d0:c3ret80483d1:90nop

完全没有把字符串拷贝到栈空间里,栈空间里甚至连一个指针都没有。访问字符串的时候使用相对寻址,在这种情况下字符串完全存在于数据段(本例是可读写的)。总结一下,其实字符串存储的位置并不是一定要怎么样,编译器是拥有一定的自由度的。我估计现在的编译器基本都会使用第一种方法,毕竟相对安全一些;其次是栈空间是动态的,函数返回后就自动释放;最后,现在内存可是白菜价呀!

蝙蝠黑暗中闯荡,树木默默的成长,蝴蝶破蛹后飞翔,

字符串存储位置的疑问

相关文章:

你感兴趣的文章:

标签云: