Einzelnen Beitrag anzeigen

NormanNG

Registriert seit: 1. Feb 2006
294 Beiträge
 
Delphi 2007 Professional
 
#1

Methode nach ASM übersetzen

  Alt 18. Dez 2018, 17:40
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
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;
Gruß
Norman
  Mit Zitat antworten Zitat