Autor Beitrag
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 24.09.04 21:35 
Wie übersetzt man folgende Zeile nach Assembler?

ausblenden Delphi-Quelltext
1:
Raise EMathError.Crate(FmtInvalidDim);					


FmtInvalidDim ist eine String-Konstante, die als Fehlertext übergeben werden soll...

Der Delphi-Kompiler übersetzt das etwa so hier, Anmerkungen stehen als Kommentare dahinter:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
    MOV      ECX, $Irgendwas //Mir unbegrieflich
    MOV      DL, 1 //Mir klar, damit der Constructor konstruiert
    MOV      EAX, [$irgendwas] //Mir unbegrieflich
    CALL     Exception.Create
    CALL     @RaiseExcept //In Code nicht verfügbar, da Compiler-Interne Funktion



Moderiert von user profile iconChristian S.: Topic aus Sonstiges verschoben am Fr 08.10.2004 um 11:01

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Fr 24.09.04 22:27 
Zeile 3 sieht mir nach einem Parameter für den Kontruktor aus. ist das $irgendwas vielleicht ein Zeiger auf einen String oder sowas in der Art? Wenn der Konstruktor stdcall wäre, dann müsste an dieser Stelle glaube ich ein "mov eax, [$irgendwas]; push eax" stehen, aber ich glaube Delphi übergibt Variablen über die Register, sofern man "the delphi way of calling functions" benutzt *g* (bin mir da aber grad net so sicher; ich mein des hätt ich mal in meim quellcode gelesen)
Was Zeile 2 soll, weiß ich net genau, aber wenn du sagst, dass das der Konstruktor braucht, dann glaub ich dir das vom Felck weg ;)
Und Zeile 1 is mir auch absolut unbegreiflich... :D


MrSaint

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Fr 24.09.04 22:49 
nach nem bisl decompilen


mov ecx, xxx

ist das offset des textes als pchar

so dann in eax:

[eax - $c] muss die adresse von tobject.NewInstance sein
[eax -$1c] muss die adresse von tobject.AfterConstrucion (oder ne funktion mit nem simplen ret)
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 25.09.04 00:21 
Zeile 1 verwundert mich aber:

Wenn ich in meinem Source
ausblenden Delphi-Quelltext
1:
MOV ECX, OFFSET FmtInvalidDim					

schreib, kommt was total anderes raus, als das was Delphi geproggt hat.

@EAX: Also müsste EAX der Zeiger auf die zu erzeugende Objekt-Klasse sein?

@DL: Muss eins sein, damit der Konstruktor eine Objekt-Referenz erzeugt. Ist bei jedem (internen) folgenden Aufruf 0, damit kein neues Objekt angelegt wird.

Aber wo ich besonders dran Scheitere ist die Sache mit dem Raise-en dieser erzeugten Exception ... Wie gesagt kann ich diese Routine @RaiseExcept ja leider nicht direkt aufrufen ... :(

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: So 26.09.04 12:51 
hab da mal nen bisl probiert
hier das was ich rausgefunden habe

der text der angezeigt werden soll

ausblenden Delphi-Quelltext
1:
2:
    mov ecx, offset FmtInvalidDim
    mov ecx, [ecx]


wobei FmtInvalidDim nen string ist

in eax wird nen offset von ne mstruct geschrieben
wo eax-$28 die länge des textes steht
in eax-$3c steht die adresse für den text der unit EMathbla
wobei am ersten byte die länge des textes steht

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
  unittext^ := 4;
  unittext := pointer(integer(unittext)+1); unittext^ := byte('H');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('E');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('H');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('E');

  p := pointer(integer(p)+$2c);


bei der excpetion würde nun stehen
"bla bla fehler in der unit: HEHE"

hier mal alle funktionen nachgebaut, trotzdem funzt es nbet weil ich ncoh net den aufbau der struktur kenne
am besten mal kernel32.RaiseException angucken weil damit kann man die std exceptions machen, um aber selbst nen text festzulegene muss du dich mal damit auseinandersetzen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
var FmtInvalidDim: string = 'hallo kleines';

procedure classcreate;
asm
  PUSH EDX
  PUSH ECX
  PUSH EBX
  TEST DL,DL
  JL @jmp1
  CALL tobject.newinstance;
  @jmp1:
  XOR EDX,EDX
  LEA ECX,DWORD PTR SS:[ESP+$10]
  MOV EBX,DWORD PTR FS:[EDX]
  MOV DWORD PTR DS:[ECX],EBX
  MOV DWORD PTR DS:[ECX+$8],EBP
  MOV DWORD PTR DS:[ECX+$4], offset @hae
  MOV DWORD PTR DS:[ECX+$C],EAX
  MOV DWORD PTR FS:[EDX],ECX
  POP EBX
  POP ECX
  POP EDX
  RETN
  @hae:
//JMP HandleAnyException
end;

procedure error;
begin
end;

procedure GetMemx;
asm
  PUSH EBX
  TEST EAX,EAX
  JLE @jmp1
  CALL SysGetMem
  MOV EBX,EAX
  TEST EBX,EBX
  JNZ @jmp2
  MOV AL,1
  CALL Error
  JMP @jmp2
  @jmp1:
  XOR EBX,EBX
  @jmp2:
  MOV EAX,EBX
  POP EBX
  RETN
end;

procedure NewAnsiString;
asm
  TEST EAX,EAX
  JLE @jmp1
  PUSH EAX
  ADD EAX,$0A
  AND EAX,$FFFFFFFE
  PUSH EAX
  CALL GetMemx
  POP EDX
  MOV WORD PTR DS:[EDX+EAX-$2],0
  ADD EAX,8
  POP EDX
  MOV DWORD PTR DS:[EAX-$4],EDX
  MOV DWORD PTR DS:[EAX-$8],1
  RETN
  XOR EAX,EAX
  @jmp1:
  RETN
end;

procedure Move;
asm
  PUSH ESI
  PUSH EDI
  MOV ESI,EAX
  MOV EDI,EDX
  MOV EAX,ECX
  CMP EDI,ESI
  JA @jmp1
  JE @jmp2
  SAR ECX,$2
  JS @jmp2
  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
  MOV ECX,EAX
  AND ECX,$3
  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  POP EDI
  POP ESI
  RETN
  @jmp1:
  LEA ESI,DWORD PTR DS:[ECX+ESI-$4]
  LEA EDI,DWORD PTR DS:[ECX+EDI-$4]
  SAR ECX,$2
  JS @jmp2
  STD
  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
  MOV ECX,EAX
  AND ECX,$3
  ADD ESI,$3
  ADD EDI,$3
  REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
  CLD
  @jmp2:
  POP EDI
  POP ESI
  RETN
end;

procedure FreeMem;
begin
end;

procedure lstrasg;
asm
  TEST EDX,EDX
  JE @jmp1
  MOV ECX, DWORD PTR DS:[EDX-$8]
  INC ECX
  JG @jmp1
  PUSH EAX
  PUSH EDX
  MOV EAX,DWORD PTR DS:[EDX-$4]
  CALL NewAnsiString
  MOV EDX,EAX
  POP EAX
  PUSH EDX
  MOV ECX,DWORD PTR DS:[EAX-$4]
  CALL Move
  POP EDX
  POP EAX
  JMP @jmp1
  LOCK INC DWORD PTR DS:[EDX-$8]
  @jmp1:
  XCHG DWORD PTR DS:[EAX],EDX
  TEST EDX,EDX
  JE @jmp2
  MOV ECX,DWORD PTR DS:[EDX-$8]
  DEC ECX
  JL @jmp2
  LOCK DEC DWORD PTR DS:[EDX-$8]
  JNZ @jmp2
  LEA EAX,DWORD PTR DS:[EDX-$8]
  CALL FreeMem
  @jmp2:
  RETN
end;

procedure AfterConstruction;
asm
  PUSH EBX
  MOV EBX,EAX
  MOV EAX,EBX
  MOV EDX,DWORD PTR DS:[EAX]
  //CALL DWORD PTR DS:[EDX-1C]
  MOV EAX,EBX
  POP EBX
  RETN
end;

procedure exceptcreate;
asm
  PUSH EBX
  PUSH ESI
  PUSH EDI
  TEST DL,DL
  JE @jmp1
  ADD ESP,-$10
  CALL classcreate
  @jmp1:
  MOV ESI,ECX
  MOV EBX,EDX
  MOV EDI,EAX
  LEA EAX,DWORD PTR DS:[EDI+$4]
  MOV EDX,ESI
  CALL Lstrasg
  MOV EAX,EDI
  TEST BL,BL
  JE @jmp2
  CALL AfterConstruction
  POP DWORD PTR FS:[0]
  ADD ESP,$C
  @jmp2:
  MOV EAX,EDI
  POP EDI
  POP ESI
  POP EBX
  RETN
end;

procedure showexcept;
asm
  OR EAX,EAX
  JNZ @jmp1
  MOV EAX,$0D8
  //CALL Project1.00403E04
  POP EDX
  @jmp1:
  PUSH ESP
  PUSH EBP
  PUSH EDI
  PUSH ESI
  PUSH EBX
  PUSH EAX
  PUSH EDX
  PUSH ESP
  PUSH $7
  PUSH $1
  PUSH $0EEDFADE
  PUSH EDX
  JMP RaiseException
end;

procedure TForm1.Button1Click(Sender: TObject);
var p: pointer;
    i: ^integer;
    unittext: ^byte;
begin
  getmem(p,$800);
  zeromemory(p,$800);
  copymemory(p,pointer($00406ff0-$2c),$2c);


  getmem(unittext,10);

  i := p;
  i^ := integer(unittext);

  unittext^ := 4;
  unittext := pointer(integer(unittext)+1); unittext^ := byte('H');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('E');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('H');
  unittext := pointer(integer(unittext)+1); unittext^ := byte('E');

  p := pointer(integer(p)+$2c);

  asm
    mov ecx, offset FmtInvalidDim
    mov ecx, [ecx]
    mov dl, $1
    mov eax, [p]
    call exceptcreate
    call showexcept
  end;
end;
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 26.09.04 19:09 
Gut, soviel zum Construieren der Exception. Und das eigentliche Aufrufen? Die Function RaiseException, die in der System.pas aus der Kernel32.dll eingebunden wird wird wohl auf eher weniger was damit zu tun haben, da die für Win32-Exceptions gedacht ist, nicht für die Delphi-Exceptions.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: So 26.09.04 21:42 
doch die hat was damit zu tun
der parameter muss $0EEDFADE sein bei kernel.RaiseExcpetion, dann kann man selbst über parameter bestimmten welcher text ausgegeben werden soll
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 07.10.04 17:36 
Hab jetzt auch ne Möglichkeit gefunden, die EIGENTLICH funktionieren sollte.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
asm
  //Raise EMathError.Create(FmtInvalidDim);
  MOV    ECX, [FmtInvalidDim]       //Load the Error Text
  MOV    DL, $01              //Tell the constructor to reserve some memory
  MOV    EAX, [EMathError]        //Tell what kind of Exception to create
  CALL    Exception.Create        //Instantiate the Exception
  CALL    _RaiseExcept           //Raise the Exception
end;


Das einzige Problem, was es mit diesem Source gibt, ist hier beschrieben.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Fr 08.10.04 10:50 
also ich habe mir das nochmal genauer angeguckt,

folgendermaßen:

die wichtige funktion ist RaiseException
aus der kernel32.dll

diese funktion hat als

1. parameter die art der exception, eine delphi exception hat den wert
$0EEDFADE alle weiteren findest du bei msdn.microsoft.com/l...getexceptioncode.asp

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
const { copied from xx.h }
  cContinuable        = 0;
  cNonContinuable     = 1;
  cUnwinding          = 2;
  cUnwindingForExit   = 4;
  cUnwindInProgress   = cUnwinding or cUnwindingForExit;
  cDelphiException    = $0EEDFADE;
  cDelphiReRaise      = $0EEDFADF;
  cDelphiExcept       = $0EEDFAE0;
  cDelphiFinally      = $0EEDFAE1;
  cDelphiTerminate    = $0EEDFAE2;
  cDelphiUnhandled    = $0EEDFAE3;
  cNonDelphiException = $0EEDFAE4;
  cDelphiExitFinally  = $0EEDFAE5;
  cCppException       = $0EEFFACE{ used by BCB }
  EXCEPTION_CONTINUE_SEARCH    = 0;
  EXCEPTION_EXECUTE_HANDLER    = 1;
  EXCEPTION_CONTINUE_EXECUTION = -1;



der 2. parameter sollte EXCEPTION_EXECUTE_HANDLER sein, d.h. die excpeion geht an den handler
der 3. parameter ist die anzahl der parameter der exception handler bekommt
der 4. parameter ist die adresse wo die einzelnen parameter für den exception handler stehen

delphi hat einen eigenen SEH, der am anfang installiert wird, eine 'cDelphiException = $0EEDFADE' benötigt 7 parameter ->

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  TRaisedException = packed record
    RefCount: Integer;
    ExceptObject: TObject;
    ExceptionAddr: Pointer;
    HandlerEBP: LongWord;
    Flags: LongWord;
    Cleanup: Pointer;
    Prev: PRaisedException;
    ReleaseProc: Pointer;
  end;

PS: frag mich net warum das 8 sind delphi übergibt der kernel funktion nen $07 ;>

aber um eine eigene exception aufzurufen kannst dir besser nen eigenen exception handler installieren
das geht über

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
asm
  push fs:[0]
  push esp
  mov fs:[0], offset myexceptionhandler
end;


der eigentlich exception handler hat folgenden aufbau:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
function except_handler(
     ExceptionRecord: P_EXCEPTION_RECORD;
     EstablisherFrame: pointer;
     ContextRecord: P_CONTEXT;
     DispatcherContext: pointer): integer; cdecl;


aus dem exception handler kannste dann selber die parameter auslesen über ExceptionRecord
für $0EEDFADE solltest dir dann selbst ne eigene zahl nehmen

-> also was delphi macht ist genau

nen exception handler installieren
bei ner raise exception vom user wird dann CreateException oder wie funktion heißt aufgerufen
dann kernel32.dll Raisexception mit den 7 parametern

der eigentliche delphi SEH bekommt dann diese exception und macht nichts anderes als zu schauen ob der parmeter $0EEDFADE, wenn so weiß der delphi SEH das es eine delphi raise exception ist, es werden die 7 parmeter auslesen und dann einfach ne messagebox angezeigt

also im endeffekt ist -> raise einfach ne msg box :P

bsp.:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure raiseerror(oo: tobject; s: string); stdcall;
var retn: integer;
begin
  asm
    mov eax, [ebp+4]
    mov [retn], eax
  end;
  dec(retn,5);
  messagebox(0,pchar('In der Unit: "'+oo.ClassName+'" an adresse: 0x'+inttohex(retn,8)+
    ' mit der meldung: "'+s+'" aufgetreten'),'Exception',MB_ABORTRETRYIGNORE);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  raiseerror(EMathError.NewInstance,'bla');
end;
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 09.09.05 19:39 
Manchmal sind die Dinge doch soooo einfach:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
asm
    //Raise EMathError.Create(FmtInvalidDim);
    MOV     ECX, [FmtInvalidDim]           //Load the Error Text
    MOV     DL, $01                     //Tell the constructor to reserve some memory
    MOV     EAX, [EMathError]              //Tell what kind of Exception to create
    CALL    Exception.Create               //Instantiate the Exception
    CALL    System.@RaiseExcept        //Raise the Exception
end;


Dann funktioniert es!!!

Auszug aus der Hilfe bzgl. Assembler-Direktiven:
Zitat:
Zwei zusätzliche Direktiven ermöglichen dem Assembler-Code den Zugriff auf dynamische und virtuelle Methoden: VMTOFFSET und DMTINDEX.

VMTOFFSET ruft den Byte-Offset des Tabelleneintrags mit dem virtuellen Methodenzeiger des virtuellen Methodenarguments vom Anfang der virtuellen Methodentabelle (VMT) ab. Diese Direktive benötigt einen vollständig angegebenen Klassennamen mit einem Methodennamen als Parameter (beispielsweise TExample.VirtualMethod) oder einen Schnittstellennamen und einen Schnittstellenmethodennamen.

DMTINDEX ruft den dynamischen Methodentabellenindex der übergebenen dynamischen Methode ab. Diese Direktive benötigt ebenfalls einen vollständig angegebenen Klassennamen mit einem Methodennamen als Parameter, (z. B. TExample.DynamicMethod). Sie rufen die dynamische Methode mit System.@CallDynaInst mit dem (E)SI-Register auf, das den von DMTINDEX abgerufenen Wert enthält.

Hinweis

Methoden mit der message-Direktive werden als dynamische Methoden implementiert und können auch mit DMTINDEX aufgerufen werden. Beispiel:

ausblenden Delphi-Quelltext
1:
2:
3:
    TMyClass = class
      procedure x; message MYMESSAGE;
    end;


Das folgende Beispiel verwendet sowohl DMTINDEX als auch VMTOFFSET für den Zugriff auf dynamische und virtuelle Methoden:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
program Project2;

type
  TExample = class
    procedure DynamicMethod; dynamic;
    procedure VirtualMethod; virtual;
  end;

procedure TExample.DynamicMethod;
begin

end;

procedure TExample.VirtualMethod;
begin

end;

procedure CallDynamicMethod(e: TExample);
asm
  // ESI-Register speichern
  PUSH    ESI

  // Instanzzeiger muss in EAX vorliegen
  MOV     EAX, e

  // DMT-Eintragsindex muss in (E)SI vorliegen
  MOV     ESI, DMTINDEX TExample.DynamicMethod
  // Aufruf der Methode
  CALL    System.@CallDynaInst

  // ESI-Register wiederherstellen
  POP ESI
end;

procedure CallVirtualMethod(e: TExample);
asm
  // Instanzzeiger muss in EAX vorliegen
  MOV     EAX, e

  // VMT-Tabelleneintrag abrufen
  MOV     EDX, [EAX]

  // Aufruf der Methode bei Offset VMTOFFSET
  CALL    DWORD PTR [EDX + VMTOFFSET TExample.VirtualMethod]

end;

var
  e: TExample;

begin
  e := TExample.Create;
  try
    CallDynamicMethod(e);
    CallVirtualMethod(e);
  finally
    e.Free;
  end;
end.


Damit wäre wieder einmal ein Rätsel entmystifiziert ...

Habs getestet, der Source funzt so wirklich. Bin heut nur durch Zufall drauf gestoßen, hab eigentlich was ganz anderes gesucht ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.