Warum werden Programme nicht häufiger in Assembly geschrieben? [geschlossen]


216

Es scheint eine gängige Meinung zu sein, dass Assembler-Programmierung länger dauert und schwieriger zu programmieren ist als eine höhere Sprache wie C. Daher scheint es aus diesen Gründen zu empfehlen oder anzunehmen, dass es besser ist, in einer höheren Sprache zu schreiben und aus Gründen der besseren Portabilität.

Vor kurzem habe ich in x86-Assembly geschrieben und mir ist klar geworden, dass diese Gründe möglicherweise nicht wirklich zutreffen, außer vielleicht die Portabilität. Vielleicht ist es eher eine Frage der Vertrautheit und des Wissens, wie man Assemblierungen gut schreibt. Mir ist auch aufgefallen, dass die Programmierung in Assembly ganz anders ist als die Programmierung in einer HLL. Vielleicht könnte ein guter und erfahrener Assembler-Programmierer Programme genauso einfach und schnell schreiben wie ein erfahrener C-Programmierer, der in C schreibt.

Vielleicht liegt es daran, dass Assembler-Programmierung ganz anders ist als HLLs und daher unterschiedliche Denkweisen, Methoden und Methoden erfordert, was es sehr umständlich erscheinen lässt, für Unbekannte zu programmieren, und es daher seinen schlechten Namen für das Schreiben von Programmen gibt.

Wenn Portabilität kein Problem ist, was hätte C dann wirklich über einen guten Assembler wie NASM?

Edit: Nur um darauf hinzuweisen. Wenn Sie in Assembly schreiben, müssen Sie nicht nur in Anweisungscodes schreiben. Sie können Makros und Prozeduren sowie Ihre eigenen Konventionen verwenden, um verschiedene Abstraktionen zu erstellen, um Programme modularer, wartbarer und leichter lesbar zu machen. Hier kommt es darauf an, mit dem Schreiben einer guten Baugruppe vertraut zu sein.


71
Schreiben ? Was ist mit dem Lesen von Code? Sie (und andere) werden den Code viel mehr lesen als Sie schreiben
Nr.

81
Warum sollte ich eine neue Sprache lernen müssen, nur weil mein Programm auf einer neuen Plattform ausgeführt werden soll? Warum sollte ich meine Programme so erstellen müssen, dass sie der Vorstellung der CPU entsprechen, wie viele Register es gibt und was Sie damit tun können? Ich versuche Probleme zu lösen, nicht die Computer bieten.
Joachim Sauer

8
Zusammenfassung der EDIT: Man kann einen C-Compiler verwenden.
Meinersbur

4
@Simon Vielleicht habe ich dann meine Jahre falsch, aber ich bin überrascht, dass wir 2010 über ASM gegen "eine Hochsprache wie C" diskutieren. Insbesondere der Teil, in dem C das Beispiel einer Hochsprache ist
matt b

11
@changelog: So buchstabieren Sie programmieren.reddit.com nicht.
BoltClock

Antworten:


331

ASM ist schlecht lesbar und im Vergleich zu höheren Sprachen nicht wirklich wartbar .

Außerdem gibt es viel weniger ASM-Entwickler als für andere populärere Sprachen wie C.

Wenn Sie eine höhere Sprache verwenden und neue ASM-Anweisungen verfügbar werden (z. B. SSE), müssen Sie lediglich Ihren Compiler aktualisieren, und Ihr alter Code kann die neuen Anweisungen problemlos verwenden.

Was ist, wenn die nächste CPU doppelt so viele Register hat?

Die Umkehrung dieser Frage wäre: Welche Funktionalität bieten Compiler?

Ich bezweifle, dass Sie Ihr ASM besser optimieren können / wollen / sollten als gcc -O3können.


10
gcc ist nicht so gut in der Optimierung, weitaus besser als der durchschnittliche Mensch, aber es gibt viele Stellen, an denen die Optimierer keine gute Arbeit leisten. Stimme dir aber anders zu.
old_timer

4
@dwelch In sehr seltenen Fällen kann gcc (oder viele andere Compiler) kompiliertes C nicht richtig optimieren. In diesen Fällen können Sie jedoch immer eine begrenzte Anzahl von Prozeduren in ASM schreiben und nur diese Methoden während des Builds verknüpfen.
Cortijon

@ Ben S: Ich habe anfangs eher "viele" als "viel" bearbeitet, da "viel" nur für einzelne Objekte verwendet wird. Da das Objekt von "viel" Plural ist (Entwickler), ist "viele" die richtige Option. Aber ich werde Ihre Antwort nicht erneut bearbeiten, wenn "viel" das ist, was Sie wollen.
Billy ONeal

1
Es gibt viele Fälle, in denen ein Compiler nicht gut optimieren kann, aber häufig kann ein Entwickler, der sich der Einschränkungen des Optimierers bewusst ist, seinen C-Code optimieren, ohne auf Assembly zurückgreifen zu müssen.
Qwertie

1
FWIW in meiner täglichen Arbeit kompiliere ich unser Produkt mit gcc -g -O0, weil es verdammt viel mehr wert ist, gdb auf einem Live-System daran anzuhängen und nicht aufgrund von Variablen verrückt zu werden, die aus der Existenz heraus optimiert wurden Unternehmen als es wäre, jeden Tag weitere 4 Milliarden CPU-Zyklen im Leerlauf zu lassen (von insgesamt 3 Billionen). Das Knacken von ganzen Zahlen ist nicht sehr oft der Engpass.
Bernd Jendrissek

1930

Hallo, ich bin ein Compiler.

Ich habe gerade Tausende von Codezeilen gescannt, während Sie diesen Satz gelesen haben. Ich habe Millionen von Möglichkeiten durchgesehen, eine einzelne Zeile von Ihnen mithilfe von Hunderten verschiedener Optimierungstechniken zu optimieren, basierend auf einer großen Menge akademischer Forschung, mit der Sie jahrelang arbeiten würden. Ich werde keine Verlegenheit verspüren, nicht einmal ein leichtes Problem, wenn ich eine dreizeilige Schleife in Tausende von Anweisungen konvertiere, nur um sie schneller zu machen. Ich schäme mich nicht, große Optimierungen vorzunehmen oder die schmutzigsten Tricks zu machen. Und wenn du nicht willst, dass ich es tue, vielleicht für ein oder zwei Tage, werde ich mich so verhalten und es tun, wie du willst. Ich kann die von mir verwendeten Methoden jederzeit transformieren, ohne auch nur eine einzige Zeile Ihres Codes zu ändern. Ich kann Ihnen sogar zeigen, wie Ihr Code in der Assembly aussehen würde. auf verschiedenen Prozessorarchitekturen und verschiedenen Betriebssystemen und in verschiedenen Assemblykonventionen, wenn Sie möchten. Ja, alles in Sekunden. Weil ich es kann; und du weißt, du kannst nicht.

PS Oh, übrigens, Sie haben nicht die Hälfte des Codes verwendet, den Sie geschrieben haben. Ich habe dir einen Gefallen getan und es weggeworfen.


99

Ich habe eine Menge Assembler für die Chips 6502, Z80, 6809 und 8086 geschrieben. Ich hörte damit auf, sobald C-Compiler für die von mir angesprochenen Plattformen verfügbar wurden, und wurde sofort mindestens zehnmal produktiver. Die meisten guten Programmierer verwenden die Werkzeuge, die sie verwenden, aus rationalen Gründen.


72

Ich liebe es, in Assemblersprache zu programmieren, aber es braucht mehr Code, um dasselbe zu tun wie in einer Sprache auf hoher Ebene, und es besteht eine direkte Korrelation zwischen Codezeilen und Fehlern. (Dies wurde vor Jahrzehnten in The Mythical Man-Month erklärt .)

Es ist möglich, sich C als "High-Level-Assembly" vorzustellen, aber wenn Sie ein paar Schritte darüber hinausgehen, befinden Sie sich in einer anderen Welt. In C # denken Sie nicht zweimal darüber nach, dies zu schreiben:

foreach (string s in listOfStrings) { /* do stuff */ }

Dies wären Dutzende, vielleicht Hunderte von Codezeilen in Assembly, jeder Programmierer, der sie implementiert, würde einen anderen Ansatz verfolgen, und die nächste Person, die mitkommt, müsste es herausfinden. Wenn Sie also glauben (wie viele andere auch), dass Programme hauptsächlich für andere Personen geschrieben wurden, ist Assembly weniger lesbar als die typische HLL.

Bearbeiten: Ich habe eine persönliche Codebibliothek für allgemeine Aufgaben und Makros für die Implementierung von C-ähnlichen Kontrollstrukturen gesammelt. Aber ich bin in den 90ern an die Wand gegangen, als GUIs zur Norm wurden. Es wurde zu viel Zeit für Dinge aufgewendet, die Routine waren.

Die letzte Aufgabe, bei der ASM unerlässlich war, war vor einigen Jahren das Schreiben von Code zur Bekämpfung von Malware. Keine Benutzeroberfläche, also waren es alle lustigen Teile ohne das Aufblähen.


Bist du dir da sicher? Ich erinnere mich an das Lesen in Code Complete, dass dies nicht der Fall war ...
jcolebrand

1
Ich bin sicher, dass es einen Punkt gibt, an dem der Vorteil "weniger Linien" durch den Nachteil "vorzeitige Optimierung" übertroffen wird. Aber ich habe Code Complete seit Ewigkeiten nicht mehr angeschaut ...
egrunin

6
Ein bisschen ironisch, "vorzeitige Optimierung" als Argument für die Montage zu verwenden ... (Ich interpretiere Sie wahrscheinlich falsch. Ich finde es immer noch lustig.)
Bernd Jendrissek

Sie können die Funktion im Assembler weiterhin aufrufen, daher bezweifle ich, dass eine foreach-Schleife Dutzende bis Hunderte von Zeilen benötigt. Oder was fehlt mir?
Sebastian Mach

@phresnel: foreachmacht weit mehr Arbeit als for- es instanziiert und verwendet einen typspezifischen Iterator.
Egrunin

15

Zusätzlich zu den Antworten anderer Leute auf Lesbarkeit, Wartbarkeit, kürzeren Code und damit weniger Fehler und weil es viel einfacher ist, füge ich einen weiteren Grund hinzu:

Programmgeschwindigkeit.

Ja, bei der Montage können Sie Ihren Code von Hand optimieren, um jeden letzten Zyklus zu nutzen und ihn so schnell wie möglich zu machen. Doch wer hat die Zeit? Wenn Sie ein nicht ganz dummes C-Programm schreiben, kann der Compiler wirklich gut für Sie optimieren. Nehmen Sie wahrscheinlich mindestens 95% der Optimierungen vor, die Sie von Hand vornehmen würden, ohne dass Sie sich darum kümmern müssen, den Überblick zu behalten. Es gibt hier definitiv eine 90/10-Regel, bei der die letzten 5% der Optimierungen 95% Ihrer Zeit in Anspruch nehmen. Wieso sich die Mühe machen?


4
+1. Das Schreiben von Assembler-Code und das Schreiben von schnellem Assembler-Code sind zwei verschiedene Dinge. Wenn Sie einen guten Compiler verwenden, erhalten Sie den schnellen Assembler-Code kostenlos.
Niki

Sie erhalten schnellen Assembler-Code nur dann kostenlos, wenn Sie wissen, wie man den Compiler verwendet, die meisten verwenden keine Optimierung, die meisten Leute kompilieren mit Debug-Optionen und erhalten daher einen schlecht gemachten langsamen Assembler. Ja, in 99% der Fälle sollten Sie es nicht berühren. Berühren Sie einfach die Compiler-Regler und optimieren Sie die Ausgabe nicht direkt.
old_timer

Wenn Sie sich für die Optimierungen interessieren, sollten Sie dies vom Compiler aus tun ... WENN Sie sich nicht für Optimierungen interessieren, aber immer noch Assembly verwenden, sind Sie einfach nur albern.
Brian Postow

@dwelch: Ich denke, es gibt einige Script-Kiddies, die sich nicht die Mühe machen, herauszufinden, wie ihre Tools verwendet werden. Aber ich bezweifle, dass Leute wie sie jemals in der Lage sein würden, schnellen Assembler-Code zu schreiben.
Niki

13

Wenn ein durchschnittliches Produktionsprogramm beispielsweise 100.000 Codezeilen enthält und jede Zeile etwa 8-12 Assembler-Anweisungen enthält, entspricht dies 1 Million Assembler-Anweisungen.

Selbst wenn Sie dies alles von Hand mit einer anständigen Geschwindigkeit schreiben könnten (denken Sie daran, es ist 8-mal mehr Code, den Sie schreiben müssen), was passiert, wenn Sie einige der Funktionen ändern möchten? Es ist ein Albtraum, etwas zu verstehen, das Sie vor einigen Wochen aus diesen 1 Million Anweisungen geschrieben haben! Es gibt keine Module, keine Klassen, kein objektorientiertes Design, keine Frameworks, kein Nichts. Und die Menge an ähnlich aussehendem Code, die Sie selbst für die einfachsten Dinge schreiben müssen, ist bestenfalls entmutigend.

Außerdem können Sie Ihren Code nicht annähernd so gut optimieren wie eine Hochsprache. Wenn C beispielsweise eine wahnsinnige Anzahl von Optimierungen durchführt, weil Sie Ihre Absicht beschreiben , nicht nur Ihren Code. In Assembler schreiben Sie nur Code. Der Assembler kann keine wirklich notenwürdigen Optimierungen an Ihrem Code durchführen. Was Sie schreiben, erhalten Sie, und vertrauen Sie mir, Sie können 1 Million Anweisungen, die Sie beim Schreiben patchen und patchen, nicht zuverlässig optimieren.


8

Nun, ich habe "in den alten Tagen" viel Assembler geschrieben, und ich kann Ihnen versichern, dass ich viel produktiver bin, wenn ich Programme in einer Hochsprache schreibe.


8
"Versammlung ist lateinisch".
Adriano Varoli Piazza

4
@Adriano: außer es gibt viele, viele verschiedene Dialekte und keine zwei sehen gleich aus.
Joachim Sauer

1
Sicher, aber ich meinte, dass das Erlernen des Programmierens in einem von ihnen Ihnen einen Einblick in die Architektur einer Maschine gibt, die Ihnen auf höheren Ebenen hilft. Wenn Sie sich nicht mit ausgelagertem Speicher befassen, werden Sie in diesem Fall vernarbt. Als würde man Carmen 16 von Catullus lesen.
Adriano Varoli Piazza

5
@Adriano "Versammlung ist lateinisch", kein Asm ist Höhlenmensch grunzt. Ein Grunzen für Rock 2 Grunzen für Hirsche, 3 Grunzen für Feuer - gut für einfache Sachen, aber schwer, ein Imperium zu führen.
Martin Beckett

1
@ Martin: Haben Sie jemals versucht, komplexe Arithmetik mit römischen Ziffern durchzuführen?
Adriano Varoli Piazza

6

Ein angemessenes Maß an Assembler-Kompetenz ist eine nützliche Fähigkeit, insbesondere wenn Sie auf einer beliebigen Systemebene oder mit eingebetteter Programmierung arbeiten, nicht so sehr, weil Sie so viel Assembler schreiben müssen, sondern weil es manchmal wichtig ist, zu verstehen, was die Box wirklich tut . Wenn Sie kein Verständnis für Assembler-Konzepte und -Probleme haben, kann dies sehr schwierig sein.

Es gibt jedoch mehrere Gründe, warum beim Schreiben von viel Code in Assembler nicht viel getan wird.

  • Es gibt einfach keine (fast) Notwendigkeit. Abgesehen von der sehr frühen Systeminitialisierung und möglicherweise einigen in C-Funktionen oder Makros versteckten Assembler-Fragmenten kann der gesamte Code auf sehr niedriger Ebene, der möglicherweise einmal in Assembler geschrieben wurde, problemlos in C oder C ++ geschrieben werden.

  • Code in höheren Sprachen (sogar C und C ++) verdichtet die Funktionalität in weitaus weniger Zeilen, und es gibt umfangreiche Untersuchungen, die zeigen, dass die Anzahl der Fehler mit der Anzahl der Zeilen des Quellcodes korreliert. Das heißt, dasselbe Problem, das in Assembler und C gelöst wurde, wird mehr Fehler in Assembler haben, einfach weil es länger ist. Das gleiche Argument motiviert den Wechsel zu höheren Sprachen wie Perl, Python usw.

  • Wenn Sie in Assembler schreiben, müssen Sie sich mit jedem einzelnen Aspekt des Problems befassen, von detailliertem Speicherlayout, Befehlsauswahl, Algorithmusauswahl, Stapelverwaltung usw. Höhere Sprachen nehmen Ihnen all dies weg, weshalb Sie so viel dichter sind Bedingungen des LOC.

Im Wesentlichen beziehen sich alle oben genannten Punkte auf die Abstraktionsebene, die Ihnen in Assembler gegenüber C oder einer anderen Sprache zur Verfügung steht. Assembler zwingt Sie, alle Ihre eigenen Abstraktionen zu erstellen und diese durch Ihre eigene Selbstdisziplin aufrechtzuerhalten, wobei jede Sprache der mittleren Ebene wie C und insbesondere Sprachen der höheren Ebene Ihnen sofort verfügbare Abstraktionen sowie die Fähigkeit, relativ einfach neue zu erstellen.


6

Als Entwickler, der die meiste Zeit in der Welt der eingebetteten Programmierung verbringt, würde ich argumentieren, dass Assembly weit von einer toten / veralteten Sprache entfernt ist. Es gibt eine bestimmte metallnahe Codierungsstufe (z. B. in Treibern), die in einer höheren Sprache manchmal nicht so genau oder effizient ausgedrückt werden kann. Wir schreiben fast alle unsere Hardware-Schnittstellenroutinen in Assembler.

Davon abgesehen ist dieser Assemblycode so verpackt, dass er aus dem C-Code aufgerufen werden kann und wie eine Bibliothek behandelt wird. Wir schreiben aus vielen Gründen nicht das gesamte Programm in Assembly. In erster Linie ist Portabilität; Unsere Codebasis wird für mehrere Produkte verwendet, die unterschiedliche Architekturen verwenden, und wir möchten die Menge an Code maximieren, die zwischen ihnen geteilt werden kann. Zweitens ist die Vertrautheit der Entwickler. Einfach ausgedrückt, Schulen unterrichten Montage nicht mehr so ​​wie früher, und unsere Entwickler sind in C weitaus produktiver als in Montage. Außerdem steht für unseren C-Code eine Vielzahl von "Extras" (z. B. Bibliotheken, Debugger, statische Analysetools usw.) zur Verfügung, die für Assembler-Code nicht verfügbar sind. Auch wenn wir ein reines Montageprogramm schreiben wollten, Dies wäre nicht möglich, da mehrere wichtige Hardwarebibliotheken nur als C-Bibliotheken verfügbar sind. In gewisser Hinsicht ist es ein Henne / Ei-Problem. Die Leute werden von der Assembly vertrieben, weil nicht so viele Bibliotheken und Entwicklungs- / Debug-Tools dafür verfügbar sind, aber die Bibliotheken / Tools existieren nicht, weil nicht genügend Leute die Assembly verwenden, um den Aufwand für ihre Erstellung zu rechtfertigen.

Am Ende gibt es eine Zeit und einen Ort für nahezu jede Sprache. Menschen verwenden das, was sie am besten kennen und produktivsten. Es wird wahrscheinlich immer einen Platz im Assembler-Repertoire für Programmierer geben, aber die meisten Programmierer werden feststellen, dass sie Code in einer höheren Sprache schreiben können, die in viel kürzerer Zeit fast genauso effizient ist.


6

Wenn Sie in Assembly schreiben, müssen Sie nicht nur in Anweisungscodes schreiben. Sie können Makros und Prozeduren sowie Ihre eigenen Konventionen verwenden, um verschiedene Abstraktionen zu erstellen, um Programme modularer, wartbarer und leichter lesbar zu machen.

Sie sagen also im Grunde genommen, dass Sie mit dem geschickten Einsatz eines hoch entwickelten Assemblers Ihren ASM-Code immer näher an C (oder auf jeden Fall an eine andere Sprache auf niedriger Ebene Ihrer eigenen Erfindung) bringen können, bis Sie schließlich gerecht sind so produktiv wie ein C-Programmierer.

Beantwortet das deine Frage? ;-);

Ich sage das nicht untätig: Ich habe mit genau einem solchen Assembler und System programmiert. Noch besser ist, dass der Assembler auf einen virtuellen Prozessor abzielen kann und ein separater Übersetzer die Ausgabe des Assemblers für eine Zielplattform kompiliert. Ähnlich wie bei LLVMs IF, aber in seinen frühen Formen vor etwa 10 Jahren. Es gab also Portabilität und die Möglichkeit, Routinen für einen bestimmten Ziel-Assembler zu schreiben, wenn dies für die Effizienz erforderlich war.

Das Schreiben mit diesem Assembler war ungefähr so ​​produktiv wie C, und im Vergleich zu GCC-3 (das es zu meiner Zeit gab) produzierte der Assembler / Übersetzer Code, der ungefähr so ​​schnell und normalerweise kleiner war. Die Größe war wirklich wichtig, und das Unternehmen hatte nur wenige Programmierer und war bereit, neuen Mitarbeitern eine neue Sprache beizubringen, bevor sie etwas Nützliches tun konnten. Und wir hatten die Sicherung, dass Leute, die den Assembler nicht kannten (z. B. Kunden), C schreiben und es für denselben virtuellen Prozessor kompilieren konnten, wobei dieselbe Aufrufkonvention verwendet wurde und so weiter, so dass eine saubere Schnittstelle bestand. Es fühlte sich also wie ein geringfügiger Gewinn an.

Das war mit mehreren Mannjahren Arbeit in der Tasche, die Assembler-Technologie, Bibliotheken und so weiter zu entwickeln. Zugegeben, ein Großteil davon floss in die Portabilität, wenn es nur auf eine Architektur abgezielt hätte, wäre der allsingende All-Dance-Assembler viel einfacher gewesen.

Zusammenfassend: Sie mögen C vielleicht nicht, aber das bedeutet nicht, dass der Aufwand für die Verwendung von C größer ist als der Aufwand für die Entwicklung von etwas Besserem.


5

Die Baugruppe kann nicht zwischen verschiedenen Mikroprozessoren transportiert werden.


Dies ist bei modernen Prozessoren und Assembler-Programmen nicht genau der Fall. Sie können wie in C auf verschiedene Prozessoren abzielen. Sicher, Sie können in diesem Fall nicht alle Anweisungen verwenden, aber Sie auch nicht, wenn Sie sie schreiben in C. Portabilität ist nicht das Hauptanliegen.
Blindy

6
Vielleicht meinst du Architektur .
Ben S

2
@Blindy - Sie können verschiedene Prozessoren innerhalb der x86-Familie ansprechen, aber es gibt definitiv keine Gemeinsamkeiten in Montageanweisungen zwischen einer x86-Variante und einem ARM-Prozessor oder einem Z80 oder einem 8051.
Semaj

Stimmt, aber dann können Sie auch kein z80 in c programmieren. Ich denke, wir reden hier alle über normale x86 / x64-Prozessoren.
Blindy

1
Die ganze Welt ist kein x86. Nichts über "verschiedene Mikroprozessoren" deutet darauf hin, dass sie alle denselben Befehlssatz ausführen.
Bernd Jendrissek

5

Aus dem gleichen Grund gehen wir nicht mehr draußen auf die Toilette oder sprechen kein Latein oder Aramäisch.

Technologie kommt und macht die Dinge einfacher und zugänglicher.

BEARBEITEN - um die Beleidigung von Personen zu beenden, habe ich bestimmte Wörter entfernt.


4
Sie beleidigen immer noch Luddites mit dem WortTechnology
SeanJA

1
"Wir" sprechen kein Latein?
Dank

Weder Latein noch Aramäisch verschwanden, weil sie durch bessere Technologie ersetzt wurden (dh eine leichter zu erlernende / zu erlernende Sprache). Tatsächlich ist Latein immer noch überall in Europa bei uns. Alle römischen Sprachen basieren auf Latein. Das moderne (neo) Aramäisch wird heute von fast einer halben Million Menschen gesprochen. Die Gründe, warum diese Sprachen nicht mehr verbreitet sind, sind historisch (geopolitisch, genauer gesagt) und nicht technologisch. Der gleiche Grund, warum Englisch die Verkehrssprache der Wissenschaft und der herrschenden Klassen unserer Zeit ist - die Menschen des letzten Reiches, die Briten (und jetzt US-Amerikaner), sprechen es.
das Ritz

4

Warum? Einfach.

Vergleichen Sie dies:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

mit

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Sie sind in Bezug auf die Funktionen identisch. Der zweite ist nicht einmal Assembler, sondern .NET IL (Intermediary Language, ähnlich wie Javas Bytecode). Die zweite Kompilierung wandelt die IL in nativen Code um (dh fast Assembler), wodurch sie noch kryptischer wird.


3

Ich würde vermuten, dass ASM sogar auf x86 (_64) in Fällen sinnvoll ist, in denen Sie durch die Verwendung von Anweisungen, für die ein Compiler nur schwer optimieren kann, viel gewinnen. x264 verwendet zum Beispiel viel asm für seine Codierung, und die Geschwindigkeitsgewinne sind enorm.


2

Ich bin mir sicher, dass es viele Gründe gibt, aber zwei schnelle Gründe, die mir einfallen, sind:

  1. Assembler-Code ist definitiv schwerer zu lesen (ich bin mir sicher, dass das Schreiben auch zeitaufwändiger ist).
  2. Wenn ein großes Entwicklerteam an einem Produkt arbeitet, ist es hilfreich, Ihren Code in logische Blöcke zu unterteilen und durch Schnittstellen zu schützen.

1
Beachten Sie, dass Sie Assembly auch in logische Blöcke unterteilen können.
Paul Williams

2

Eine der frühen Entdeckungen (Sie finden sie in Brooks ' Mythical Man-Month , der aus Erfahrung in den 1960er Jahren stammt) war, dass Menschen in einer Sprache mehr oder weniger produktiv waren als in einer anderen, in debuggten Codezeilen pro Tag. Dies ist offensichtlich nicht allgemein gültig und kann brechen, wenn es zu weit gedrängt wird, aber es galt im Allgemeinen für die Hochsprachen der Zeit von Brooks.

Der schnellste Weg, um Produktivität zu erzielen, wäre daher die Verwendung von Sprachen, in denen eine einzelne Codezeile mehr bewirkt, und dies funktioniert tatsächlich, zumindest für komplexere Sprachen wie FORTRAN und COBOL, oder um ein moderneres Beispiel C zu nennen.


2

Portabilität ist immer ein Problem - wenn nicht jetzt, zumindest irgendwann. Die Programmierbranche gibt jedes Jahr Milliarden aus, um alte Software zu portieren, die zum Zeitpunkt der Erstellung "offensichtlich" keinerlei Probleme mit der Portabilität hatte.


2
"Es muss nicht auf eine andere Architektur portiert werden" klingt für mich sehr nach "Es werden nicht mehr als zwei Ziffern für das Jahr benötigt."
David Thornley

Oder können wir C # nicht verwenden, weil Windows möglicherweise nächstes Jahr nicht verfügbar ist?
Martin Beckett

Zum Beispiel Apples MacIntosh-Computer, die auf Prozessoren der Motorola MC68000-Serie, PowerPC (IBM et al.) Und jetzt Intels x86-Prozessoren (IA-32 (e)) basieren. Also ja, Portabilität ist ein Problem für jedes System, das lange genug verwendet wird, und jeder Programmierer, der nicht länger als erwartet von seinem Code gebissen wurde, hat noch keine Erfahrung.
mctylr

@Martin: In zwanzig Jahren wird es viele C # -Programme geben, die ausgeführt werden sollen, und daher wird es eine Möglichkeit geben, C # -Programme zu kompilieren und auszuführen. An C # ist nichts von Natur aus behoben, obwohl ich mich in zwanzig Jahren wundern würde, wenn es immer noch so beliebt wäre wie jetzt. In zwanzig Jahren werden sich unsere CPUs jedoch erheblich unterscheiden. Ein Assembler-Programm, das 1990 geschrieben wurde, läuft heutzutage zwar gut, ist aber sicher nicht optimal und läuft langsamer als kompiliertes C.
David Thornley

Das habe ich gemeint - ich habe viel mehr Portierungsprobleme, weil sich ein Framework auf hoher Ebene seit 6 Monaten geändert hat, als weil sich die Anweisungen in einem x86 geändert haben - insbesondere, weil handcodierter asm dazu neigt, sich an die einfachsten Methoden zu halten.
Martin Beckett

2

Es gab einen Teufelskreis, als Assembler weniger alltäglich wurden: Mit zunehmender Reife der übergeordneten Sprachen wurden Assembler-Befehlssätze weniger für die Bequemlichkeit der Programmierer als vielmehr für die Bequemlichkeit der Compiler erstellt.

Realistisch gesehen kann es jetzt sehr schwierig sein, die richtigen Entscheidungen zu treffen, beispielsweise welche Register Sie verwenden sollten oder welche Anweisungen etwas effizienter sind. Compiler können mithilfe von Heuristiken herausfinden, welche Kompromisse wahrscheinlich die beste Auszahlung erzielen. Wir können wahrscheinlich kleinere Probleme durchdenken und lokale Optimierungen finden, die unsere mittlerweile ziemlich hoch entwickelten Compiler übertreffen könnten, aber die Chancen stehen gut, dass ein guter Compiler im Durchschnitt beim ersten Versuch einen besseren Job macht als ein guter Programmierer wahrscheinlich. Schließlich könnten wir wie John Henry die Maschine schlagen, aber wir könnten uns ernsthaft verbrennen, um dorthin zu gelangen.

Unsere Probleme sind jetzt auch ganz anders. 1986 versuchte ich herauszufinden, wie ich aus kleinen Programmen, bei denen ein paar hundert Pixel auf den Bildschirm gebracht wurden, etwas mehr Geschwindigkeit herausholen konnte. Ich wollte, dass die Animation weniger ruckelt. Ein fairer Fall für Assemblersprache. Jetzt versuche ich herauszufinden, wie Abstraktionen in Bezug auf Vertragssprache und Servicerichtlinien für Hypotheken dargestellt werden können, und ich möchte lieber etwas lesen, das der Sprache, die die Geschäftsleute sprechen, nahe kommt. Im Gegensatz zu LISP-Makros erzwingen Assembly-Makros nicht viel Regeln. Auch wenn Sie in einem guten Assembler möglicherweise etwas erreichen können, das einem DSL angemessen nahe kommt, ist es anfällig für alle möglichen Macken, die gewonnen haben. ' Ich habe keine Probleme, wenn ich denselben Code in Ruby, Boo, Lisp, C # oder sogar F # geschrieben habe.

Wenn sich Ihre Probleme jedoch leicht in einer effizienten Assemblersprache ausdrücken lassen, erhalten Sie mehr Leistung.


2

Das Gleiche gilt für das, was andere gesagt haben.

In den guten alten Zeiten vor der Erfindung von C, als die einzigen Hochsprachen Dinge wie COBOL und FORTRAN waren, gab es viele Dinge, die einfach nicht möglich waren, ohne auf Assembler zurückzugreifen. Es war der einzige Weg, die volle Flexibilität zu erhalten, auf alle Geräte zugreifen zu können usw. Aber dann wurde C erfunden, und fast alles, was bei der Montage möglich war, war in C möglich. Ich habe seitdem sehr wenig Montage geschrieben dann.

Trotzdem denke ich, dass es eine sehr nützliche Übung für neue Programmierer ist, das Schreiben in Assembler zu lernen. Nicht weil sie es tatsächlich viel benutzen würden, sondern weil Sie dann verstehen, was wirklich im Computer passiert. Ich habe viele Programmierfehler und ineffizienten Code von Programmierern gesehen, die offensichtlich keine Ahnung haben, was wirklich mit den Bits, Bytes und Registern passiert.


Ja, genau richtig. Fortran Disk- und Tape-E / A auf IBM-Mainframes war vor Jahren so gut wie nutzlos, daher haben wir unsere eigenen E / A-Routinen in 370 / Assembler geschrieben und sie aus dem Fortan IV-Code aufgerufen. Durch das Schreiben von Assembler-Code habe ich die zugrunde liegende Architektur wirklich verstanden. Ich habe seit einigen Jahren keinen Assembler-Code mehr geschrieben und all die jüngeren Leute, mit denen ich zusammenarbeite, haben noch nie einen geschrieben - aber ich wünschte, sie würden es tun, es ist so lehrreich.
Simon Knights

2

Ich programmiere jetzt seit ungefähr einem Monat in der Montage. Ich schreibe oft einen Code in C und kompiliere ihn dann zur Assembly, um mich zu unterstützen. Vielleicht nutze ich nicht die volle Optimierungsleistung des C-Compilers, aber es scheint, dass meine C asm-Quelle unnötige Operationen enthält. Ich beginne zu erkennen, dass die Rede von einem guten C-Compiler, der einen guten Assembly-Codierer übertrifft, nicht immer wahr ist.

Wie auch immer, meine Montageprogramme sind so schnell. Und je mehr ich Assembly verwende, desto weniger Zeit brauche ich, um meinen Code zu schreiben, weil es wirklich nicht so schwer ist. Auch der Kommentar zur Montage mit schlechter Lesbarkeit ist nicht wahr. Wenn Sie Ihre Programme korrekt beschriften und Kommentare abgeben, wenn zusätzliche Ausarbeitungen erforderlich sind, sollten Sie bereit sein. In gewisser Weise ist die Montage für den Programmierer klarer, da er sieht, was auf der Ebene des Prozessors geschieht. Ich weiß nichts über andere Programmierer, aber für mich mag ich es zu wissen, was passiert, anstatt Dinge in einer Art Black Box zu haben.

Der eigentliche Vorteil von Compilern besteht darin, dass ein Compiler Muster und Beziehungen verstehen und sie dann automatisch an den entsprechenden Stellen in der Quelle codieren kann. Ein beliebtes Beispiel sind virtuelle Funktionen in C ++, bei denen der Compiler Funktionszeiger optimal zuordnen muss. Ein Compiler kann jedoch nur das tun, was der Hersteller des Compilers dem Compiler erlaubt. Dies führt dazu, dass Programmierer manchmal auf bizarre Dinge mit ihrem Code zurückgreifen müssen, um die Codierungszeit zu verlängern, wenn dies mit der Montage trivial möglich gewesen wäre.

Persönlich denke ich, dass der Markt Hochsprachen stark unterstützt. Wenn Assemblersprache die einzige Sprache wäre, die heute existiert, dann würden etwa 70% weniger Leute programmieren und wer weiß, wo unsere Welt sein würde, wahrscheinlich in den 90er Jahren. Höhere Sprachen sprechen ein breiteres Spektrum von Menschen an. Dies ermöglicht ein höheres Angebot an Programmierern, um die benötigte Infrastruktur unserer Welt aufzubauen. Entwicklungsländer wie China und Indien profitieren stark von Sprachen wie Java. Diese Länder werden ihre IT-Infrastruktur schnell entwickeln und die Menschen werden stärker miteinander verbunden. Mein Punkt ist also, dass Hochsprachen nicht deshalb beliebt sind, weil sie überlegenen Code produzieren, sondern weil sie dazu beitragen, die Nachfrage auf den Weltmärkten zu befriedigen.


+1 für Black-Box-Sache. Ja, wir verwenden Black Boxes und es gibt keine Möglichkeit, einen Blick darauf zu werfen (zu einfach). Wie funktioniert C # foreach wirklich? Wer weiß. Microsoft sagte, es ist perfekt. Dann muss es sein.
ern0

Vergessen Sie auch nicht, dass mit einer „Hochsprache“ viele andere Dinge einhergehen, die in der realen Welt wichtig sind. C kommt mit den Standardbibliotheken (Mathematik, Zeichenfolgenverarbeitung, E / A usw.), und dann kommen die schweren Gewichte wie Java mit vielen anderen Paketen und Bibliotheken für Konnektivität, Bildverarbeitung, Datenverarbeitung, Webentwicklung usw. Es ist eine Frage Sie können Ihre Zeit nutzen, um sich darauf zu konzentrieren, eine detaillierte Aufgabe auf einer Plattform hochleistungsfähig zu machen (also Assembly zu verwenden), anstatt dieselbe Zeit damit zu verbringen, eine viel größere Aufgabe auf mehreren Plattformen mit minimalen Fehlern auszuführen.
jbx

1

Ich lerne gerade Assembler in Comp Org, und obwohl es interessant ist, ist es auch sehr ineffizient, darin zu schreiben. Sie müssen viel mehr Details im Kopf behalten, um die Dinge zum Laufen zu bringen, und es ist auch langsamer, dieselben Dinge zu schreiben . Beispielsweise kann eine einfache 6-Zeilen-for-Schleife in C ++ 18 oder mehr Assembly-Zeilen entsprechen.

Persönlich macht es viel Spaß zu lernen, wie die Dinge auf Hardware-Ebene funktionieren, und es gibt mir eine größere Wertschätzung dafür, wie Computer funktionieren.


1

Was C gegenüber einem guten Makro-Assembler hat, ist die Sprache C. Typprüfung. Schleifenkonstrukte. Automatische Stapelverwaltung. (Fast) automatische Variablenverwaltung. Dynamische Speichertechniken im Assembler sind ein massiver Schmerz im Hintern. Eine verknüpfte Liste richtig zu machen ist im Vergleich zu C oder besser noch foo.insert () beängstigend. Und Debuggen - nun, es gibt keinen Wettbewerb darüber, was einfacher zu debuggen ist. HLLs gewinnen dort unten zweifellos.

Ich habe fast die Hälfte meiner Karriere als Assembler programmiert, was es mir sehr leicht macht, in Assmebler zu denken. Es hilft mir zu sehen, was der C-Compiler tut, was mir wiederum hilft, Code zu schreiben, den der C-Compiler effizient verarbeiten kann. Eine gut durchdachte Routine in C kann geschrieben werden, um mit ein wenig Arbeit genau das auszugeben, was Sie in Assembler wollen - und sie ist portabel! Ich musste bereits einige ältere ASM-Routinen aus plattformübergreifenden Gründen wieder auf C umschreiben, und es macht keinen Spaß.

Nein, ich bleibe bei C und beschäftige mich mit der gelegentlichen leichten Leistungsabnahme gegenüber der Produktivitätszeit, die ich mit HLL gewinne.


1

Ich kann nur antworten, warum ich persönlich nicht öfter Programme in Assembly schreibe, und der Hauptgrund ist, dass es langwieriger ist , dies zu tun. Ich denke auch, dass es einfacher ist, Dinge auf subtile Weise falsch zu machen, ohne es sofort zu bemerken. Sie können beispielsweise die Art und Weise ändern, wie Sie ein Register in einer Routine verwenden, aber vergessen, dies an einer Stelle zu ändern. Es wird gut zusammengebaut und Sie werden es vielleicht erst viel später bemerken.

Trotzdem denke ich, dass es noch gültige Verwendungszwecke für die Montage gibt. Zum Beispiel habe ich eine Reihe ziemlich optimierter Assembler-Routinen für die Verarbeitung großer Datenmengen unter Verwendung von SIMD und nach dem paranoiden Ansatz "Jedes Bit ist heilig" [Zitat V.Stob]. (Beachten Sie jedoch, dass naive Assembly-Implementierungen oft viel schlechter sind als das, was ein Compiler für Sie generieren würde.)


1

C ist ein Makro-Assembler! Und es ist das beste!

Es kann fast alles, was Assemblierung kann, kann portabel sein und in den meisten seltenen Fällen, in denen es nichts kann, können Sie immer noch eingebetteten Assembler-Code verwenden. Dies lässt nur einen kleinen Teil der Programme übrig, die Sie unbedingt in Assembly schreiben müssen, und nichts als Assembly.

Aufgrund der höheren Abstraktionen und der Portabilität lohnt es sich für die meisten Benutzer, Systemsoftware in C zu schreiben. Auch wenn Sie jetzt möglicherweise keine Portabilität benötigen, wenn Sie viel Zeit und Geld in das Schreiben eines Programms investieren, möchten Sie sich möglicherweise nicht einschränken in was Sie es in Zukunft verwenden können.


1

Die Leute scheinen zu vergessen, dass es auch die andere Richtung gibt.

Warum schreibst du überhaupt in Assembler? Warum nicht das Programm in einer wirklich niedrigen Sprache schreiben?

Anstatt

mov eax, 0x123
add eax, 0x456
push eax
call printInt

du könntest genauso gut schreiben

B823010000
0556040000
50 
FF15.....

Das hat so viele Vorteile, dass Sie die genaue Größe Ihres Programms kennen, den Wert von Anweisungen als Eingabe für andere Anweisungen wiederverwenden können und nicht einmal einen Assembler zum Schreiben benötigen. Sie können einen beliebigen Texteditor verwenden ...

Und der Grund, warum Sie Assembler immer noch bevorzugen, ist der Grund, warum andere Leute C ...


0

Weil es immer so ist: Zeit vergeht und auch gute Dinge vergehen :(

Aber wenn Sie asm-Code schreiben, ist das ein völlig anderes Gefühl als beim Codieren von langsamen High-Levels, obwohl Sie wissen, dass es viel weniger produktiv ist. Es ist, als wären Sie ein Maler: Sie können alles, was Sie möchten, ohne Einschränkungen nach Ihren Wünschen zeichnen (naja, nur nach CPU-Funktionen) ... Deshalb liebe ich es. Schade, dass diese Sprache verschwindet. Aber während sich jemand noch daran erinnert und es codiert, wird es niemals sterben!


Wahr. Auf der anderen Seite gibt es die Demütigung, die Sie erleben, wenn die Kassiererin und der Supermarkt sich weigern, Ihren Scheck einzulösen, und verächtlich sagen: "Oh, Sie programmieren in einer Sprache mit niedrigem Niveau."
Jay

0

$$$

Ein Unternehmen stellt einen Entwickler ein, um Code in $$$ umzuwandeln. Je schneller das nützlich ist Code erstellt werden kann, desto schneller kann das Unternehmen diesen Code in $$$ umwandeln.

Höhere Sprachen sind im Allgemeinen besser darin, größere Mengen nützlichen Codes zu produzieren. Dies bedeutet nicht, dass die Versammlung ihren Platz nicht hat, denn es gibt Zeiten und Orte, an denen nichts anderes tun wird.


0

Der Vorteil von HLLs ist noch größer, wenn Sie Assembly mit einer höheren Sprache als C vergleichen, z. B. Java, Python oder Ruby. Diese Sprachen verfügen beispielsweise über eine Speicherbereinigung: Sie müssen sich keine Gedanken darüber machen, wann ein Teil des Speichers freigegeben werden muss, und es gibt keine Speicherlecks oder Fehler aufgrund einer zu frühen Freigabe.


0

Wie bereits erwähnt, besteht der Grund für die Existenz eines Tools darin, wie effizient es arbeiten kann. Da HLLs dieselben Aufgaben wie viele Zeilen ASM-Code ausführen können, ist es natürlich selbstverständlich, dass Assemblys von anderen Sprachen abgelöst werden. Und für das Hardware-nahe Fummeln gibt es Inline-Assemblys in C und anderen Varianten gemäß Sprache. Dr. Paul Carter sagt in der PC-Assemblersprache

"... ein besseres Verständnis dafür, wie Computer wirklich auf einer niedrigeren Ebene funktionieren als in Programmiersprachen wie Pascal. Durch ein tieferes Verständnis der Funktionsweise von Computern kann der Leser häufig viel produktiver Software in höheren Sprachen wie C entwickeln und C ++. Das Erlernen des Programmierens in Assemblersprache ist ein hervorragender Weg, um dieses Ziel zu erreichen. "

Wir haben eine Einführung in die Montage in meinen College-Kursen. Es wird helfen, Konzepte zu klären. Ich bezweifle jedoch, dass einer von uns 90% des Codes in Assembly schreiben würde. Wie relevant ist fundiertes Montagewissen heute?


-2

Wenn ich diese Antworten durchblättere, würde ich wetten, dass 9/10 der Antwortenden noch nie mit der Montage gearbeitet haben.

Dies ist eine uralte Frage, die immer wieder auftaucht und Sie erhalten die gleichen, meist falsch informierten Antworten. Ohne Portabilität würde ich immer noch alles selbst in der Montage tun. Selbst dann codiere ich in C fast so wie in der Montage.


1
+1 Erwähnung von Personen ohne Asm-Erfahrung und ein weiteres +1 für "Codierung in C wie Asm". Wenn ich C ++ (ja, CPP, nicht C) Apps für Embedded schreibe, codiere ich sozusagen asm, z. B. ohne new / malloc ().
ern0

Sie verwenden also viele Dinge wie char buf [MAX_PATH], die dann umfallen, wenn jemand Daten mit der Größe MAX_PATH + n hat? ;)
Paulm

1
@paulm - Du meinst genau wie C?
Rob

1
Ich hoffe, dass Assembler-Autoren die Verwendung von malloc () nicht vermeiden. Ja, bei Embedded sind Sie speicherbeschränkt. Wenn Sie dies jedoch unter Unix oder einem anderen Desktop (oder sogar den meisten mobilen Betriebssystemen) tun, schränken Sie sich und Ihre Benutzer nur unnötig ein. Außerdem: Je weniger LOC Sie schreiben, desto geringer ist die Wahrscheinlichkeit von Fehlern, was bedeutet, dass Code höherer Ebene wahrscheinlich weniger Fehler aufweist als niedrigere.
uliwitness

1
Ich habe nur geschaut, weil ich misstrauisch war und ich kann sicher sagen, dass die Redakteure und HNer hier sind.
Rob
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.