Discussion:
Nasm Variable erhaelt komischen Wert nach Zuweisung
(zu alt für eine Antwort)
Christian Ress
2006-09-11 16:14:05 UTC
Permalink
Hallo,

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
Herbert Kleebauer
2006-09-11 16:32:24 UTC
Permalink
Post by Christian Ress
Hallo,
ich bin beim Programmieren auf ein Problem mit dem Inhalt von einer
Variable gestossen.
tmp_dw1 dw 0
tmp_dw2 dw 0
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.
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?
Wandle doch mal 393221 in hex um, dann solltest du selbst sehen
was passiert ist.
Heiko Nocon
2006-09-11 16:56:47 UTC
Permalink
Post by Christian Ress
tmp_dw1 dw 0
tmp_dw2 dw 0
Also zwei _Worte_ (je zwei Byte breit).
Post by Christian Ress
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.
Post by Christian Ress
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...
Post by Christian Ress
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.
Post by Christian Ress
(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)
Post by Christian Ress
(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.
Sebastian Biallas
2006-09-11 17:20:34 UTC
Permalink
Post by Heiko Nocon
Post by Christian Ress
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.
Du interpretierst die gdb Ausgaben falsch. Die obige Zeile 11 wird erst
Post by Heiko Nocon
Post by Christian Ress
(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
Heiko Nocon
2006-09-11 17:53:53 UTC
Permalink
Post by Sebastian Biallas
Du interpretierst die gdb Ausgaben falsch.
Das mag gut sein. Ich habe den noch nie benutzt, dementsprechend auch
keine Ahnung davon.
Post by Sebastian Biallas
Ist da tatsächliche so eine Heuristik drin?
Wie sonst sollte zu erklären sein, daß er es einmal so und einmal so
interpretiert?
Sebastian Biallas
2006-09-11 18:33:21 UTC
Permalink
Post by Heiko Nocon
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
Stefan Reuther
2006-09-11 18:39:06 UTC
Permalink
Warum der gdb aber tmp_dw1 und tmp_dw2 als dwords interpretiert,
verstehe ich nicht. Ist da tatsächliche so eine Heuristik drin?
Vielleicht fehlen in den Debuginformationen einfach die Typinformationen.
Gib mal 'whatis tmp_dw1' ein.


Stefan
Sebastian Biallas
2006-09-11 18:48:39 UTC
Permalink
Post by Stefan Reuther
Warum der gdb aber tmp_dw1 und tmp_dw2 als dwords interpretiert,
verstehe ich nicht. Ist da tatsächliche so eine Heuristik drin?
Vielleicht fehlen in den Debuginformationen einfach die Typinformationen.
Gib mal 'whatis tmp_dw1' ein.
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
Christian Ress
2006-09-15 15:29:58 UTC
Permalink
Post by Heiko Nocon
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.
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

Loading...