德尔福装配块中的异常行为

我正在使用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.

这仅仅是为了举例(将[asdf]移动到eax中并没有做太多,但它适用于该示例).如果你看看这个程序的程序集,你会看到

mov eax,[asdf]

已经变成了

mov eax,ds:[4]

(由OllyDbg代表)显然崩溃了.但是,如果你这样做:

var
    temp: TAsdf;
begin
    temp := asdf;

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

它变成了
mov eax,[ebp-4]
哪个有效.为什么是这样?我通常使用C而且我习惯使用类似的实例变量,可能是因为我使用的是实例变量错误.

编辑:是的,就是这样.将mov eax,[asdf]更改为mov eax,[Self.asdf]可以解决问题.对于那个很抱歉.

解决方法

方法接收EAX寄存器中的Self指针.您必须使用该值作为访问对象的基值.所以你的代码将是这样的:
mov ebx,TBlah[eax].asdf

有关示例,请参见http://www.delphi3000.com/articles/article_3770.asp.

相关文章

ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:...
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂...
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (By...