Problem mit Dereferenzierung von einem Zeiger (X86-Assembler Windows)
-
Hallo,
ich habe ein Problem mit dem Code, den ich unten gepostet habe.
Der Offset von myVar wird in esi und in zeiger geladen. Zeiger und esi zeigen auf dieselbe Adresse.
Aber wieso haben bl und al verschiedene Ergebnisse drin? Der Wert von bl müsste doch auch in al sein...
https://www.flickr.com/photos/128517876@N07/18935745388/in/dateposted-public/.386 .model flat,stdcall .stack 4096 exitprocess proto, dwexitcode:dword .data zeiger dword ? myvar byte 1h,2h,3h,8h .code main proc mov zeiger, offset myvar mov esi, offset myvar mov al,byte ptr [zeiger] mov bl, byte ptr [esi] ret main endp end main
-
asd1 schrieb:
Der Wert von bl müsste doch auch in al sein
Ja, das ist nicht ganz logisch und kommt daher, dass der Prozessor das, was Du willst, mit einem einzigen Maschinenbefehl einfach nicht kann.
Bei `mov al,byte ptr [zeiger]` - so wie Du Dir das vorstellst - müsste er zunächst einen 4-Byte-Wert (Zeiger) an der Stelle 'zeiger' (ein Label, keine Variable) holen und dann von diesem Zeiger ein Byte holen. Eine doppelte Dereferenzierung sozusagen. Geht nicht, Du musst so etwas in mehrere Befehle verpacken. Es gibt nur einen Befehl, der einen Wert an einer Speicherstelle lädt, und dieser wird von MASM genommen. Nur mit Mühe kann man das Dereferenzierung nennen. Du kannst Dir auch die seltsame Dokumentation zu [] von Microsoft zur Brust nehmen.
Bei `mov al,byte ptr [esi]` geschieht tatsächlich eine Derefenzierung. Der Prozessor nimmt den Wert in ESI als Zeiger und lädt von dort ein Byte. ESI zeigt auf das Label myvar, also woanders hin als [zeiger]. Letzendlich lädt der Prozessor ein Byte von 'zeiger' nach AL und ein Byte von 'myvar' nach BL.
viele grüße
ralph
-
Hallo Ralph,
danke für Deine Antwort. Ich bin mir nicht ganz sicher, ob ich das alles verstanden habe.
Wie soll ich in Zukunft damit umgehen? Muss ich immer Zeiger in ein Register laden und dann mit z.B. [eax] dereferenzieren? Ich habe mal ein bisschen in meinen Büchern hin- und hergeblättert. Da steht immer [reg], wobei reg immer ein Register wie eax, ebx, esi, edi, etc. ist.