AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Assembler Routine - korrekt so?

Ein Thema von Stevie · begonnen am 16. Nov 2012 · letzter Beitrag vom 16. Nov 2012
Antwort Antwort
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

Assembler Routine - korrekt so?

  Alt 16. Nov 2012, 14:52
Delphi-Version: XE2
Kurze Hintergrundinfo:

Ich in gerade dabei, die DSharp Multicast Events etwas zu überarbeiten.
Momentan gibt es 3 verschiedene Methoden, ein Event aufzurufen (inline asm für Delphi 2010 und XE und jeweils pure pascal ab XE2 für 32-bit und 64-bit)

Da die pure Pascal Versionen ziemlich viel Overhead (erst die aus der ObjAuto gelieferten Parameter im auf TValue umbasteln um sie dann an die Rtti.Invoke Methode zu übergeben) und Wartungsaufwand mit sich bringen, hab ich mich mal hingesetzt und hab 2 reine asm Routinen geschrieben.

Da ich nicht gerade der Assembler Crack bin, wär es prima, wenn die, die sich damit etwas besser auskennen, mal drüber schauen könnten und mich auf Fehler und/oder Optimierungsmöglichkeiten hinweisen würden (speziell bei der 64bit Version, die ich mir nur mit Hilfe der Rtti Sourcen zusammen gefrickelt hab).

Delphi-Quellcode:
procedure InvokeMethod(const Method: TMethod; Parameters: PParameters; StackSize: Integer);
const
  PointerSize = SizeOf(Pointer);
type
  TParameters = packed record
{$IFDEF CPUX86}
    Registers: array[paEDX..paECX] of Cardinal;
    EAXRegister: Cardinal;
    ReturnAddress: Pointer;
{$ENDIF CPUX86}
    Stack: array[0..1023] of Byte;
  end;
{$IF Defined(CPUX86)}
asm
  push ebp
  mov ebp,esp
  push eax // ebp-4 = Method
  push ebx
  mov ebx, edx // ebx = Parameters

  // if StackSize > 0
  test ecx,ecx
  jz @@no_stack

  // stack address alignment
  add ecx,PointerSize-1
  and ecx,not(PointerSize-1)
  and ecx,$ffff
  sub esp,ecx

  // put stack address as second parameter
  mov edx,esp

  // put params on stack as first parameter
  lea eax,[ebx].TParameters.Stack

  call Move

@@no_stack:
  mov edx,[ebx].TParameters.Registers.dword[0]
  mov ecx,[ebx].TParameters.Registers.dword[4]
  mov ebx,[ebp-$04]
  mov eax,[ebx].TMethod.Data
  call [ebx].TMethod.Code

  pop ebx
  pop eax
  mov esp,ebp
  pop ebp
end;
{$ELSEIF Defined(CPUX64)}
asm
  .params 60
  mov [rbp+$200],Method
  mov [rbp+$208],Parameters
  test r8,r8
  jz @@no_stack

  // put params on stack as first parameter
  lea rcx,[Parameters].TParameters.Stack

  // put stack address as second parameter
  mov rdx,rsp

  call Move

  mov rdx,[rbp+$208]

@@no_stack:
  mov rcx,[rdx].TParameters.Stack.qword[0]
  mov r8,[rdx].TParameters.Stack.qword[16]
  mov r9,[rdx].TParameters.Stack.qword[24]

  movsd xmm0,[rdx].TParameters.Stack.qword[0]
  movsd xmm1,[rdx].TParameters.Stack.qword[8]
  movsd xmm2,[rdx].TParameters.Stack.qword[16]
  movsd xmm3,[rdx].TParameters.Stack.qword[24]

  mov rdx,[rdx].TParameters.Stack.qword[8]

  mov rax,[rbp+$200]
  lea rax,[rax]
  mov rcx,[rax].TMethod.Data
  call [rax].TMethod.Code
end;
{$IFEND}
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: Assembler Routine - korrekt so?

  Alt 16. Nov 2012, 15:05
Ich würde versuchen einfach was Fertiges zu nutzen.
RTTI hat es schon fertige Invoke-Methoden ... man müsste sich nur zur Laufzeit (beim Erstellen des MulticastEvents) eine TRTTIMethod (oder so) manuell zusammenstellen oder aus der TypeInfo einer EventMethode erstellen und könnte Dieses dann verwenden.


Beim Umstellen auf andere Zielplattformen würde Emba dann für dich den Rest mit anpassen.


[edit]
Der Nachteil wäre dann zwar, daß dieser Code dann nicht zu alten Delphis kompatibel ist, wo es die neue RTTI noch nicht gibt.


Hätte es erst richtig/komplett durchlesen sollen
Dann halt kein Pascal ._.
$2B or not $2B

Geändert von himitsu (16. Nov 2012 um 15:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Assembler Routine - korrekt so?

  Alt 16. Nov 2012, 15:14
Ich würde versuchen einfach was Fertiges zu nutzen.
RTTI hat es schon fertige Invoke-Methoden ... man müsste sich nur zur Laufzeit (beim Erstellen des MulticastEvents) dynamisch eine TRTTIMethod (oder so) zusammenstellen und könnte diese dann verwenden.


Beim Umstellen auf andere Zielplattformen würde Emba dann für dich den Rest mit anpassen.
Danke für den Hinweis - das ist doch in etwa das, was ich im Moment für XE2 und aufwärts mache

Problem 1.: Ich darf erstmal tonnenweise Bugs in verschiedenen Delphi Versionen in der Rtti reporten und fixen
Problem 2.: Für das dynamische Zusammenbauen einer TRttiMethod nur über die TypeInfo eines Events oder einer anonymen Methode ist noch mehr Fuckelei notwendig als für das da oben
Problem 3.: Die Invoke Methoden sind inperformant
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (16. Nov 2012 um 15:25 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz