Warum sind kryptische Kurzbezeichner in der Low-Level-Programmierung immer noch so verbreitet?


64

Früher gab es sehr gute Gründe, Instruktions- / Registernamen kurz zu halten. Diese Gründe gelten nicht mehr, aber kurze kryptische Namen sind in der Low-Level-Programmierung immer noch weit verbreitet.

Warum ist das? Liegt es nur daran, dass alte Gewohnheiten schwer zu brechen sind, oder gibt es bessere Gründe?

Zum Beispiel:

  • Atmel ATMEGA32U2 (2010?): TIFR1(Anstelle von TimerCounter1InterruptFlag), ICR1H(anstelle von InputCapture1High), DDRB(anstelle von DataDirectionPortB) usw.
  • .NET CLR-Befehlssatz (2002): bge.s(anstelle von branch-if-greater-or-equal.short) usw.

Sind die längeren, nicht kryptischen Namen nicht einfacher zu bearbeiten?


Beachten Sie beim Beantworten und Abstimmen Folgendes. Viele der hier vorgeschlagenen möglichen Erklärungen gelten gleichermaßen für die Programmierung auf hoher Ebene, und dennoch besteht der Konsens im Großen und Ganzen darin, nicht kryptische Namen zu verwenden, die aus einem oder zwei Wörtern bestehen (allgemein verstandene Akronyme ausgenommen).

Wenn es bei Ihrem Hauptargument um physischen Platz in einem Papierdiagramm geht , beachten Sie bitte, dass dies absolut nicht für Assemblersprache oder CIL gilt. Ich würde mich freuen, wenn Sie mir ein Diagramm zeigen, in dem knappe Namen passen, aber lesbare die Darstellung verschlechtern . Aus eigener Erfahrung in einem Halbleiterunternehmen ohne Fabless passen lesbare Namen gut zusammen und führen zu besser lesbaren Diagrammen.

Was ist die Kern Sache , die über Low-Level - Programmierung unterschiedlich ist , wie Hochsprachen im Gegensatz zu , die die lapidaren kryptischen Namen wünschenswert in Low-Level machen aber nicht High-Level - Programmierung?


82
Antwort: Damit Sie das Gefühl haben, in einer einfachen Sprache zu programmieren.
Thomas Eding

5
Kryptisch ist relativ. JSRist dreimal länger als der Opcode, den es darstellt ( $20auf einem 6502) und auf einen Blick wesentlich einfacher zu verstehen.
Blrfl

4
Ich bin ein bisschen enttäuscht, weil die richtige Antwort da ist, aber es ist definitiv nicht die akzeptierte. Schaltpläne und solche Interrupts werden normalerweise nach Leitungen benannt, mit denen sie verknüpft sind, und in einem Schaltplan, den Sie nicht ausführlich verwenden möchten, ist dies keine gute oder praktische Vorgehensweise. Zweitens, weil Sie die Antworten nicht mögen, heißt das nicht, dass sie nicht korrekt sind.
Jeff Langemeier

4
@gnat: Versuch set Accumulator32 to BaseIndex32? Das einfache Erweitern der traditionellen Abkürzungen ist nicht die einzige Möglichkeit, etwas lesbarer zu machen.
Timwi

1
"Wenn es bei Ihrem Hauptargument um physischen Raum auf einem Papierdiagramm geht", geht es nicht darum, dass eine gute Benennung andere Dinge berücksichtigt als nur die Klarheit des Namens (ich habe in meiner Antwort einige angegeben, Diagramme - einschließlich der darauf gezeichneten) Eine Tafel - ist nur eines dieser anderen Dinge), und diese Klarstellung ist eine relative Sache (Vertrautheit hilft der Klarheit, zum Beispiel bei jeder Wahl).
Programmierer

Antworten:


106

Der Grund, warum die Software diese Namen verwendet, liegt darin, dass die Datenblätter diese Namen verwenden. Da Code auf dieser Ebene ohnehin nur schwer ohne das Datenblatt zu verstehen ist, ist es äußerst wenig hilfreich, Variablennamen zu erstellen, die Sie nicht durchsuchen können.

Das wirft die Frage auf, warum Datenblätter Kurznamen verwenden. Dies liegt wahrscheinlich daran, dass Sie die Namen häufig in Tabellen wie der folgenden darstellen müssen, in denen kein Platz für 25-stellige Bezeichner vorhanden ist:

TIFR1-Tabelle aus Datenblatt

Außerdem sind Dinge wie Schaltpläne, Pin-Diagramme und PCB-Siebdrucke oft sehr beengt.


7
Außerdem spricht diese Antwort nicht wirklich die reine Software-Seite an, z. B. CLR, JVM, x86 usw. :)
Timwi

12
@romkyns: Es ist etwas offensichtlicher, warum diese Kurznamen verwendet wurden, als Sie diese Datenblätter tatsächlich durchgelesen haben. Die Datenblätter für einen Mikrocontroller, die ich zur Hand habe, haben ungefähr 500 Seiten, selbst wenn die Kurznamen durchgehend verwendet werden . Die Breite der Tabellen würde sich über mehrere Seiten / Bildschirme erstrecken, wenn wir längere Namen verwenden, was die Verwendung einer Referenz sehr unpraktisch macht.
In silico

27
@romkyns: Längere Namen sind gleichermaßen durchsuchbar, aber "nicht native". Wenn Sie eingebetteten Ingenieuren zuhören, sagen sie tatsächlich "tiffer zero" und nicht "timer zero's interrupt flag". Ich bezweifle, dass Webentwickler HTTP, HTML oder JSON in ihren Methodennamen erweitern.
TMN

6
@ KarlBielefeldt ähm, was? :) Offensichtlich werde ich es nicht im aktuellen Datenblatt finden, weil sie stattdessen für den Kurznamen gingen. Das stützt nicht die Behauptung, dass Kurznamen im Geringsten durchsuchbarer sind ...
Roman Starkov

5
Es sind nicht nur Datenblätter, die nur über begrenzten Speicherplatz verfügen, sondern auch die Schaltpläne. Alle diese logischen Komponenten haben Leitungen, die mit anderen Komponenten verbunden werden müssen. "TimerCounter1InteruptFlag.clear" passt fast nicht auf eine winzige Drahtdarstellung "TCIF.C"
AShelly

60

Zipfs Gesetz

Wenn Sie sich genau diesen Text ansehen, können Sie selbst feststellen, dass Wortlänge und Häufigkeit der Verwendung im Allgemeinen in umgekehrter Beziehung zueinander stehen. Worte , die sehr häufig verwendet werden, wie it, a, but, you, und andsind sehr kurz, während Worte , die weniger häufig verwendet werden , wie observe, comprehensionund verbositysind länger. Diese beobachtete Beziehung zwischen Frequenz und Länge wird als Zipf-Gesetz bezeichnet .

Die Anzahl von Befehlen in dem Befehlssatz für einen gegebenen Mikroprozessor beträgt normalerweise Dutzende oder Hunderte. Zum Beispiel scheint der Atmel AVR-Befehlssatz ungefähr hundert verschiedene Befehle zu enthalten (ich habe nicht gezählt), aber viele davon sind Variationen eines gemeinsamen Themas und haben sehr ähnliche Mnemoniken. Beispielsweise umfassen die Multiplikationsbefehle MUL, MULS, MULSU, FMUL, FMULS und FMULSU. Sie müssen die Anweisungsliste nicht lange durchsehen, bevor Sie die allgemeine Vorstellung bekommen, dass Anweisungen, die mit "BR" beginnen, Verzweigungen sind, Anweisungen, die mit "LD" beginnen, Ladevorgänge usw. Dasselbe gilt für Variablen: Selbst komplexe Prozessoren bieten nur eine begrenzte Anzahl von Speicherplätzen für Werte: Bedingungsregister, Universalregister usw.

Da es so wenige Anweisungen gibt und das Lesen langer Namen länger dauert, ist es sinnvoll, ihnen kurze Namen zu geben. Im Gegensatz dazu können Programmierer mit höheren Programmiersprachen eine Vielzahl von Funktionen, Methoden, Klassen, Variablen usw. erstellen. Jede dieser Anweisungen wird weitaus seltener verwendet als die meisten Montageanweisungen. Längere, aussagekräftigere Namen werden immer wichtiger, damit Leser (und Verfasser) genügend Informationen erhalten, um zu verstehen, was sie sind und was sie tun.

Darüber hinaus verwenden Befehlssätze für verschiedene Prozessoren häufig ähnliche Namen für ähnliche Vorgänge. Die meisten Befehlssätze enthalten Operationen für ADD, MUL, SUB, LD, ST, BR, NOP. Wenn sie nicht genau diese Namen verwenden, verwenden sie normalerweise sehr nahe beieinander liegende Namen. Sobald Sie die Mnemonik für einen Befehlssatz gelernt haben, dauert es nicht lange, bis Sie sich an die Befehlssätze für andere Geräte gewöhnt haben. So Namen , die vielleicht „kryptische“ Sie scheinen , sind ungefähr so vertraut wie Wörter wie and, orund notan Programmierer , die Programmierung auf dem Gebiet der niedrigen Niveau qualifiziert sind. Ich denke, dass die meisten Leute, die auf Assembler-Ebene arbeiten, Ihnen sagen würden, dass das Lernen, den Code zu lesen, keine der größeren Herausforderungen bei der Programmierung auf niedriger Ebene ist.


2
danke Caleb! Für mich geborgen diese ausgezeichnete Antwort eine Frage , die es irgendwie geschafft zu vier sammeln Werturteile in einem Titel: „kryptisch“, „kurz“, „nach wie vor“, „so gemein“
gnat

1
Vielen Dank, @gnat, sowohl für Ihren Kommentar als auch für Ihren großzügigen Bonus.
Caleb

37

Im Allgemeinen

Bei der Namensqualität geht es nicht nur darum, beschreibende Namen zu haben, sondern es müssen auch andere Aspekte berücksichtigt werden. Dies führt zu Empfehlungen wie:

  • Je globaler der Geltungsbereich, desto aussagekräftiger sollte der Name sein
  • Je öfter es verwendet wird, desto kürzer sollte der Name sein
  • Der gleiche Name sollte in allen Kontexten für die gleiche Sache verwendet werden
  • Unterschiedliche Dinge sollten unterschiedliche Namen haben, auch wenn der Kontext unterschiedlich ist
  • Abweichungen sollten leicht zu erkennen sein
  • ...

Beachten Sie, dass diese Empfehlungen widersprüchlich sind.

Anweisungsmnemonik

Als Assembler-Programmierer erweckt die Verwendung von short-branch-if-greater-or-equalfor bge.sden gleichen Eindruck wie bei mir, als Algol-Programmierer, der Berechnungsgeometrie ausführt, SUBSTRACT THE-HORIZONTAL-COORDINATE-OF-THE-FIRST-POINT TO THE-HORIZONTAL-COORDINATE-OF-THE-SECOND-POINT GIVING THE-DIFFERENCES-OF-THE-COORDINATE-OF-THE-TWO-POINTSanstatt dx := p2.x - p1.x. Ich kann einfach nicht zustimmen, dass die ersten in den Kontexten, die mir wichtig sind, besser lesbar sind.

Registrieren Sie Namen

Sie wählen den offiziellen Namen aus der Dokumentation. In der Dokumentation wird der Name aus dem Entwurf ausgewählt. Das Design verwendet viele Grafikformate, bei denen lange Namen nicht ausreichen und das Designteam mit diesen Namen monatelang, wenn nicht sogar jahrelang leben wird. Aus beiden Gründen verwenden sie das "Interrupt-Flag des ersten Timer-Zählers" nicht, sondern kürzen es in ihrem Schema sowie beim Sprechen ab. Sie kennen es und verwenden systematische Abkürzungen wie diese TIFR1, um die Gefahr von Verwechslungen zu verringern. Ein Punkt hier ist, dass TIFR1es sich nicht um eine zufällige Abkürzung handelt, sondern das Ergebnis eines Namensschemas.


4
Ist das TIFR1wirklich ein besseres Namensschema als InterruptFlag1wenn, oder muss IptFlag1man wirklich kurz sein?
Timwi

4
@ Timwi, InterruptFlagund IptFlagsind besser als IFin der gleichen Weise wie EnumerableInterfaceund ItfcEnumerablesind besser als IEnumerable.
Programmierer

@AProgrammer: Ich halte Ihre Antwort und Ihren Kommentar für die beste und würde sie als akzeptiert markieren, wenn ich könnte. Diejenigen, die glauben, dass nur physikalische Grenzen Kurznamen diktieren, sind falsch. Diese Diskussion wird für Sie interessant sein: 37signals.com/svn/posts/…
alpav

5
@alpav Weißt du, dass dein Link das Gegenteil von dem ist, was diese Antwort sagt? Wenn überhaupt, wird dies InterruptFlag1aus Gründen der besseren Übersichtlichkeit uneingeschränkt unterstützt .
Roman Starkov

24

Abgesehen von den Gründen für "alte Gewohnheiten" ist Legacy-Code, der vor 30 Jahren geschrieben wurde und immer noch verwendet wird, weit verbreitet. Ungeachtet dessen, was einige weniger erfahrene Leute denken, ist die Umgestaltung dieser Systeme, damit sie hübsch aussehen, mit sehr hohen Kosten und geringem Gewinn verbunden und wirtschaftlich nicht tragbar.

Eingebettete Systeme, die sich in der Nähe der Hardware befinden und auf Register zugreifen, verwenden aus guten Gründen in der Regel dieselben oder ähnliche Bezeichnungen wie die in den Hardwaredatenblättern verwendeten. Wenn das Register in den Hardwaredatenblättern XYZZY1 heißt, ist es sinnvoll, dass die Variable, die es darstellt, wahrscheinlich XYZZY1 ist, oder wenn der Programmierer einen guten Tag hatte, RegXYZZY1.

Soweit bge.ses das betrifft, ist es ähnlich wie Assembler - für die wenigen Leute, die es wissen müssen, sind längere Namen weniger lesbar. Wenn Sie sich nicht zurechtfinden bge.sund denken branch-if-greater-or-equal.short, dass dies etwas bewirken wird, spielen Sie nur mit der CLR und wissen es nicht.

Der andere Grund, warum Sie kurze Variablennamen sehen, ist, dass die Abkürzungen in der von der Software angesprochenen Domäne weit verbreitet sind.

Zusammenfassend lässt sich sagen, dass kurze abgekürzte Variablennamen, die einen externen Einfluss widerspiegeln, wie Industrienormen und Hardwaredatenblätter, erwartet werden. Kurze abgekürzte Variablennamen, die sich innerhalb der Software befinden, sind normalerweise weniger wünschenswert.


Wenn ich das Argument verstanden habe, mit dem Sie "bge.s" verteidigen, TIFR1ist es für diejenigen lesbarer, die es wissen müssen, als TimerCounter1InterruptFlag, richtig?
Roman Starkov

2
@romkyns: Auf jeden Fall - in diesem Fall ist weniger mehr .... Im Gegensatz zu CNTR, was "Counter", "Control", "Can Not Trace Route" usw. bedeuten könnte, hat T1FR1 eine genau definierte Bedeutung.
Mattnz

"Wenn Sie nicht mit bge.s zurechtkommen und glauben, dass branch-if-major-or-equal.short den Unterschied ausmacht, spielen Sie nur mit der CLR und wissen es nicht." Das weiß ich nicht. Ich verstehe x86-Assembly ziemlich gut, aber jedes Mal , wenn ich eine Schleife schreibe, muss ich nachsehen, was alle j?Anweisungen bedeuten. Eine offensichtlichere Anweisung würde mir definitiv helfen. Aber vielleicht bin ich eher die Ausnahme als die Regel. Ich kann mich nicht an triviale Details erinnern.
Cody Grey

11

Hier gibt es so viele verschiedene Ideen. Ich kann keine der vorhandenen Antworten , wie akzeptieren die Antwort: Zum einen gibt es wahrscheinlich viele Faktoren , die dazu beitragen, zum anderen kann ich nicht wissen , welches der bedeutendste ist.

Hier ist eine Zusammenfassung der Antworten, die andere hier gepostet haben. Ich poste dies als CW und meine Absicht ist es, es schließlich als akzeptiert zu markieren. Bitte bearbeiten, wenn ich etwas verpasst habe. Ich habe versucht, jede Idee neu zu formulieren, um sie kurz und klar auszudrücken.

Warum sind kryptische Kurzbezeichner in der Low-Level-Programmierung so häufig?

  • Weil viele von ihnen in der jeweiligen Domäne häufig genug sind, um einen sehr kurzen Namen zu rechtfertigen. Dies verschlechtert die Lernkurve, ist jedoch angesichts der Häufigkeit der Nutzung ein lohnender Kompromiss.
  • Weil es normalerweise eine kleine Menge von Möglichkeiten gibt, die behoben sind (der Programmierer kann nicht zur Menge hinzufügen).
  • Denn Lesbarkeit ist Gewohnheits- und Übungssache. branch-if-greater-than-or-equal.shortist anfangs besser lesbar als bge.s, aber mit etwas Übung kehrt sich die Situation um.
  • Weil sie oft vollständig von Hand eingegeben werden müssen, weil einfache Sprachen oft keine leistungsstarken IDEs mit guter Autovervollständigung enthalten oder die Klimaanlage nicht zuverlässig ist.
  • Da es manchmal wünschenswert ist, viele Informationen in die Kennung zu packen, und ein lesbarer Name selbst für hohe Standards unannehmbar lang ist.
  • Denn so haben Low-Level-Umgebungen in der Vergangenheit ausgesehen. Die Gewohnheit zu brechen erfordert bewusste Anstrengung, läuft Gefahr, diejenigen zu ärgern, die die alten Methoden mochten, und muss als lohnenswert gerechtfertigt werden. Das Festhalten am etablierten Weg ist die "Vorgabe".
  • Weil viele von ihnen an anderer Stelle entstanden sind, beispielsweise in Form von Schaltplänen und Datenblättern. Diese wiederum sind von Platzbeschränkungen betroffen.
  • Weil die Leute, die für die Benennung von Dingen zuständig sind, noch nie über die Lesbarkeit nachgedacht haben oder nicht wissen, dass sie ein Problem verursachen oder faul sind.
  • In einigen Fällen sind die Namen Teil eines Protokolls für den Datenaustausch geworden, beispielsweise die Verwendung der Assemblersprache als Zwischendarstellung durch einige Compiler.
  • Denn dieser Stil ist sofort als Low-Level erkennbar und sieht somit cool für Geeks aus.

Ich persönlich bin der Meinung, dass einige davon nicht wirklich zu den Gründen beitragen, warum ein neu entwickeltes System diesen Benennungsstil wählt, aber ich fand es falsch, einige Ideen in dieser Art von Antwort herauszufiltern.


10

Ich werde meinen Hut in dieses Chaos werfen.

Kodierungskonventionen und -standards auf hoher Ebene sind nicht dasselbe wie Kodierungsstandards und -praktiken auf niedriger Ebene. Leider sind die meisten davon Überbleibsel aus altem Code und alten Denkprozessen.

Einige dienen jedoch einem Zweck. Sicher, BranchGreaterThan wäre viel besser lesbar als BGT , aber es gibt eine Konvention, die eine Anweisung darstellt und als solche in den letzten 30 Jahren als Standard etwas an Bodenhaftung gewonnen hat. Warum haben sie damit angefangen, wahrscheinlich mit einer willkürlichen Zeichenbreitenbeschränkung für Anweisungen, Variablen und dergleichen? Warum behalten sie es, es ist ein Standard. Dieser Standard entspricht der Verwendung von int als Bezeichner. Die Verwendung von Integer ist in allen Fällen besser lesbar. Er ist jedoch für alle erforderlich, die mehr als ein paar Wochen programmiert haben ... nein. Warum? Weil es eine Standardpraxis ist.

Zweitens, wie ich in meinem Kommentar sagte, tragen viele der Interrupts den Namen INTG1 und andere kryptische Namen. Diese dienen ebenfalls einem Zweck. In Schaltplänen ist es NICHT üblich, die Linien zu benennen, und so ausführlich, dass das Diagramm unübersichtlich wird und die Lesbarkeit beeinträchtigt wird. Alle Ausführlichkeit wird in der Dokumentation behandelt. Und da alle Verdrahtungs- / Schaltpläne diese Kurznamen für Interrupt-Leitungen haben, erhalten die Interrupts selbst denselben Namen, um die Konsistenz für den eingebetteten Entwickler vom Schaltplan bis zum Code für die Programmierung zu gewährleisten.

Ein Designer hat eine gewisse Kontrolle darüber, aber wie bei jedem Feld / jeder neuen Sprache gibt es Konventionen, die von Hardware zu Hardware folgen und daher in jeder Assemblersprache gleich bleiben sollten. Ich kann mir einen Ausschnitt aus der Assembly ansehen und in der Lage sein, den Kern des Codes zu erhalten, ohne jemals diesen Befehlssatz zu verwenden, weil sie sich an eine Konvention halten, LDA oder eine Beziehung dazu wahrscheinlich ein Register laden. MV verschiebt wahrscheinlich etwas von irgendwo hin anderswo geht es nicht darum, was Sie für nett halten oder was ein hohes Maß an Übung ist, es ist eine Sprache für sich und hat als solche ihre eigenen Standards und bedeutet, dass Sie als Designer folgen sollten, diese sind oft nicht annähernd so willkürlich wie Sie scheinen.

Ich überlasse Ihnen Folgendes: Wenn Sie die Embedded-Community bitten, ausführliche Methoden auf hoher Ebene anzuwenden, müssen Sie die Chemiker auffordern, immer chemische Verbindungen aufzuschreiben. Der Chemiker schreibt sie kurz für sich selbst und jeder andere auf dem Gebiet wird es verstehen, aber es kann eine Weile dauern, bis sich ein Neuling daran gewöhnt hat.


1
Ich bin der Meinung, dass "Wir werden kryptische Namen verwenden, weil dies das Gefühl von Low-Level-Programmierung ist" und "Wir werden kryptische Namen verwenden, weil dies die Konvention für Low-Level-Programmierung ist" ziemlich gleich sind, also +1 von mir und ich werde darüber nachdenken, dies als eine weniger entzündliche Variante derjenigen zu akzeptieren, die ich ursprünglich akzeptiert habe .
Roman Starkov

6
+1 für die Chemiker, da dies eine gute Analogie für die verschiedenen Bereiche der Programmierung darstellt.

4
+1 Ich habe auch nie verstanden, warum Leute kurze, kryptische Namen wie "Wasser" verwenden, wenn es das viel besser lesbare "DiHydrogenOxyde" gibt
Ingo

6

Ein Grund, warum sie kryptische Kurzbezeichner verwenden, ist, dass sie für die Entwickler nicht kryptisch sind. Man muss erkennen, dass sie jeden Tag damit arbeiten und diese Namen wirklich Domainnamen sind. Sie wissen also auswendig, was genau TIFR1 bedeutet.

Wenn ein neuer Entwickler zum Team kommt, muss er die Datenblätter (wie von @KarlBielefeldt erklärt) lesen, damit er sich mit diesen vertraut macht.

Ich glaube, Ihre Frage war ein schlechtes Beispiel, denn in der Tat sehen Sie auf solchen Quellcodes normalerweise eine Menge unnötiger Krypta-IDs für Nicht-Domain-Inhalte.

Ich würde sagen, meistens tun sie das, weil es schlechte Angewohnheiten gab, als die Compiler nicht alles, was Sie eingeben, automatisch vervollständigten.


5

Zusammenfassung

Initialismus ist in vielen technischen und nichttechnischen Kreisen ein weit verbreitetes Phänomen. Als solches ist es nicht auf Low-Level-Programmierung beschränkt. Für die allgemeine Diskussion siehe den Wikipedia-Artikel über Akronym . Meine Antwort ist spezifisch für Low-Level-Programmierung.

Ursachen für kryptische Namen:

  1. Low-Level-Anweisungen sind stark typisiert
  2. Es müssen viele Typinformationen in den Namen eines Befehls auf niedriger Ebene gepackt werden
  3. In der Vergangenheit werden Ein-Zeichen-Codes zum Packen der Typinformationen bevorzugt.

Lösungen und ihre Nachteile:

  1. Es gibt moderne Namensschemata auf niedriger Ebene, die konsistenter sind als historische.
    • LLVM
  2. Es besteht jedoch weiterhin die Notwendigkeit, viele Typinformationen zu packen.
    • So sind kryptische Abkürzungen immer noch überall zu finden.
  3. Verbesserte Lesbarkeit von Zeile zu Zeile hilft einem unerfahrenen Programmierer, die Sprache schneller zu erlernen, hilft jedoch nicht beim Verstehen großer Teile von Code auf niedriger Ebene.

Volle Antwort

(A) Längere Namen sind möglich. Beispiel: Die Namen der C ++ SSE2-Intrinsics haben im Durchschnitt 12 Zeichen im Vergleich zu den 7 Zeichen in der Assembly-Mnemonik. http://msdn.microsoft.com/en-us/library/c8c5hx3b(v=vs.80).aspx

(B) Die Frage geht dann weiter zu: Wie lange / nicht kryptisch muss man mit Anweisungen auf niedriger Ebene umgehen?

(C) Nun analysieren wir die Zusammensetzung solcher Namensschemata. Es folgen zwei Benennungsschemata für denselben Befehl auf niedriger Ebene:

  • Namensschema Nr. 1: CVTSI2SD
  • Namensschema Nr. 2: __m128d _mm_cvtsi32_sd (__m128d a, int b);

(C.1) Anweisungen auf niedriger Ebene sind immer stark typisiert. Es darf keine Mehrdeutigkeit, Typinferenz, automatische Typkonvertierung oder Überladung geben (die Wiederverwendung des Befehlsnamens bedeutet ähnliche, aber nicht äquivalente Operationen).

(C.2) Jeder Low-Level-Befehl muss viele Typinformationen in seinen Namen kodieren. Beispiele für Informationen:

  • Architektur-Familie
  • Betrieb
  • Argumente (Eingänge) und Ausgänge
  • Types (Signed Integer, Unsigned Integer, Float)
  • Präzision (Bitbreite)

(C.3) Wenn jede Information ausgeschrieben ist, ist das Programm ausführlicher.

(C.4) Die von verschiedenen Anbietern verwendeten Typcodierungsschemata hatten lange historische Wurzeln. Beispiel im x86-Befehlssatz:

  • B bedeutet Byte (8 Bit)
  • W bedeutet Wort (16-Bit)
  • D bedeutet dword "Doppelwort" (32-Bit)
  • Q bedeutet qWort "Quad-Word" (64-Bit)
  • DQ bedeutet dqword "double-quad-word" (128-bit)

Diese historischen Bezüge hatten keinerlei moderne Bedeutung, bleiben aber bestehen. Ein konsistenteres Schema hätte den Bitbreitenwert (8, 16, 32, 64, 128) in den Namen eingefügt.

Im Gegenteil, LLVM ist ein richtiger Schritt in Richtung Konsistenz in Anweisungen auf niedriger Ebene: http://llvm.org/docs/LangRef.html#functions

(D) Ungeachtet des Befehlsbenennungsschemas sind Programme auf niedriger Ebene bereits ausführlich und schwer zu verstehen, da sie sich auf die winzigen Details der Ausführung konzentrieren. Das Ändern des Befehlsbenennungsschemas verbessert die Lesbarkeit von Zeile zu Zeile, beseitigt jedoch nicht die Schwierigkeit, die Operationen eines großen Codeteils zu verstehen.


1
Eine verbesserte Lesbarkeit von Zeile zu Zeile hat zwangsläufig einen gewissen Einfluss auf das Verständnis des Ganzen, aber die Nennung allein kann es natürlich nicht trivial machen.
Roman Starkov

3
Auch Art von Off-Topic, aber CVTSI2SDkeine mehr Informationen als ConvertDword2Doubleoder ConvInt32ToFloat64, aber die letzteren, während länger, sind sofort erkennbar, während die ersteren entschlüsselt werden müssen ...
Roman Starkov

2

Menschen lesen und schreiben Assembler nur gelegentlich und meistens handelt es sich nur um ein Kommunikationsprotokoll. Das heißt, es wird am häufigsten als zwischengeschaltete, serialisierte, textbasierte Darstellung zwischen Compiler und Assembler verwendet. Je ausführlicher diese Darstellung ist, desto unnötiger ist der Aufwand in diesem Protokoll.

Bei Opcodes und Registernamen beeinträchtigen lange Namen die Lesbarkeit. Kurze Mnemoniken sind besser für ein Kommunikationsprotokoll (zwischen Compiler und Assember), und Assemblersprache ist die meiste Zeit ein Kommunikationsprotokoll. Kurze Mnemoniken sind für Programmierer besser, da der Compiler-Code leichter zu lesen ist.


Wenn Sie Platz sparen möchten, können Sie es einfach komprimieren! ... Wenn Sie keinen Overhead benötigen, verwenden Sie stattdessen ein Binärformat! Wenn Sie Text verwenden, streben Sie Lesbarkeit an - warum sollten Sie dann nicht den ganzen Weg gehen und ihn richtig lesbar machen?
Roman Starkov

2
@romkyns, Komprimieren eines textbasierten Kommunikationsprotokolls zwischen zwei lokalen Prozessen? Das ist etwas Neues. Binäre Protokolle sind viel weniger robust. Es ist ein Unix-Weg - textbasierte Protokolle dienen der gelegentlichen Lesbarkeit. Sie sind gerade genug lesbar.
SK-logic am

Richtig. Sie gehen davon aus, dass ich die Namen dieser Register oder CIL-Anweisungen so wenig lese und schreibe, dass der Overhead eine Rolle spielt. Aber denke darüber nach; Sie werden während des Programmierens genauso oft verwendet wie ungerade Methoden oder Variablennamen in anderen Programmiersprachen . Ist das so selten, dass die wenigen zusätzlichen Bytes eine Rolle spielen?
Roman Starkov

1
Ich respektiere Ihr Recht, einen anderen Geschmack daran zu haben, wie lange Namen sein sollten, aber nennen Sie Methoden und Einheimische in Ihren Compilern wirklich so kryptische Dinge TIFR, oder enthalten sie eher vollständige Wörter?
Roman Starkov

1
Ich sehe keinen Unterschied zwischen dem lesbaren und dem kurzen Trade-off. Ich sehe sie natürlich anders, genauso wie Variablen sich von Funktionen unterscheiden, die sich von Typen unterscheiden. Ich verstehe nur nicht, warum Opcodes und Registernamen davon profitieren, dass sie so kurz sind , dass Sie die Dokumentation für jede neu aufgetretene konsultieren müssen, bevor Sie eine Ahnung davon haben , was sie tut. Ihr einziges Argument ist die effiziente Speicherung, wenn ich mich nicht irre. Meinen Sie es wirklich so? ... Oder haben Sie andere Gründe?
Roman Starkov

1

Meistens ist es idiomatisch. Wie @TMN an anderer Stelle sagt, schreiben Sie weder in C import JavaScriptObjectNotationnoch import HypertextTransferProtocolLibraryin Python Timer1LowerHalf = 0xFFFF. Das sieht im Kontext genauso lächerlich aus. Jeder, der es wissen muss, weiß es bereits.

Der Widerstand gegen Änderungen kann teilweise auf die Tatsache zurückzuführen sein, dass einige C-Compiler-Anbieter für eingebettete Systeme vom Sprachstandard und der Syntax abweichen, um Funktionen zu implementieren, die für die eingebettete Programmierung nützlicher sind. Dies bedeutet, dass Sie die Autovervollständigungsfunktion Ihrer bevorzugten IDE oder Ihres bevorzugten Texteditors beim Schreiben von Code auf niedriger Ebene nicht immer verwenden können, da diese Anpassungen ihre Fähigkeit zum Analysieren von Code beeinträchtigen. Daher der Nutzen von kurzen Registernamen, Makros und Konstanten.

Beispielsweise enthielt der C-Compiler von HiTech eine spezielle Syntax für Variablen, die eine benutzerdefinierte Position im Speicher benötigen. Sie könnten erklären:

volatile char MAGIC_REGISTER @ 0x7FFFABCD;

Jetzt ist die einzige vorhandene IDE, die dies analysiert, die HiTech-eigene IDE ( HiTide ). In jedem anderen Editor müssen Sie es jedes Mal manuell aus dem Speicher eingeben. Das wird sehr schnell alt.

Hinzu kommt, dass beim Überprüfen von Registern mithilfe von Entwicklungstools häufig eine Tabelle mit mehreren Spalten angezeigt wird (Registername, hexadezimaler Wert, binärer Wert, letzter hexadezimaler Wert usw.). Lange Namen bedeuten, dass Sie die Namensspalte auf 13 Zeichen erweitern müssen, um den Unterschied zwischen zwei Registern zu erkennen, und den Unterschied in Dutzenden von Zeilen wiederholter Wörter erkennen müssen.

Das hört sich vielleicht nach albernen kleinen Dingen an, aber ist nicht jede Codierungskonvention darauf ausgelegt, die Belastung der Augen zu verringern, überflüssiges Tippen zu reduzieren oder eine von Millionen anderen kleinen Beschwerden zu lösen?


2
Alle Ihre Argumente sind sinnvoll. Ich verstehe all diese Punkte voll und ganz. Denken Sie jedoch nicht, dass genau das Gleiche für Code auf hoher Ebene gilt? Sie müssen auch eine Tabelle mit Einheimischen in einer C # -Funktion anzeigen. Der Kontext ist subjektiv und File.ReadAllByteskönnte für jemanden, der es gewohnt ist, auch lächerlich lang sein fread. Warum also High-Level- und Low-Level-Code unterschiedlich behandeln ?
Roman Starkov

@romkyns - Ich verstehe, aber ich glaube nicht, dass wir Code auf hoher Ebene tatsächlich nicht sehr unterschiedlich behandeln. Abkürzungen sind in vielen hochrangigen Kontexten in Ordnung. Wir erkennen sie einfach nicht, weil wir uns eher an die Abkürzung oder das dazugehörige Schema gewöhnt haben. Wenn ich Funktionen schreibe oder Variablen in einfachem Code erstelle, verwende ich nette beschreibende Namen. Aber wenn ich mich auf ein Register beziehe, bin ich froh, dass ich auf ein Durcheinander von Buchstaben und Zahlen blicken kann und schnell denke: "T = Timer, IF = Interrupt-Flag, 1 = erstes Register". In dieser Hinsicht ist es fast wie in der organischen Chemie: P
Detly,

@romkyns - Auch in einem rein praktischen Sinne, ich glaube , der Unterschied zwischen einer Tabelle von Registern in einigen Entwicklungs IDE und Anwendung des Mikroprozessors in C # , ist dies: eine Tabelle von uP Registern könnte wie folgt aussehen: Timer1InterruptFlag, Timer2InterruptFlag, ..., Timer9InterruptFlag, IOPortAToggleMask, IOPortBToggleMask, etc x100. In einer höheren Sprache würden Sie Variablen verwenden, die sich viel stärker unterscheiden ... oder Sie würden mehr Struktur verwenden. Timer1InterruptFlagist 75% irrelevent Lärm im Vergleich zu T1IF. Ich glaube nicht, dass Sie eine riesige Liste von Variablen in C # erstellen würden, die sich so kaum unterscheiden.
Detly

1
@romkyns - Was Sie vielleicht nicht bewusst ist , die Tatsache , dass es hat eine Verschiebung in Richtung gewesen , was Sie beschreiben. Die jüngsten Compiler von Microchip enthalten Bibliotheken, die weitaus ausführlicher und aussagekräftiger sind als nur Register, z. UARTEnable(UART1, BITS_8, PARITY_N, STOP_1, BAUD_115200). Aber sie sind immer noch unglaublich klobig und beinhalten viel Indirektion und Ineffizienz. Ich versuche, sie nach Möglichkeit zu verwenden, aber die meiste Zeit packe ich die Registermanipulation in meine eigenen Funktionen und rufe sie von der übergeordneten Logik aus auf.
Detly

@detly: Der CCS-Compiler hatte solche Methoden, und einige andere Prozessoren tun das auch. Ich mag sie im Allgemeinen nicht. Die Registerspezifikation reicht aus, um Code zu schreiben, der die Register verwendet, und es reicht aus, wenn jemand Code liest, der Register verwendet, um zu sehen, was diese Register tun. Wenn der Vorgang des Schreibens eines Werts von N in einen Hardware-Prescalar die Periode auf N + 1 setzt (ziemlich häufig), ist die eigentliche Bedeutung von set_prescalar(TMR4,13);IMHO viel weniger klar als dies der Fall wäre TMR4->PSREG=12;. Selbst wenn man sich das Compiler-Handbuch ansieht, um herauszufinden, was der erste Code tut, muss man wahrscheinlich immer noch ...
supercat

1

Ich bin überrascht, dass niemand Faulheit erwähnt hat und dass andere Wissenschaften nicht diskutiert werden. Meine tägliche Arbeit als Programmierer zeigt mir, dass Namenskonventionen für jede Art von Variable in einem Programm von drei verschiedenen Aspekten beeinflusst werden:

  1. Der wissenschaftliche Hintergrund des Programmierers.
  2. Die Programmierkenntnisse des Programmierers.
  3. Die Umgebung des Programmierers.

Ich denke, es nützt nichts, über Low-Level- oder High-Level-Programmierung zu diskutieren. Letztendlich kann es immer auf die drei erstgenannten Aspekte beschränkt werden.


Eine Erklärung des ersten Aspekts: Viele "Programmierer" sind in erster Linie keine Programmierer. Sie sind Mathematiker, Physiker, Biologen oder sogar Psychologen oder Ökonomen, aber viele von ihnen sind keine Informatiker. Die meisten von ihnen haben ihre eigenen domänenspezifischen Schlüsselwörter und Abkürzungen, die Sie in ihren Namenskonventionen sehen können. Sie sind häufig in ihrer Domäne gefangen und verwenden diese bekannten Abkürzungen, ohne an die Lesbarkeit oder Codierungsanweisungen zu denken.

Eine Erklärung des zweiten Aspekts: Da die meisten Programmierer keine Informatiker sind, sind ihre Programmierkenntnisse begrenzt. Deshalb interessieren sie sich oft nicht für Kodierungskonventionen, sondern mehr für domänenspezifische Konventionen, wie als erster Aspekt angegeben. Auch wenn Sie nicht über die Fähigkeiten eines Programmierers verfügen, haben Sie kein Verständnis für Codierungskonventionen. Ich denke, die meisten von ihnen sehen nicht die dringende Notwendigkeit, verständlichen Code zu schreiben. Es ist wie Feuer und vergessen.

Eine Erklärung des dritten Aspekts: Es ist unwahrscheinlich, dass Sie gegen die Konventionen Ihrer Umgebung verstoßen, die alter Code sein können, den Sie unterstützen müssen, die Kodierungsstandards Ihres Unternehmens (die von Wirtschaftswissenschaftlern betrieben werden, denen die Kodierung egal ist) oder die Domäne, der Sie angehören. Wenn jemand kryptische Namen verwendet und Sie ihn oder seinen Code unterstützen müssen, ist es unwahrscheinlich, dass Sie die kryptischen Namen ändern. Wenn es in Ihrem Unternehmen keine Kodierungsstandards gibt, schreibt fast jeder Programmierer seinen eigenen Standard. Und als letztes, wenn Sie von Domain-Benutzern umgeben sind, werden Sie nicht anfangen, eine andere Sprache zu schreiben, als sie verwenden.


faulheit hat niemand erwähnt - vielleicht liegt es daran, dass dies hier nicht relevant ist. Und dass andere Wissenschaften nicht diskutiert werden , ist ganz einfach: Diese Seite steht nicht zur Diskussion . Es ist für Fragen und Antworten
Mücke

Faulheit ist ein legitimer Grund. Fast alle Programmierer sind faule Leute (sonst würden wir alles manuell machen ooo!).
Thomas Eding
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.