Dead beef und andere texte in hex

Hallo,

da hier die meisten µController-Experten anzutreffen sind, stelle ich meine Frage hier:

Kennt jemand eine List von Wörtern, die mit den HEX-Buchstaben (evt. auch Zahlen) einen Sinn ergeben?

Wie Beispielsweise das „dead beef“, dass sich bei den meisten 16/32Bit-Systemen gut zur Vorbelegung von normalerweise ungenutztem Speicher eignet. Über all wo das zu lesen ist, hat niemand vorinitialisiert.

Gruß
achim

Hallo,

Kennt jemand eine List von Wörtern, die mit den HEX-Buchstaben
(evt. auch Zahlen) einen Sinn ergeben?

kenne ich nicht. Ich sehe auch überhaupt keinen Sinn darin.

Wie Beispielsweise das „dead beef“, dass sich bei den meisten
16/32Bit-Systemen gut zur Vorbelegung von normalerweise
ungenutztem Speicher eignet.

Das ist kompletter Unsinn. Die Vorbelegung dient nicht dazu, irgendwelchen Unsinn irgendwohin zu speichern, sondern eventuell verwendeten Speicher sicherheitshalber mit einem bestimmten Wert zu belegen, bei dem im Fehlerfall möglichst nichts passiert. Lauter Nullen sind da wohl der Normalfall, je nach Prozessor kann ein ‚Do-Nothing‘ aber viel sinnvoller sein. Wenn es aber überflüssig ist, lässt man den Speicher, wie er grad ist. Schont die Eproms bzw. Flashbausteine und natürlich auch die Entwicklungszeit und die Rechenzeit des Programms.

Über all wo das zu lesen ist, hat niemand vorinitialisiert.

Ebenfalls kompletter Unsinn. Es kommt ganz auf die jeweiligen Exemplare von Bauteilen an, was da ohne Initialisierung drinsteht. Lauter Nullen sind genauso möglich wie lauter ‚FF‘.

Gruß
loderunner

Hallo Achim,

wozu soll das gut sein? Hat dein Prozessor eine „DEAD BEEF“-Erkennung?

Für Daten gibt es nur 0 als sinnvolle Initialisierung: Zahlenwerte sind 0, Strings sind leer, Pointer sind invalid usw. Daher initialisieren Compiler, wenn sie denn überhaupt etwas initialisieren, alles mit 0.

Wenn dann der Prozessor 0 im Speicher auch noch als NOP interpretiert, ist das ganz nett, aber notwendig ist es nicht, deswegen führt ein wild gewordener Prozessor ja noch kein korrektes Programm aus, und irgenwo im Speicher findet er im Amoklauf immer eine Endlosschleife, ob initialisiert oder nicht.

Gruss Reinhard

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

wozu das ganze
Hallo Reinhard,

Beispiele für die Verwendung:

  • Default-Rückgabe eines Peripheriebausteins mit größerem Adressrange, z.B. ein FPGA mit Registern. Alle nicht genutzten Adressbereiche liefern per Default ein Pattern zurück, dass schnell erkannt werden kann. Wenn dann z.B. der gelesene Wert eines Sensors (=FPGA-Registers) „0xdead“ beträgt, kann das Zufall sein. Wenn mehrere Sensoren das Anzeigen, so wird möglicherweise auf die falschen Adressen zugegriffen

  • Vorbelegung von ungenutztem RAM-Speicher. Überall, wo dieses Pattern erhalten bleibt, ist a) RAM vorhanden (also nicht defekt) und b) kein Schreibzugriff erfolgt. Dies lässt sich im Debugger mit dem bloßen Auge relativ leicht erkennen.

  • Belegungen mit 0xffff und 0x0 sind meist schlechter geeignet, da 0 massiv vom C-Compiler (bzw. vom Startup-Code) verwendet wird, und zusammen mit 0xffff bei leeren Speichern, bei Sensoren als markanter Messwert und bei defekten Speicherbereichen (z.B kein Busteilnehmer) häufiger vorkommt.

  • Wenn Versionsnummern in Hexform angegeben und angezeigt werden müssen, so lassen sich markante Versionen u.U. besser darstellen, und sei es nur in einer Unterversionsstelle.

Gruß
achim

Hallo,
einfach irgendwelche Ram-Zellen zu verwenden, weil zufällig das reichtige drinsteht, anstatt einen tatsächlichen Test zu machen, ist genauso sinnbefreit wie das gleiche mit nicht vorhandenen Sensoren.
Die Kennzeichnung der Programmversionen kannst Du natürlich halten wie ein Dachdecker, aber wenn Du dafür eine Tabelle mit Ascii-Wörtern benötigst…

Wer so programmiert, sollte sich das Lehrgeld zurückzahlen lassen.

Gruß
loderunner

45054h owt
AFFE

Hallo achim,

der Speicher ist dazu da, vom Prozessor gelesen zu werden, nicht von dir, und ein Prozessor fängt mit DEAD BEEF soviel oder sowenig an wie mit irgendeinem anderen Muster auch. Das ganze wäre also nur für den unbedeutenden Zeitraum des Debuggens wenigstens annähernd sinnvoll.

Oder sitzt du jeden Morgen vor deinem PC und studierst 2 GB mit DEAD BEEF Muster, bevor du den Start des PC freigibst? Und bei deiner Waschmaschine auch? Na dann viel Spass.

Gruss Reinhard

  • Vorbelegung von ungenutztem RAM-Speicher. Überall, wo dieses
    Pattern erhalten bleibt, ist a) RAM vorhanden (also nicht
    defekt) und b) kein Schreibzugriff erfolgt. Dies lässt sich im
    Debugger mit dem bloßen Auge relativ leicht erkennen.

Hallo Achim,

dem liegt sowieso ein massiver Denkfehler zugrunde. Hat ein einfacher Controller einen Adressbereich von 64 kB, aber ein eingebautes RAM von 1 kB, so werden meistens die oberen Adressbits nicht auskodiert (warum auch, wenn man extern keinen Speicher anschliessen kann), und die 1 kB erscheinen 64mal im Adressraum. Da kannst du „DEADBEEF“ reinschreiben und auch wieder lesen, aber dummerweise sind es immer die gleichen 1 kB.

Um das zu erkennen, braucht man ein Muster mit der Länge einer Primzahl, deren Quadrat grösser ist als der Adressbereich. Das erfüllt dein DEADBEEF sowenig wie AFFE oder ähnliches. Speichertests sind halt nicht ganz so trivial wie du dir das vorstellst.

Gruss Reinhard

Zusammenfassung
Hallo Reinhard

unter http://de.wikipedia.org/wiki/Hexspeak gibt es einen interessanten Artikel zum Thema.

Der einzige wirklich konstruktive Beitrag kam von HICK, danke dafür.

Mit den Beispielen die ich genannt habe, kommt man sicher als Hobbyprogrammierer weniger in Berührung.

Deine Ausführung zum RAM ist natürlich richtig und unstrittig. Aber angenommen du möchtest Wissen, wieviel Heap oder Stack von dem 1 kB verwendet wurden. Das geht einfach durch Vorbelegung mit einem magic pattern, es geht auch anders.

Wenn Du einen Prozessor-Busteilnehmer entwickelst (z.B. per FPGA), der nicht den gesamten Adressbereich (sukkzessive) verwendet, welchen wert gibst Du für unused area zurück? Wenn alles funktioniert, die Beschreibung richtig ist, und der Prozessor-Programmierer alles richtig implementiert hat, sind 0x0000 oder 0xffff o.k… Bei einem Fehler sind sie unauffälliger als 0xAFFE. Welchen Wert verwendest Du standardmäßig?

Um das zu erkennen, braucht man ein Muster mit der Länge einer
Primzahl, deren Quadrat grösser ist als der Adressbereich. Das
erfüllt dein DEADBEEF sowenig wie AFFE oder ähnliches.
Speichertests sind halt nicht ganz so trivial wie du dir das
vorstellst.

Den ersten Speichertest vor Jahren bin ich ähnlich angegangen. Er lässt sich aber auch, falls es Dich interessiert, einfach gestalten, wenn man **eine fortlaufende Zahl in alle Adresen mit (1 bit = 1 alle anderen = 0) schreibt (und danach zurückliest). Bei 1MB also gerade mal 20 (*2) Zugriffe. Bei mehreren Speicherchips ist jeder entsprechend einzeln zu testen.

Gruß
achim

Gruss Reinhard**

Wenn Du einen Prozessor-Busteilnehmer entwickelst (z.B. per
FPGA), der nicht den gesamten Adressbereich (sukkzessive)
verwendet, welchen wert gibst Du für unused area zurück? Wenn
alles funktioniert, die Beschreibung richtig ist, und der
Prozessor-Programmierer alles richtig implementiert hat, sind
0x0000 oder 0xffff o.k… Bei einem Fehler sind sie
unauffälliger als 0xAFFE. Welchen Wert verwendest Du
standardmäßig?

Hallo Achim,

für mich heisst unused, das ist nichts, und dann gibt es auch nichts zu diskutieren: wenn an meinen Bussen sich keiner meldet, ergibt sich automatisch 0FFH, weil am Bus Pullup-Widerstände sind.

Wenn eine Peripherie einen Adressbereich nicht benutzt, hat sie sich dort auch nicht zu melden.

Gruss Reinhard

Hallo achim,

Mit den Beispielen die ich genannt habe, kommt man sicher als
Hobbyprogrammierer weniger in Berührung.

Deine Ausführung zum RAM ist natürlich richtig und unstrittig.
Aber angenommen du möchtest Wissen, wieviel Heap oder Stack
von dem 1 kB verwendet wurden. Das geht einfach durch
Vorbelegung mit einem magic pattern, es geht auch anders.

Der AFFE ist ja ein magic pattern, das ist eine reine Angelegenheit der Definition !
Den Stack kannst du mit 0x00 oder irgendetwas vorbelegen.
Ich verwende oft die Task-ID, dann kann ich sehen zu welchem der Stack gehört.

Zudem Zeigen die meisten Hexdumper zusätzlich die Werte noch als ASCII an. Man kann also auch Text als Vorbelegung verwenden. Unter CP/M war es z.B. üblich den Stackbereich mit „STACK“ zu befüllen.

Wenn Du einen Prozessor-Busteilnehmer entwickelst (z.B. per
FPGA), der nicht den gesamten Adressbereich (sukkzessive)
verwendet, welchen wert gibst Du für unused area zurück? Wenn
alles funktioniert, die Beschreibung richtig ist, und der
Prozessor-Programmierer alles richtig implementiert hat, sind
0x0000 oder 0xffff o.k… Bei einem Fehler sind sie
unauffälliger als 0xAFFE. Welchen Wert verwendest Du
standardmäßig?

Bei 8-Bit-Zugriffen erkennt man den AFFEn nicht unbedingt.
Im Rahmen einer Erweiterbarkeit des Bausteins haben 0x00 und 0xFF aber auch ihre Vorteile.

Wenn das Ganze Decimal angezeigt wird, erübrigt sich der AFFE aber …
Eine 0x00 hat aber oft den Vorteil, dass das Rechenergebnis eindeutig aus dem Rahmen fällt oder sogar eine DIV_ZERO Exception auslöst. Mit 0xFF ergibt sich meist auch ein Ergebnis, welches auffällig ist. Wenn sich der AFFE aber im normalen Wertebereich befindet, bekommst du kein auffälliges Ergebnis.

Das einzige Sichere ist, wenn du einen Bus mit Parity verwendest. Dann kannst du dein FPGA so konstruieren, dass ein Fehler erzeugt wird.

Den ersten Speichertest vor Jahren bin ich ähnlich angegangen.
Er lässt sich aber auch, falls es Dich interessiert, einfach
gestalten, wenn man eine fortlaufende Zahl
in alle Adresen mit (1 bit = 1 alle anderen = 0) schreibt (und
danach zurückliest). Bei 1MB also gerade mal 20 (*2) Zugriffe.
Bei mehreren Speicherchips ist jeder entsprechend einzeln zu
testen.

Als Decodertest, fülle ich das RAM mit der Speicheradresse, ist dann je nach CPU ein 16- oder 32-Bit-Wert.
Über Speichertests wurden schon ganze Bücher geschrieben und je nachdem welchen Aspekt testen will, muss man unterschiedliche Methoden verwenden.

MfG Peter(TOO)