2011-02-09 9 views
6

estoy corriendo en algún comportamiento extraño con ensamblador en línea de Delphi, como se ha demostrado en este muy corto y sencillo programa:comportamiento inusual en el bloque de montaje 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. 

Es sólo por el bien de ejemplo (mov ing [asdf] en eax no hace mucho, pero funciona para el ejemplo). Si nos fijamos en el conjunto de este programa, se verá que

mov eax, [asdf] 

se ha convertido en

mov eax, ds:[4] 

(representada por OllyDbg) que obviamente se bloquea. Sin embargo, si usted hace esto:

var 
    temp: TAsdf; 
begin 
    temp := asdf; 

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

Cambia a mov eax, [ebp-4] que trabaja. ¿Por qué es esto? Normalmente estoy trabajando con C++ y estoy acostumbrado a usar vars de instancia como ese, es posible que esté usando variables de instancia incorrectas.

EDITAR: Sí, eso fue todo. Cambiar mov eax, [asdf] a mov eax, [Self.asdf] soluciona el problema. Lo siento por eso.

Respuesta

10

Un método recibe el puntero Self en el registro EAX. Debe usar ese valor como el valor base para acceder al objeto. Por lo que su código sería algo como:

mov ebx, TBlah[eax].asdf 

Ver http://www.delphi3000.com/articles/article_3770.asp para un ejemplo.

12

En el primer caso, mov eax, [asdf], el ensamblador buscará asdf y descubrirá que es un campo de desplazamiento 4 en la instancia. Como usó un modo de direccionamiento indirecto sin una dirección base, solo codificará el desplazamiento (se ve como 0 + asdf para el ensamblador). Si lo hubieras escrito así: mov eax, [eax] .asdf, habría sido codificado como mov eax, [eax + 4]. (aquí eax contiene Self como pasado de la persona que llama).

En el segundo caso, el ensamblador buscará Temp y verá que es una variable local indexada por EBP. Como conoce el registro de dirección base que se utilizará, puede decidir codificarlo como [EBP-4].

Cuestiones relacionadas