1,首先源码:
#include
#include
int our_init_data = 30;
int our_noinit_data;
void our_prints(int a,int b,int c,int d)
{
int our_local_data = 1;
char buf[1024];
char *rodata="hello,world,string"; //字符串指针
char arr[]="Hello,world,array"; //字符串数组
printf("\nPid of the process is = %d", getpid());
printf("\nAddresses which fall into:");
printf("\n 1) Data segment = %p", &our_init_data);
printf("\n 2) BSS segment = %p", &our_noinit_data);
printf("\n 3) Code segment = %p", &our_prints);
printf("\n 4) Stack segment = %p", &our_local_data);
printf("\n 5) rodata segment = %p", rodata);
printf("\n 6) arr segment = %p\n", arr);
printf("%x\n",&arr[0]);
a=b+c+d;
sprintf(buf,"cat /proc/%d/maps",getpid());
system(buf);
}
int main()
{
//int n=50,j=500;
our_prints(100,200,300,400);
return 0;
}
~
2,运行结果
~
[root@localhost st]# ./a.out
Pid of the process is = 21611
Addresses which fall into:
1) Data segment = 0x8049880
2) BSS segment = 0x804988c
3) Code segment = 0x8048414
4) Stack segment = 0xbfc11970
5) rodata segment = 0x8048670
6) arr segment = 0xbfc1155e
bfc1155e
00110000-0024f000 r-xp 00000000 fd:00 16090599 /lib/libc-2.5.so
0024f000-00251000 r-xp 0013f000 fd:00 16090599 /lib/libc-2.5.so
00251000-00252000 rwxp 00141000 fd:00 16090599 /lib/libc-2.5.so
00252000-00255000 rwxp 00252000 00:00 0
00b76000-00b90000 r-xp 00000000 fd:00 16090598 /lib/ld-2.5.so
00b90000-00b91000 r-xp 00019000 fd:00 16090598 /lib/ld-2.5.so
00b91000-00b92000 rwxp 0001a000 fd:00 16090598 /lib/ld-2.5.so
00b9a000-00b9b000 r-xp 00b9a000 00:00 0 [vdso]
08048000-08049000 r-xp 00000000 fd:00 1083484 /var/ftp/pub/st/a.out
08049000-0804a000 rw-p 00000000 fd:00 1083484 /var/ftp/pub/st/a.out
b7fe7000-b7fe9000 rw-p b7fe7000 00:00 0
b7ff5000-b7ff6000 rw-p b7ff5000 00:00 0
bfbfe000-bfc13000 rw-p bffea000 00:00 0 [stack]
3, 检查只读数据段objdump -S -j .rodata
[root@localhost st]# objdump -S -j .rodata
a.out: file format elf32-i386
Disassembly of section .rodata:
08048664 <_fp_hw>:
8048664: 03 00 00 00 ....
08048668 <_IO_stdin_used>:
8048668: 01 00 02 00 ....
0804866c <__dso_handle>:
804866c: 00 00 00 00 68 65 6c 6c 6f 2c 77 6f 72 6c 64 2c ....hello,world,
804867c: 73 74 72 69 6e 67 00 0a 50 69 64 20 6f 66 20 74 string..Pid of t
804868c: 68 65 20 70 72 6f 63 65 73 73 20 69 73 20 3d 20 he process is =
804869c: 25 64 00 0a 41 64 64 72 65 73 73 65 73 20 77 68 %d..Addresses wh
80486ac: 69 63 68 20 66 61 6c 6c 20 69 6e 74 6f 3a 00 0a ich fall into:..
80486bc: 20 31 29 20 44 61 74 61 20 20 73 65 67 6d 65 6e 1) Data segmen
80486cc: 74 20 3d 20 25 70 00 0a 20 32 29 20 42 53 53 20 t = %p.. 2) BSS
80486dc: 20 20 73 65 67 6d 65 6e 74 20 3d 20 25 70 00 0a segment = %p..
80486ec: 20 33 29 20 43 6f 64 65 20 20 73 65 67 6d 65 6e 3) Code segmen
80486fc: 74 20 3d 20 25 70 00 0a 20 34 29 20 53 74 61 63 t = %p.. 4) Stac
804870c: 6b 20 73 65 67 6d 65 6e 74 20 3d 20 25 70 00 0a k segment = %p..
804871c: 20 35 29 20 72 6f 64 61 74 61 20 73 65 67 6d 65 5) rodata segme
804872c: 6e 74 20 3d 20 25 70 00 0a 20 36 29 20 61 72 72 nt = %p.. 6) arr
804873c: 20 73 65 67 6d 65 6e 74 20 3d 20 25 70 0a 00 25 segment = %p..%
804874c: 78 0a 00 63 61 74 20 2f 70 72 6f 63 2f 25 64 2f x..cat /proc/%d/
804875c: 6d 61 70 73 00 48 65 6c 6c 6f 2c 77 6f 72 6c 64 maps.Hello,world
804876c: 2c 61 72 72 61 79 00 ,array.
4,检查代码段objdump -S -j .text
char *rodata="hello,world,string";
8048424: c7 45 fc 70 86 04 08 movl $0x8048670,0xfffffffc(%ebp) ;立即数
char arr[]="Hello,world,array";
804842b: a1 61 87 04 08 mov 0x8048761,%eax ;直接引用地址
8048430: 89 85 e6 fb ff ff mov %eax,0xfffffbe6(%ebp)
8048436: a1 65 87 04 08 mov 0x8048765,%eax
804843b: 89 85 ea fb ff ff mov %eax,0xfffffbea(%ebp)
8048441: a1 69 87 04 08 mov 0x8048769,%eax
8048446: 89 85 ee fb ff ff mov %eax,0xfffffbee(%ebp)
804844c: a1 6d 87 04 08 mov 0x804876d,%eax
8048451: 89 85 f2 fb ff ff mov %eax,0xfffffbf2(%ebp)
8048457: 0f b7 05 71 87 04 08 movzwl 0x8048771,%eax
804845e: 66 89 85 f6 fb ff ff mov %ax,0xfffffbf6(%ebp)
字符串常量 只读数据段的地址 直接被直接付给了变量;但是 字符串数组 只读数据段的地址所指向的内容被付给了变量
5,总结
字符串指针 和 字符串数组 在编译的时候都存储在 只读数据段.rodata section。但是在赋值的时候,字符串指针获得的是 只读数据段的地址,而字符串数组 获得的是 堆栈段的地址。因此字符串指针 是不能修改的,但是 字符串数组 是可以修改的。