【问题标题】:unusual behaviour in delphi assembly blockdelphi 汇编块中的异常行为
【发布时间】:2011-06-24 11:25:32
【问题描述】:

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

这只是为了举例(moving [asdf]eax 并没有多大作用,但它适用于示例)。如果您查看该程序的程序集,您会发现

mov eax, [asdf]

变成了

mov eax, ds:[4]

(由 OllyDbg 表示)显然会崩溃。但是,如果您这样做:

var
    temp: TAsdf;
begin
    temp := asdf;

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

它变为 移动 eax,[ebp-4] 哪个有效。为什么是这样?我通常使用 C++ 并且习惯于使用这样的实例变量,可能是我使用错误的实例变量。

编辑:是的,就是这样。将mov eax, [asdf] 更改为mov eax, [Self.asdf] 可以解决此问题。对此感到抱歉。

【问题讨论】:

    标签: delphi assembly instance-variables basm


    【解决方案1】:

    在第一种情况下,mov eax,[asdf],汇编器将查找 asdf 并发现它是实例中偏移量为 4 的字段。因为您使用了没有基地址的间接寻址模式,所以它只会对偏移量进行编码(它看起来像 0 + asdf 对于汇编器)。如果你这样写:mov eax, [eax].asdf,它会被编码为 mov eax, [eax+4]。 (这里 eax 包含从调用者传入的 Self)。

    在第二种情况下,汇编程序将查找 Temp 并看到它是由 EBP 索引的局部变量。因为它知道要使用的基地址寄存器,所以它可以决定将其编码为 [EBP-4]。

    【讨论】:

      【解决方案2】:

      一个方法接收 EAX 寄存器中的Self 指针。您必须使用该值作为访问对象的基础值。所以你的代码会是这样的:

      mov ebx, TBlah[eax].asdf
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多