Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Methode nach ASM übersetzen (https://www.delphipraxis.net/199007-methode-nach-asm-uebersetzen.html)

NormanNG 18. Dez 2018 16:40

Methode nach ASM übersetzen
 
Delphi 10.2 32bit VCL

Hi,
die u.g. Methode Increment8_PAS soll aus Performance-Gründen nach ASM übersetzt werden.
Der erste Versuch Increment8_OLD hat irgendwie nicht gepasst und Zugriffsfehler produziert.
Mit der Version Increment8_NEW läuft das Programm und liefert auch korrekte Ergebnisse.

Da ich aber nicht wirklich gut in ASM bin, wäre es nett, wenn ein Assembler-Profi sich das nochmal ansieht :wink:
Vor allem wie und in welchen Registern die Parameter übergeben werden ist mir nicht so klar.

Vielen Dank für eure Mühe


Delphi-Quellcode:
type
  TWorker = class
    FCount: array[0..7] of UInt32;
   
    procedure Increment8_PAS(var Value; Add: UInt32);
    procedure Increment8_OLD(var Value; Add: UInt32);
    procedure Increment8_NEW(var Value; Add: UInt32);   
    :
  end;





procedure TWorker.Increment8_PAS(var Value; Add: UInt32);
type
  TData = packed array[0..7] of UInt32;

var
  HiBits: UInt32;
  Add8: UInt32;
  Carry: Boolean;

  procedure AddC(var Value: UInt32; const Add: UInt32; var Carry: Boolean);
  begin
    if Carry then
    begin
      Value := Value + 1;
      Carry := (Value = 0); // we might cause another overflow by adding the carry bit
    end
    else
      Carry := False;

    Value := Value + Add;
    Carry := Carry or (Value < Add); // set Carry Flag on overflow
  end;

begin
  HiBits := Add shr 29; // Save most significant 3 bits in case an overflow occurs
  Add8 := Add * 8;
  Carry := False;

  AddC(TData(Value)[0], Add8, Carry);
  AddC(TData(Value)[1], HiBits, Carry);
  AddC(TData(Value)[2], 0, Carry);
  AddC(TData(Value)[3], 0, Carry);
  AddC(TData(Value)[4], 0, Carry);
  AddC(TData(Value)[5], 0, Carry);
  AddC(TData(Value)[6], 0, Carry);
  AddC(TData(Value)[7], 0, Carry);

  if Carry then
    RaiseOverflowError;
end;

procedure TWorker.Increment8_ASM_OLD(var Value; Add: UInt32);
asm
    MOV ECX,EDX
    LEA EDX,[EDX * 8]
    SHR ECX,29
    ADD [EAX].DWord[ 0],EDX
    ADC [EAX].DWord[ 4],ECX
    ADC [EAX].DWord[ 8],0
    ADC [EAX].DWord[12],0
    ADC [EAX].DWord[16],0
    ADC [EAX].DWord[20],0
    ADC [EAX].DWord[24],0
    ADC [EAX].DWord[28],0
    JC RaiseOverflowError
end;

procedure TWorker.Increment8_ASM_NEW(var Value; Add: UInt32);
asm
    LEA EAX,[ECX*8]
    SHR ECX,29
    ADD [EDX].DWord[00],EAX
    ADC [EDX].DWord[04],ECX
    ADC [EDX].DWord[08],0
    ADC [EDX].DWord[12],0
    ADC [EDX].DWord[16],0
    ADC [EDX].DWord[20],0
    ADC [EDX].DWord[24],0
    ADC [EDX].DWord[28],0
    JC RaiseOverflowError
end;

freimatz 19. Dez 2018 12:21

AW: Methode nach ASM übersetzen
 
1. Es ist selten eine gute Idee wegen Performance Code in asm zu übersetzen.
2. Du könntest Dir den Assember-Code, den Delphi generiert hat, im Debugger anschauen
3. Schau dir mal die Direktiven inline und static an.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:05 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