AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Der DEC x32 ASM in x64/PurePascal Konvertierungsthread
Thema durchsuchen
Ansicht
Themen-Optionen

Der DEC x32 ASM in x64/PurePascal Konvertierungsthread

Ein Thema von Assertor · begonnen am 7. Jan 2012 · letzter Beitrag vom 17. Sep 2020
Antwort Antwort
Seite 2 von 7     12 34     Letzte »    
Benutzerbild von himitsu
himitsu

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

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 12:36
the caller writes to EDX what automatically clears the high DWORD of RDX
Und das ist auch immer definitiv so?
Nja, ein kleiner zusätzlicher Befehl, um das zu leeren/sicherzustellen, sollte auch nicht so sehr stören.



Für eine zukünftig unbestimmte Portierungen auf weitere Systeme/CPUs wäre jeweils eine (zusätzliche) PurePascal-Variante bestimmt kein Nachteil.
$2B or not $2B

Geändert von himitsu ( 8. Jan 2012 um 12:39 Uhr)
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#12

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 12:56
the caller writes to EDX what automatically clears the high DWORD of RDX
Und das ist auch immer definitiv so?
Ja, da der Prozessor bei einem "MOV EDX, xyz" immer das obere QWORD ablöscht (steht auch so in der x64 Instruction Set Beschreibung) und zudem die Win64 Calling Convention es vorschreibt den zweiten Parameter im RDX Register zu übergeben. Da steht nichts von EDX sondern RDX, also alle Bits.

Zitat:
Für eine zukünftig unbestimmte Portierungen auf weitere Systeme/CPUs wäre jeweils eine (zusätzliche) PurePascal-Variante bestimmt kein Nachteil.
Portabel ist der x64-Assembler Code natürlich nicht. Der ist speziell für Win64 geschrieben. Nur mit PurePascal bist du platformunabhängig.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#13

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 13:08
Ich stelle hier schonmal die nächste ASM Funktion zur Diskussion und Hijacke damit meinen eigenen Thread:
Delphi-Quellcode:
{ TODO : Consider implementing IDEAMul() as PurePascal if porting to FPC }
function IDEAMul(X, Y: LongWord): LongWord; assembler;
asm
       AND EAX,0FFFFh
       JZ @@1
       AND EDX,0FFFFh
       JZ @@1
       MUL EDX
       MOV EDX,EAX
       MOV ECX,EAX
       SHR EDX,16
       SUB EAX,EDX
       SUB CX,AX
       ADC EAX,0
       RET
@@1: LEA EAX,[EAX + EDX - 1]
       NEG EAX
end;
Hier die Win64 kompatible Version. Ein "MOV EAX,ECX" das den ersten Parameter in EAX kopiert, reicht aus und alles läuft wie gewohnt weiter.
Delphi-Quellcode:
function IDEAMul(X, Y: LongWord): LongWord; assembler;
asm
{$IFDEF CPUX64}
       MOV EAX,ECX
{$ENDIF CPUX64}
       AND EAX,0FFFFh
       JZ @@1
       AND EDX,0FFFFh
       JZ @@1
       MUL EDX
       MOV EDX,EAX
       MOV ECX,EAX
       SHR EDX,16
       SUB EAX,EDX
       SUB CX,AX
       ADC EAX,0
       RET
@@1: LEA EAX,[EAX + EDX - 1]
       NEG EAX
end;


UPDATE:
Und hier die PurePascal Version:
Delphi-Quellcode:
function IDEAMul(X, Y: LongWord): LongWord;
begin
  X := X and $FFFF;
  if X <> 0 then
  begin
    Y := Y and $FFFF;
    if Y <> 0 then
    begin
      X := X * Y;
      Result := X - (X shr 16);
      if Word(X) < Word(Result) then // carry flag check for "sub cx,ax"
        Inc(Result);
      Exit;
    end;
  end;
  Result := -(X + Y - 1);
end;

Geändert von jbg ( 8. Jan 2012 um 13:24 Uhr)
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#14

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 13:33
Nice, Andreas

Ob das "JC HashingOverflowError" so gut mit der strikten Aufrufkonvention unter x64 vereinbar ist, kann ich jetzt nicht beurteilen, da ich den Code des Sprungziels nicht kenne.
Delphi-Quellcode:
procedure HashingOverflowError;
begin
  raise EDECHashException.CreateRes(@sHashingOverflowError);
end;
Sollte imo also kein Problem sein.

Und wenn man schon 64bit Assembler hat kann man den auch gleich verwenden:
Delphi-Quellcode:
procedure Increment8(var Value; Add: LongWord);
asm
  SHL RDX, 3 // the caller writes to EDX what automatically clears the high DWORD of RDX
  ADD QWORD PTR [RCX ], RDX
  ADC QWORD PTR [RCX + 8], 0
  ADC QWORD PTR [RCX + 16], 0
  ADC QWORD PTR [RCX + 24], 0
  JC HashingOverflowError
end;
Das läuft in x64 Delphi, das RDX Register scheint dem FPC x64 Compiler aber nicht zu gefallen:
Zitat:
Error: Unknown identifier "RDX"
Gleich in der ersten Zeile bei SHL RDX, 3.

Nun gut, ich kenne FPC nicht weiter, möglicherweise ist dies bekannt und über Defines steuerbar. Ggf bleibt dort der Weg über PurePascal, was wegen der breiteren Unterstützung ja mit o.g. Delphi Code möglich ist.

Übrig sind noch gut 9 Assembler Funktionen, bis zur Lauffähigkeit. Wenn keine Einwände bestehen, würde ich diese gerne ebenfalls in diesem Thread zur Diskussion stellen.

@Andreas: Gerade schon ein Ping für Dein IDEAMul Post bekommen. Wow, Du bist schnell

Gruß
Assertor

P.S: Das wird eine lange Namensliste im ChangeLog - Attribution to Himitsu, Jaenicke, jbg, NamenLozer (alphabetisch)
Frederik
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#15

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread

  Alt 8. Jan 2012, 13:55
So, weiter geht es (*):
Delphi-Quellcode:
function DoRndBuffer(Seed: Cardinal; var Buffer; Size: Integer): Cardinal; assembler;
// comparable to Borlands Random() function
asm
      AND EDX,EDX
      JZ @@2
      AND ECX,ECX
      JLE @@2
      PUSH EBX
@@1: IMUL EAX,EAX,08088405H // 134775813
      INC EAX
      MOV EBX,EAX
      SHR EBX,24
      MOV [EDX],BL
      INC EDX
      DEC ECX
      JNZ @@1
      POP EBX
@@2:
end;

function RandomSystemTime: Cardinal; assembler;
// create Seed from Systemtime and PerformanceCounter
var
  SysTime: record
    Year: Word;
    Month: Word;
    DayOfWeek: Word;
    Day: Word;
    Hour: Word;
    Minute: Word;
    Second: Word;
    MilliSeconds: Word;
    Reserved: array [0..7] of Byte;
  end;
  Counter: record
    Lo,
    Hi: Integer;
  end;
asm
      LEA EAX,SysTime
      PUSH EAX
      CALL GetSystemTime
      MOVZX EAX,Word Ptr SysTime.Hour
      IMUL EAX,60
      ADD AX,SysTime.Minute
      IMUL EAX,60
      MOVZX ECX,Word Ptr SysTime.Second
      ADD EAX,ECX
      IMUL EAX,1000
      MOV CX,SysTime.MilliSeconds
      ADD EAX,ECX
      PUSH EAX
      LEA EAX,Counter
      PUSH EAX
      CALL QueryPerformanceCounter
      POP EAX
      ADD EAX,Counter.Hi
      ADC EAX,Counter.Lo
end;
Bei RandomSystemTime wird es tricky: QueryPerformanceCounter in RandomSystemTime ist natürlich ein No-Go für Crossplatform, also bleibt nur PurePascal.

Kennt da jemand was, was auch FPC versteht? Wie gesagt, ich arbeite nicht mit FPC, das hier ist nur für die Vielen, die danach fragen... Ich muß erstmal die RTL von XE2 durchsuchen, ob es eine Win/OSX Kapselung gibt.

Falls sich jemand fragt, wie viel noch kommt: die CRC Funktionen (5 an der Zahl).

@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...

Ihr seid klasse Während hier Code gepostet wird, kann ich schon an anderer Stelle weitermachen - so könnte die DEC 6.0 wirklich was werden!

Gruß
Assertor

(*) Kein Edit, für die Benachrichtigung - Andreas hat ja gerade einen Lauf
Frederik
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#16

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread

  Alt 8. Jan 2012, 15:31
Also für beide Funktionen ist überhaupt kein Assembler notwendig. Vor allem nicht für DoRndBuffer. Delphi generiert da fast haargenau den selben Assemblercode.
Was aber bei allen PurePascal Funktionen wichtig ist, ist dass {$RANGECHECKS OFF} genutzt wird, da sonst die gewünschten Arithmetiküberläufe zu Exceptions führen.

Delphi-Quellcode:
function RandomSystemTime: Cardinal;
// create Seed from Systemtime and PerformanceCounter
type
  TInt64Rec = packed record
    Lo, Hi: LongWord;
  end;
var
  {$IFDEF MSWINDOWS}
  SysTime: TSystemTime;
  {$ELSE}
  Hour, Minute, Second, Milliseconds: Word;
  {$ENDIF MSWINDOWS}
  Counter: TInt64Rec;
  Time: Cardinal;
begin
  {$IFDEF MSWINDOWS}
  GetSystemTime(SysTime);
  Time := ((Cardinal(SysTime.wHour) * 60 + SysTime.wMinute) * 60 + SysTime.wSecond) * 1000 + SysTime.wMilliseconds;
  QueryPerformanceCounter(Int64(Counter));
  {$ELSE}
  DecodeTime(Now, Hour, Minute, Second, Milliseconds);
  Time := ((Cardinal(Hour) * 60 + Minute) * 60 + Second) * 1000 + Milliseconds;
  Int64(Counter) := TStopwatch.GetTimeStamp; // uses System.Diagnostics
  {$ENDIF MSWINDOWS}

  Result := Time + Counter.Hi;
  Inc(Result, Ord(Result < Time)); // add "carry flag"
  Inc(Result, Counter.Lo);
end;

function DoRndBuffer(Seed: Cardinal; var Buffer; Size: Integer): Cardinal;
// comparable to Borlands Random() function
var
  P: PByte;
begin
  Result := Seed;
  P := @Buffer;
  if P <> nil then
  begin
    while Size > 0 do
    begin
      Result := Result * $08088405 + 1;
      P^ := Byte(Result shr 24);
      Inc(P);
      Dec(Size);
    end;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread

  Alt 8. Jan 2012, 15:34
@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...
Gute Frage

Selber arbeite ich nicht mit FPC (das Mistding Compilerchen mochte mich nicht ... vonwegen installieren und fertig).

Ich könnte höchsten mal sehn, ob ich noch was (wieder)finde.


Ach ja, mit kleinem h
Ich kenn zwar noch eine Himitsu, aber die hat es nicht so, mit dem Programmieren.
$2B or not $2B
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#18

AW: Der DEC x32 ASM in x64/PurePascal Konvertierungsthread

  Alt 8. Jan 2012, 15:57
Danke, Andreas!

Damit komme ich viel weiter, TStopWatch muß ich nur unter FPC ersetzen - aber da findet sich was.

Ich hänge die letzte Datei einfach mal an, dort sind 5 Funktionen zur CRC16/CRC32 Berechnung. Hagen hatte den Code seinerzeit sicherlich auf Performance optimiert.

In PurePascal wird das schon etwas schwieriger...

@Himitsu: Hattest Du nicht schonmal LHSZ für FPC bzw. x64 portiert? Ich meine mich da an irgendwas zu erinnern...
Gute Frage

Selber arbeite ich nicht mit FPC (das Mistding Compilerchen mochte mich nicht ... vonwegen installieren und fertig).

Ich könnte höchsten mal sehn, ob ich noch was (wieder)finde.

Ach ja, mit kleinem h
Ich kenn zwar noch eine Himitsu, aber die hat es nicht so, mit dem Programmieren.
Ok, himitsu - ist notiert

Falls Du die Anpassungen noch hast, gerne her damit. Es steht inzwischen fest, dass ich lediglich die CPU.pas, ASN1.pas und TypInfoEx.pas *nicht* mehr weiterpflege. Diese fliegen raus aus der DEC und werden in ein Tools Archiv verschoben - für den Crypto Einsatz sind diese auch nicht notwendig. Ja, ich weiß. ASN1... Trotzem, nicht für den üblichen DEC Anwender.

Tricky wird dann noch, überall die Kompatibilität herzustellen und zu prüfen (DEC 5.1 <> DEC 6.0), also bitte nicht in den nächsten Wochen mit einem Release rechnen. Ich poste dann, wenn ich Beta Tester suche (x32/x64, C++ Builder, Delphi, FPC, Win, Mac und Linux... puh!).

Viele Grüße
Assertor
Angehängte Dateien
Dateityp: pas DECCRC.pas (13,6 KB, 25x aufgerufen)
Frederik

Geändert von Assertor ( 8. Jan 2012 um 15:58 Uhr) Grund: Unit sollte man auch anhängen...
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#19

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 16:32
Zum Vergleich habe ich kurz die Assemblervariante auf 64-Bit umgeschrieben:
Delphi-Quellcode:
procedure Increment8(var Value; Add: LongWord); assembler;
asm
  MOV EBX,EDX
  LEA EDX,[EDX * 8]
  SHR EBX,29 // 12/13/2011 Fixed
  ADD [ECX].DWord[ 0],EDX
  ADC [ECX].DWord[ 4],EBX
  ADC [ECX].DWord[ 8],0
  ADC [ECX].DWord[12],0
  ADC [ECX].DWord[16],0
  ADC [ECX].DWord[20],0
  ADC [ECX].DWord[24],0
  ADC [ECX].DWord[28],0
  JC HashingOverflowError
end;
Der Test läuft 1:1 durch.
Nanu, ich dachte für 64-Bit gäbe es gar keinen Inline-Assembler mehr bei Delphi?
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#20

AW: 256 bit Integer Addition von ASM in PurePascal

  Alt 8. Jan 2012, 16:43
Nanu, ich dachte für 64-Bit gäbe es gar keinen Inline-Assembler mehr bei Delphi?
Doch, den gibt es. Man kann aber keinen Inline-Assembler mit Pascal-Funktionen mischen. Es heißt also entweder PurePascal- oder InlineAssembler-Funktion.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 7     12 34     Letzte »    

 

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 10:43 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