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.


Anmelden zum Antworten