2011-02-09 13 views
6

używam do niektórych dziwne zachowanie z montażem inline Delphi, jak wykazano w tym bardzo krótkim i prostym programie:nietypowe zachowanie w bloku montażowym Delphi

program test; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TAsdf = class 
    public 
     int: Integer; 
    end; 

    TBlah = class 
    public 
     asdf: TAsdf; 

     constructor Create(a: TAsdf); 

     procedure Test; 
    end; 

constructor TBlah.Create(a: TAsdf); 
begin 
    asdf := a; 
end; 

procedure TBlah.Test; 
begin 
    asm 
     mov eax, [asdf] 
    end; 
end; 

var 
    asdf: TAsdf; 
    blah: TBlah; 

begin 
    asdf := TAsdf.Create; 

    blah := TBlah.Create(asdf); 

    blah.Test; 

    readln; 
end. 

To właśnie przez wzgląd na przykład (mov ing [asdf] do eax nie robi wiele, ale działa na przykład). Jeśli spojrzeć na Zgromadzeniu do tego programu, zobaczysz, że

mov eax, [asdf] 

został przekształcony

mov eax, ds:[4] 

(reprezentowane przez OllyDbg), które oczywiście wywala. Jednakże, jeśli to zrobić:

var 
    temp: TAsdf; 
begin 
    temp := asdf; 

    asm 
     int 3; 
     mov eax, [temp]; 
    end; 

zmienia się mov eax, [ebp-4] który działa. Dlaczego to? Zwykle pracuję z C++ i jestem przyzwyczajony do używania takich vars instancji, może to być, że używam zmiennych instancji źle.

EDYCJA: Tak, to było to. Zmiana mov eax, [asdf] na mov eax, [Self.asdf] rozwiązuje problem. Przepraszam za to.

Odpowiedz

10

Metoda otrzymuje wskaźnik Self w rejestrze EAX. Musisz użyć tej wartości jako wartości podstawowej do uzyskania dostępu do obiektu. Twój kod będzie wyglądał następująco:

mov ebx, TBlah[eax].asdf 

Zobacz przykład na przykład http://www.delphi3000.com/articles/article_3770.asp.

12

W pierwszym przypadku mov eax, [asdf], asembler będzie szukał asdf i odkrył, że jest to pole przesunięcia 4 w instancji. Ponieważ korzystałeś z pośredniego trybu adresowania bez adresu bazowego, kodował on tylko offset (wygląda na to, że 0 + asdf do asemblera). Czy napisałeś to tak: mov eax, [eax] .asdf, byłoby zakodowane jako mov eax, [eax + 4]. (tutaj eax zawiera Self jako przekazany od dzwoniącego).

W drugim przypadku asembler wyszuka Temp i zobaczy, że jest lokalną zmienną indeksowaną przez EBP. Ponieważ zna rejestr adresów bazowych do użycia, może zdecydować o kodowaniu go jako [EBP-4].