Zitat von
BLUESCREEN3D
Demnach müsste der Arrayinhalt beim Programmstart doch nochmal in einen anderen Speicherbereich kopiert werden, um schreibbar zu sein. Dazu habe ich ein Programm mit einem 1-MB-String einmal als char* und einmal als char[] gestartet und die char[]-Version braucht tatsächlich zur Laufzeit 1 MB mehr Speicher.
Genau, so ist es:
seg.c:
Code:
#include <stdio.h>
int main(void)
{
char*s1="Hallo Welt 1";
char s2[]="Hallo Welt 2";
*s1='B';
s2[0]='B';
}
objdump -s seg
Code:
Contents of section .rodata:
8048458 03000000 01000200 48616c6c 6f205765 ........Hallo We
8048468 6c742031 0048616c 6c6f2057 656c7420 lt 1.Hallo Welt
8048478 3200 2.
Zu seg gehöriger Assemblercode:
Code:
(gdb) disassemble main
Dump of assembler code for function main:
0x08048344 <main+0>: lea ecx,[esp+0x4]
0x08048348 <main+4>: and esp,0xfffffff0
0x0804834b <main+7>: push DWORD PTR [ecx-0x4]
0x0804834e <main+10>: push ebp
0x0804834f <main+11>: mov ebp,esp
0x08048351 <main+13>: push ecx
0x08048352 <main+14>: sub esp,0x20
0x08048355 <main+17>: mov DWORD PTR [ebp-0x8],0x8048460
0x0804835c <main+24>: mov eax,ds:0x804846d
0x08048361 <main+29>: mov DWORD PTR [ebp-0x15],eax
0x08048364 <main+32>: mov eax,ds:0x8048471
0x08048369 <main+37>: mov DWORD PTR [ebp-0x11],eax
0x0804836c <main+40>: mov eax,ds:0x8048475
0x08048371 <main+45>: mov DWORD PTR [ebp-0xd],eax
0x08048374 <main+48>: movzx eax,BYTE PTR ds:0x8048479
0x0804837b <main+55>: mov BYTE PTR [ebp-0x9],al
0x0804837e <main+58>: mov eax,DWORD PTR [ebp-0x8]
0x08048381 <main+61>: mov BYTE PTR [eax],0x42
0x08048384 <main+64>: mov BYTE PTR [ebp-0x15],0x42
0x08048388 <main+68>: add esp,0x20
0x0804838b <main+71>: pop ecx
0x0804838c <main+72>: pop ebp
0x0804838d <main+73>: lea esp,[ecx-0x4]
0x08048390 <main+76>: ret
End of assembler dump.
(gdb)
.
In 0x08048355 <main+17> wird die Speicheradresse von "Hallo Welt 1" (besser gesagt von "H") in .rodata auf dem Stack abgelegt. Dann wird von 0x0804835c <main+24> bis 0x08048371 <main+45> der Inhalt von 0x804846d bis 0x8048478 (= 12 Byte, "Hallo Welt 2" = 12 Byte) aus .rodata kopiert, bei 0x08048374 <main+48> bis 0x0804837b <main+55> kommt dann vermutlich das Nullbyte auf den Stack.
Schließlich wird in 0x0804837e <main+58> die Speicheradresse des Hs von "Hallo Welt 1" in das A Register kopiert (diese Speicheradresse wurde ja vorher bei ebp-0x8 auf den Stack abgelegt). Bei 0x08048381 <main+61> kommt es dann zum Speicherzugriffsfehler, weil versucht wird, an die Speicheradresse, die in EAX steht, etwas zu schreiben.
0x08048384 <main+64> geht, weil da nur der Stack verändert wird.
Gruß, Florian
Lesezeichen