Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   BigEndian/LittleEndian (mal wieder) (https://www.delphipraxis.net/178577-bigendian-littleendian-mal-wieder.html)

KFAF 15. Jan 2014 20:00

BigEndian/LittleEndian (mal wieder)
 
Hallo DelphiPraxis!

Ich habe vorhin die Testversion der XE5 heruntergeladen, spiele mit dem Gedanken sie mir zu kaufen. Das mit den neuen Compilern für Android lohnt sich wirklich und funktioniert auch blendend. Um ein paar Dinge zu testen habe ich da älteren Quelltext aus XE3 durchgejagt. Dabei bin ich neben dem Problem, dass es dort keine AnsiStrings mehr gibt, auch noch auf ein anderes gestoßen:

Bekanntlicherweise sind ARM-CPUs ja Big-Endian, wohingegen IA-64 u. 32 Modelle Little-Endian sind. Ich habe erst kürzlich eine eigene Library für Kryptographie mangels funktionierender (XE3...), weniger überladener Units geschrieben. Dabei habe ich z.B. SHA-1 und SHA-256 implementiert.

Benutzt habe ich dafür die offizielle Spezifikation, festgelegt im FIPS 180-2. Daraus habe ich auch die Konstanten übernommen und alle Testvektoren durchprobiert. Sie funktioniert einwandfrei. Das dürfte doch aber garnicht möglich sein, da mir erst jetzt auffällt, das alle Konstanten im FIPS laut Dokument in BigEndian angegeben wurden, bei mir also die Byte-Order komplett verkehrtherum sein sollte. Aber es klappt trotzdem! Auf dem ARM geht es jedoch nicht. Deshalb bin ich in erster Linie auch drauf gekommen.

Habe ich etwas übersehen? Die ganzen Shift und Rot Befehle müssten doch da kompletten Schwachsinn erzeugen!

mkinzler 15. Jan 2014 20:50

AW: BigEndian/LittleEndian (mal wieder)
 
Neuere ARM-Prozessoren ( ab ARMv7) unterstützen beides, d.h. das OS bestimmt die Byteorder: Bei iOS, Android und Windows Phone ist das little-endian.

himitsu 16. Jan 2014 00:09

AW: BigEndian/LittleEndian (mal wieder)
 
War der MAC (PowerPC) nicht mal BigEndian?
Ich frag mich grade, so ein wenig, was der jetzt nutzt, nachdem die auf Intel umgestiegen sind. (wobei IA64 wohl auch Beides kann) ... muß man da nun beim OSX aufpassen?


Es wäre ja auch blöd, wenn in einem OS je nach System dieses plötzlich umschalten würde, dan liefen die Programme ja nicht mehr überall.
Und für die Wiederverwendbarkeit von Code wäre es auch besser, wenn wie überall das Selbe nutzen würden.

PS: Auch für die Datenübertragung und Speicherung ist es einfacher, wenn überall nur ein System verwendet würde. (also vorallem bei unseren Delphi-Programmen, egal für welches System)

Furtbichler 16. Jan 2014 05:56

AW: BigEndian/LittleEndian (mal wieder)
 
Also ich glaube, das es innerhalb eines Systems keine Rolle spielt, denn was als $1,$2,$3,$4 abgelegt ist, wird auch so gelesen.

Das einzige Problem ist der Austausch von Strukturen, also Datentypen, die aus mehreren Bytes bestehen, zwischen zwei Endian-Systemen, denn da schicke ich z.B. [$1,$2],[$3,$4] (2 WORD) los und empfange [$2,$1],[$4,$3].

Oder habe ich die rosarote Brille auf?

JamesTKirk 16. Jan 2014 06:26

AW: BigEndian/LittleEndian (mal wieder)
 
In der Tat macht es in den allermeisten Fällen keinen Unterschied, ob ein Programm nun auf Little oder Big Endian läuft, da sich der Compiler darum kümmert, dass alles richtig läuft. Die einzigen Ausnahmen sind Binärdatenaustausch mit anderen Systemen oder der Zugriff auf Werte größer 1 Byte mit Hilfe von kleineren Werten.

In FPC gibt es (da dieser im Gegensatz zu Delphi durchaus Big Endian Systeme wie Power PC (mit Mac OS X, Linux, Amiga, GameCube, Wii, etc.), M68k (Linux, Amiga, etc.), ARM Big Endian (Linux) und MIPS Big Endian (Linux) unterstützt) daher öfters mal Code wie diesen hier:

Delphi-Quellcode:
{$ifdef ENDIAN_LITTLE}
  float64 = record
    case byte of
      1: (low,high : bits32);
      // force the record to be aligned like a double
      // else *_to_double will fail for cpus like sparc
      // and avoid expensive unpacking/packing operations
      2: (dummy : double);
  end;
{$else}
  float64 = record
      case byte of
        1: (high,low : bits32);
        // force the record to be aligned like a double
        // else *_to_double will fail for cpus like sparc
        2: (dummy : double);
  end;
{$endif}
Der Code stammt in diesem Fall aus der SoftFPU-Unit, zeigt aber, dass beim Aufbrechen eines
Delphi-Quellcode:
Double
in High und Low Teil darauf geachtet werden muss, dass man die beiden Teile richtig herum hat. Ähnliches gilt, wenn man mit nem
Delphi-Quellcode:
PByte
über einen Speicherbereich von z. B.
Delphi-Quellcode:
LongInt
wandert.

Und nochmal: Delphi unterstützt nur arm-android in Little Endian.

Gruß,
Sven

Furtbichler 16. Jan 2014 06:37

AW: BigEndian/LittleEndian (mal wieder)
 
Zitat:

Zitat von JamesTKirk (Beitrag 1243883)
...oder der Zugriff auf Werte größer 1 Byte mit Hilfe von kleineren Werten.

Stimmt.

himitsu 16. Jan 2014 09:51

AW: BigEndian/LittleEndian (mal wieder)
 
Oder auch ganz einfache Casts ... Beim Rumpointern sollte man da aufpassen.

Beim Little-Endian liegen die niedrigsten Teila am anfang, also ein Byte gelesen an der Adresse eines Word, ergibt den selben Wert, wenn im Word eine Zahl mit dem Wertebereichs eines Bytes drin ist.
Beim Big-Endin würde man dort dann 0 auslesen, weil man das höherwertigere Byte erwischt.

KFAF 16. Jan 2014 14:27

AW: BigEndian/LittleEndian (mal wieder)
 
himitsu, ich glaube du hast da was verkehrt.

Bei einen Little-Endian ist das niederwertigste Byte doch am Ende, bei einem Big-Endian am Anfang. D.h., dein Beispiel müsste genau anders herum sein: lese ich auf einem LE System das erste Byte von 48879 ($BEEF) bekomme ich BE, auf BE bekomm' ich EF.

Aber um wieder zum Thema zu kommen: Der Code funktioniert trotzdem, weil ...? Der Compiler die bitwise-Operationen sowiese auf jedem System nur auf eine Art ausführt?!

Folgendes Beispiel:
Zahl X liegt in einem WORD im Speicher.
Dann gilt : LE_X shr 8 = BE_X shr 8, weil die CPU die Werte sowieso in der selben Reihenfolge schieben muss (sonst wäre es ja kein shift sondern ein shift and rotate), und nur der Speicher anders ist, oder?

gammatester 16. Jan 2014 14:55

AW: BigEndian/LittleEndian (mal wieder)
 
Zitat:

Zitat von KFAF (Beitrag 1243984)
himitsu, ich glaube du hast da was verkehrt.

Bei einen Little-Endian ist das niederwertigste Byte doch am Ende, bei einem Big-Endian am Anfang. D.h., dein Beispiel müsste genau anders herum sein: lese ich auf einem LE System das erste Byte von 48879 ($BEEF) bekomme ich BE, auf BE bekomm' ich EF.

Was hast Du denn für ein komisches LE-System? Auf allen meinen LE-Windows/Intel-Systemen mit FPC und Delphi erhalte ich mit
Delphi-Quellcode:
var
  w: word;
  b: byte absolute w;
begin
  w := $BEEF;
  writeln(b);
end.
die Ausgabe 239 = $EF.

JamesTKirk 17. Jan 2014 06:57

AW: BigEndian/LittleEndian (mal wieder)
 
Um mal das Testprogramm von gammatester aufzugreifen:

Delphi-Quellcode:
program tendiantest;

var
  w: Word = $BEEF;
  b: Byte absolute w;
begin
  (* Hinweis: hexstr ist bei FPC eine Funktion in System, welche das
   *          gleiche macht wie IntToHex. Da SysUtils unter M68k noch
   *          bockt, konnte ich die jedoch nicht verwenden...
   *)
  Writeln(hexstr(b, 2));
  Writeln(hexstr(w shl 4, 4));
  Writeln(hexstr(w shr 4, 4));
end.
Ergebnis i386:

EF
EEF0
0BEE

Ergebnis m68k:

BE
EEF0
0BEE

Gruß,
Sven


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