unusual behaviour in delphi assembly block

I am running into some weird behaviour with Delphi's inline assembly, as demonstrated in this very short and simple program:

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.

It's just for the sake of example (moving [asdf] into eax doesn't do much, but it works for the example). If you look at the assembly for this program, you'll see that

mov eax, [asdf]

has been turned into

mov eax, ds:[4]

(as represented by OllyDbg) which obviously crashes. However, if you do this:

var
    temp: TAsdf;
begin
    temp := asdf;

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

It changes to mov eax, [ebp-4] which works. Why is this? I'm usually working with C++ and I'm used to using instance vars like that, it may be that I'm using instance variables wrong.

EDIT: Yep, that was it. Changing mov eax, [asdf] to mov eax, [Self.asdf] fixes the problem. Sorry about that.

6
задан PhiS 17 August 2011 в 08:31
поделиться