ich bin beim Programmieren auf ein Problem mit dem Inhalt von einer
Variable gestossen.
Ich definiere zwei Variablen, tmp_dw1 und tmp_dw2 so:
tmp_dw1 dw 0
tmp_dw2 dw 0
und weise ihnen anschliessend wiefolgt einen Wert zu:
mov dword [tmp_dw1], 5
mov dword [tmp_dw2], 6
Mir ist allerdings aufgefallen, dass ich auf sehr komische Ergebnisse
komme wenn ich mit tmp_dw1 weiterrechne, also hab ich den Debugger
angeworfen und geguckt was schief laeuft. Nachdem ich tmp_dw2
zugewiesen habe steht in tmp_dw1 393221.
gdb output:
10 mov dword [tmp_dw1], 5
11 mov dword [tmp_dw2], 6
(gdb) print tmp_dw1
$1 = 5
(gdb) n
12 mov eax, 1
(gdb) print tmp_dw2
$2 = 6
(gdb) print tmp_dw1
$3 = 393221
Wie weise ich den Variablen "richtig" einen Wert zu?
Danke,
Christian
Wandle doch mal 393221 in hex um, dann solltest du selbst sehen
was passiert ist.
>Ich definiere zwei Variablen, tmp_dw1 und tmp_dw2 so:
>
>tmp_dw1 dw 0
>tmp_dw2 dw 0
Also zwei _Worte_ (je zwei Byte breit).
>und weise ihnen anschliessend wiefolgt einen Wert zu:
>
>mov dword [tmp_dw1], 5
>mov dword [tmp_dw2], 6
Und hier weist du ihnen _DWORD_ Werte zu. (je vier Byte breit).
Mit der ersten Zuweisung setzt du bereits beide Variablen, nämlich
tmp_dw1 auf 5 und tmp_dw2 auf 0. Mit der zweiten Zuweisung überschreibst
du dann tmp_dw2 mit 6 und die armen unschuldigen zwei Byte, die danach
im Speicher liegen überschreibst du gleich mit, und zwar mit Null.
>Mir ist allerdings aufgefallen, dass ich auf sehr komische Ergebnisse
>komme wenn ich mit tmp_dw1 weiterrechne
Dieses komische Ergebnis verdankst du der "Intelligenz" des Debuggers,
die offensichtlich keine ist...
>10 mov dword [tmp_dw1], 5
>11 mov dword [tmp_dw2], 6
>(gdb) print tmp_dw1
>$1 = 5
Hier nimmt der Debugger offensichtlich trotz der expliziten Zuweisung
mit dword-Breite immer noch an, daß es sich, wie deklariert um
word-breite Variablen handelt.
>(gdb) n
>12 mov eax, 1
>(gdb) print tmp_dw2
>$2 = 6
Das ist auf jeden Fall OK. Schließlich steht hier, egal ob man es als
word oder dword betrachtet, immer noch 6. Das würde sich aber ändern,
wenn du die danach liegende Variable irgendwann mal für ihren
eigentlichen Zweck verwendest. ;o)
>(gdb) print tmp_dw1
>$3 = 393221
Tja, und das ist offensichtlich ein Bug in der "Intelligenz" des
Debuggers. Wahrscheinlich die Zuweisung auf das dword-Register eax
verführt ihn dazu, nun plötzlich auch tmp_dw1 trotz anders lautender
Deklaration als dword zu betrachten. 393221d=00060005h. Du siehst hier
also den Inhalt beider word-Variablen auf einmal.
Du interpretierst die gdb Ausgaben falsch. Die obige Zeile 11 wird erst
hier:
>> (gdb) n
ausgeführt (d.h. "dword [tmp_dw1] == 5" gilt vorher noch). Warum der gdb
aber tmp_dw1 und tmp_dw2 als dwords interpretiert, verstehe ich nicht.
Ist da tatsächliche so eine Heuristik drin?
--
Gruß,
Sebastian
>Du interpretierst die gdb Ausgaben falsch.
Das mag gut sein. Ich habe den noch nie benutzt, dementsprechend auch
keine Ahnung davon.
>Ist da tatsächliche so eine Heuristik drin?
Wie sonst sollte zu erklären sein, daß er es einmal so und einmal so
interpretiert?
Ich denke mal, er interpretiert es nicht mal so und mal so, sondern
immer als dword. Die Zuweisung an tmp_dw2 wird erst nach der Eingabe von
'n' ausgeführt.
Allerding verstehe ich gerade nicht, wo der gdb da die debug-infos
herkriegt, ich konnte die Ausgabe zumindest nicht reproduzieren.
--
Gruß,
Sebastian
Vielleicht fehlen in den Debuginformationen einfach die Typinformationen.
Gib mal 'whatis tmp_dw1' ein.
Stefan
In der Tat:
(gdb) whatis tmp_dw1
type = <data variable, no debug info>
(gdb) p tmp_dw1
$1 = 0
(gdb) p sizeof tmp_dw1
$2 = 4
Wenn er keine Typinformation hat, nimmt er einfach an, dass es ein dword
ist. Mutig :)
--
Gruß,
Sebastian
Danke fuer die Erklaerungen!
Eigentlich sollten die Variablen ja von vorn herein dwords werden,
allerdings hab ich mich von dem Trugschluss 'dw' stehe fuer 'dword'
fehlleiten lassen. Immerhin dabei noch was ueber den gdb gelernt :)
Die Ausgabe sieht jetzt so aus, wie ich sie erwartet habe, vielen Dank
nochmal.
Christian