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