Wie hilft das Lernen der Assembler beim Programmieren? [geschlossen]


132

Ich programmiere seit ungefähr 10 Jahren in höheren Programmiersprachen (Python, C #, VBA, VB.NET) und habe keinerlei Verständnis dafür, was "unter der Haube" vor sich geht.

Ich frage mich, welche Vorteile das Lernen von Assembler hat und wie es mir als Programmierer helfen wird. Können Sie mir bitte eine Ressource zur Verfügung stellen, die mir genau den Zusammenhang zwischen dem, was ich in höherem Code schreibe, und dem, was in der Assembly passiert, zeigt?


2
Wenn Sie wirklich wissen möchten, was tief in Ihrem Code steckt, lesen Sie das Intel-Prozessorhandbuch (nur der einleitende Teil): download.intel.com/products/processor/manual/325462.pdf . Vielleicht ist das etwas tiefer als Sie wollten, aber ich finde es nützlich.
SuperM

4
Wenn Sie wissen möchten, was unter der Haube speziell in .Net passiert, möchten Sie vielleicht mehr über CIL erfahren. In gewisser Hinsicht ähnelt es dem Zusammenbau, ist aber viel höher. Aus diesem Grund ist es einfacher zu verstehen als die eigentliche Montage.
Svick

6
Wenn Sie Assemblierung lernen, können Sie vermeiden, dass Sie glauben, eine forSchleife zu optimieren, indem Sie Variablen außerhalb der Schleife deklarieren. Beispiel
StriplingWarrior

7
Oh mein Gott. Sie haben mich nur an den Assemblersprachkurs erinnert, den ich vor ungefähr einem Jahr am College besucht habe. Es ist einfach erstaunlich zu sehen, wie extrem einfache Dinge, die wir für selbstverständlich halten, in Hunderten oder sogar Tausenden kleinerer und niedrigerer Operationen übersetzt werden. Computer sind außergewöhnliche Maschinen.
Radu Murzea

14
Das Erlernen von Assembler vermittelt Ihnen eine tiefe und beständige Liebe für das Konzept der Programmiersprache, die Sie davor schützt, dass Sie in Assembler immer wieder komplexen Code schreiben müssen.
Shadur

Antworten:


188

Weil Sie verstehen werden, wie es wirklich funktioniert.

  • Sie werden verstehen, dass Funktionsaufrufe nicht kostenlos sind und warum der Aufrufstapel überlaufen kann (z. B. in rekursiven Funktionen). Sie werden verstehen, wie Argumente an Funktionsparameter übergeben werden und wie dies durchgeführt werden kann (Kopieren des Speichers, Zeigen auf den Speicher).
  • Sie werden verstehen, dass Speicher nicht kostenlos ist und wie wertvoll die automatische Speicherverwaltung ist. Gedächtnis ist nicht etwas, das Sie "nur haben", in Wirklichkeit muss es verwaltet, gepflegt und vor allem nicht vergessen werden (weil Sie es selbst befreien müssen).
  • Sie werden verstehen, wie der Kontrollfluss auf einer grundlegendsten Ebene funktioniert.
  • Sie werden die Konstrukte in höheren Programmiersprachen mehr zu schätzen wissen.

Alles, was wir in C # oder Python schreiben, muss in eine Folge grundlegender Aktionen übersetzt werden, die ein Computer ausführen kann. Es ist leicht, sich einen Computer in Bezug auf Klassen, Generika und Listenverständnisse vorzustellen, aber diese existieren nur in unseren höheren Programmiersprachen.

Wir können uns Sprachkonstrukte vorstellen, die wirklich gut aussehen, sich aber nicht gut auf eine einfache Art und Weise übersetzen lassen. Wenn Sie wissen, wie es wirklich funktioniert, werden Sie besser verstehen, warum die Dinge so funktionieren, wie sie funktionieren.


12
+1 für "Sie werden die Konstrukte in höheren Programmiersprachen mehr zu schätzen wissen". Gute Antwort.
DevSolo

42
Abgesehen davon, dass Sie nach ein paar Wochen asm anfangen, sich C als Programmiersprache auf hohem Niveau vorzustellen. Es sei denn, Sie sprechen mit Entwicklern von Embedded-Geräten auf niedrigem Niveau. Wenn Sie sagen, dass es laut ist, denken die meisten Menschen, dass Sie ein bisschen verrückt sind.
Dan Neely

19
@Dan: Es ist schon komisch, wie sich diese Begriffe im Laufe der Zeit ändern. Als ich vor 20 Jahren mit dem Programmieren anfing, hättest du jemanden gefragt, ob er sagen würde: "Natürlich ist C eine Hochsprache!" Das sollte klar sein; Es bietet ein standardisiertes Heap- und Speicherzugriffsmodell. Und das ist eine ernsthafte Abstraktion von der Hardware; In einer einfachen Sprache müssen Sie alle Speicheradressen selbst nachverfolgen, oder wenn Sie etwas wirklich Fantasievolles tun , schreiben Sie Ihren eigenen Heap-Allokator! Also muss ich mich fragen, was sind die Kriterien, die heutzutage ein hohes oder niedriges Niveau ausmachen?
Mason Wheeler

9
High-Level / Low-Level ist keine Binärdatei. Eine vielseitige Programmiererin, die in ihrer Karriere sowohl Assembler als auch Python geschrieben hat, könnte C oder C ++ als Mittelstufensprache betrachten.
Russell Borogove

6
Das sind wichtige Dinge, die zu verstehen sind, aber auf abstrakter Ebene leicht behandelt werden können: z. B. in einem Einführungskurs in Computer auf der Ebene der Maschinenanweisungen. Ich bin kein Assembler-Programmierer, aber ich verstehe sie gut, wenn ich es selbst sage. In einigen SO-Antworten sehe ich Diskussionen über Anweisungs-Caches und -Pipelines, und diese lassen meinen Kopf tatsächlich drehen. Diese Unteranweisungsebene fehlt jedoch (bisher) in den Antworten. Was ist der Vorteil, wenn Sie tatsächlich Assembler-Programmierung lernen, anstatt einen Grundkurs zu belegen?
Alexis

33

Sie erhalten ein besseres Verständnis dafür, was "unter der Haube passiert" und wie Zeiger funktionieren und welche Bedeutung Registervariablen und Architekturen (Speicherzuweisung und -verwaltung, Parameterübergabe (nach Wert / Referenz) usw.) im Allgemeinen haben.

Für einen kurzen Blick mit C, wie ist das?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

Kompilieren Sie mit gcc -S so.cund werfen Sie einen Blick auf die Assembly-Ausgabe in so.s:

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

2
+1: Guter Tipp! Sie können viel lernen, indem Sie sich ansehen, was der C-Compiler macht.
Giorgio

8
... War die SOS beabsichtigt? (um Hilfe rufen, etc.)
Izkata

1
@ Izkata ha ha .. gute, ich habe das nicht einmal bemerkt. Ich habe eine Standarddatei so.cfür Stackoverflow-Fragen (wie ich so.py, so.awketc.), um die Dinge schnell zu testen. So.S .. :)
Levon

9
Wenn Sie mit kompilieren gcc -O -c -g -Wa,-ahl=so.s so.c, sehen Sie die Assembly-Ausgabe für jede Zeile des C-Codes. Dies macht es ein wenig einfacher zu verstehen, was los ist.
Mackie Messer

1
Ja, die Ausgabe ist lang. Sie können nach suchen 5:so.c, um den Code für Zeile 5 von zu finden so.c.
Mackie Messer

30

Ich denke, die Antwort, die Sie suchen, ist hier: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language

Ein Zitat aus dem Artikel:

Obwohl es stimmt, werden Sie wahrscheinlich nicht feststellen, dass Sie die App Ihres nächsten Kunden in Assembler schreiben. Es gibt jedoch noch viel zu gewinnen, wenn Sie Assembler lernen. Heutzutage wird Assemblersprache hauptsächlich für die direkte Hardwaremanipulation, den Zugriff auf spezielle Prozessoranweisungen oder zur Behebung kritischer Leistungsprobleme verwendet. Typische Anwendungen sind Gerätetreiber, Embedded-Systeme auf niedriger Ebene und Echtzeitsysteme.

Die Tatsache ist, dass je komplexer Hochsprachen werden und je mehr ADT (abstrakte Datentypen) geschrieben werden, desto mehr Aufwand entsteht, um diese Optionen zu unterstützen. In den Fällen von .NET möglicherweise aufgeblähtes MSIL. Stellen Sie sich vor, Sie kennen MSIL. Hier erstrahlt die Assemblersprache.

Die Assemblersprache ist so nahe am Prozessor wie Sie es von einem Programmierer gewohnt sind. Ein gut gestalteter Algorithmus ist also unübersehbar - Assemblersprache ist ideal für die Geschwindigkeitsoptimierung. Es geht um Leistung und Effizienz. Assemblersprache gibt Ihnen die vollständige Kontrolle über die Systemressourcen. Ähnlich wie bei einer Fertigungsstraße schreiben Sie Code, um einzelne Werte in Register zu verschieben und Speicheradressen direkt zu verarbeiten, um Werte oder Zeiger abzurufen.

In Assembler zu schreiben bedeutet, genau zu verstehen, wie Prozessor und Speicher zusammenarbeiten, um "Dinge geschehen zu lassen". Seien Sie gewarnt, die Assemblersprache ist kryptisch und der Quellcode der Anwendung ist viel größer als der einer Hochsprache. Aber machen Sie keinen Fehler, wenn Sie bereit sind, die Zeit und die Mühe zu investieren, um die Montage zu meistern, werden Sie besser und werden zu einem herausragenden Unternehmen auf dem Gebiet.

Darüber hinaus würde ich dieses Buch empfehlen, da es eine vereinfachte Version der Computerarchitektur enthält: Einführung in Computersysteme: Von Bits und Gates zu C und darüber hinaus, 2 / e Yale N. Patt, Universität Texas, Austin Sanjay J. Patel, Universität von Illinois in Urbana / Champaign


7
In diesem Artikel wird beschrieben, wofür ASM verwendet wird, und es wird erwähnt, dass HLLs aufgebläht sind. Der einzige spezifische Vorteil beim Erlernen von ASM ist das Schreiben von superschnellem Code. Ja, aber selbst wenn Sie ASM lernen, wie wahrscheinlich ist es, dass Sie es tatsächlich in Apps einbinden? Angenommen, Sie schreiben Geschäftsanwendungen, keine Hardware-Controller oder Gerätetreiber.

+1 @notkilroy, danke für den Link und vor allem die Buchempfehlung
Anthony

2
@ Jon, ich verstehe wirklich nicht, warum Sie das tun würden, wenn Sie Unternehmenssoftware entwickeln. Es ist eine Sache, wenn Sie ein DBA sind, einen Compiler schreiben oder über begrenzten Speicherplatz verfügen, aber ich denke, dass nicht viele Leute ihn häufig berühren. Die Optimierung wird größtenteils vom Compiler übernommen, was der Hauptgrund für das Schreiben in der Assembly ist. Manchmal hilft es beim Aufspüren von Speicherlecks.
Brynne

Da ich auf die Entwicklung von Geschäftsanwendungen spezialisiert bin, verlasse ich mich hauptsächlich auf SQL-basierte App-Entwicklungstools, die eine 4GL verwenden. Sie ermöglichen es mir, schnell Prototypen einer App zu erstellen und diese in ein Produktionssystem umzuwandeln. Selten muss ich eine aufrufbare cfunc schreiben. Zeit zu liefern und Zeit zu modifizieren sind große Faktoren in meiner Welt!
Frank R.

2
Da bin ich ganz anderer meinung Ein automatisierter Optimierer kann einen menschlichen Programmierer bei der Schaffung einer schnellen Montage oft schlagen.
DeadMG

22

Meiner bescheidenen Meinung nach hilft es nicht viel.

Ich kannte x86-Assembly sehr gut. Es hat ein wenig geholfen, als in meinen Kursen Assembler auftauchte, es ist einmal während eines Interviews aufgetaucht, und es hat mir geholfen zu beweisen, dass ein Compiler (Metrowerks) schlechten Code generiert hat. Es ist faszinierend, wie der Computer tatsächlich funktioniert, und ich fühle mich geistig reicher, wenn ich ihn gelernt habe. Es hat damals auch sehr viel Spaß gemacht, damit zu spielen.

Die heutigen Compiler sind jedoch besser in der Lage, Assembler zu generieren als fast jeder andere, der mit fast jedem Code arbeitet. Wenn Sie keinen Compiler schreiben oder überprüfen, ob Ihr Compiler das Richtige tut, verschwenden Sie wahrscheinlich Ihre Zeit, indem Sie ihn erlernen.

Ich gebe zu, dass viele Fragen, die C ++ - Programmierer immer noch sinnvoll stellen, durch Assembler-Kenntnisse beantwortet werden. Beispiel: Soll ich Stack- oder Heap-Variablen verwenden? soll ich als Wert oder als konstante Referenz übergeben? In fast allen Fällen sollten diese Entscheidungen jedoch auf der Grundlage der Lesbarkeit des Codes getroffen werden, anstatt Rechenzeit zu sparen. (Verwenden Sie Stapelvariablen, wenn Sie eine Variable auf einen Bereich beschränken möchten.)

Mein bescheidener Vorschlag ist, mich auf Fähigkeiten zu konzentrieren, die wirklich wichtig sind: Software-Design, Algorithmus-Analyse und Problemlösung. Mit der Erfahrung, große Projekte zu entwickeln, wird sich Ihre Intuition verbessern, was Ihren Wert viel mehr steigert als das Wissen um die Montage (meiner Meinung nach).


2
Ich stimme nicht zu. Wenn Sie umfassende Kenntnisse über einen bestimmten Algorithmus und ein gutes Verständnis der Hardware haben, ist es normalerweise möglich, Assembly-Code zu erstellen, der besser optimiert ist als das, was der Compiler erstellen kann, da er auf Nummer sicher gehen muss. Wenn Sie ungefähr wissen, wie Ihr Code in Assembler übersetzt wird, können Sie auch Optimierungen vornehmen.
Leo

Optimierung ist nicht der Grund, es zu lernen. In dieser Hinsicht stimme ich Neil G zu. Er unterschätzt, wie sein grundlegendes Verständnis der realen Maschine darüber Auskunft gibt, wie er die Hochsprache verwendet.
Warren P

Nach meiner Erfahrung wird ein Algorithmus schnell umgesetzt, indem Dinge gemessen, Optimierungsmöglichkeiten gefunden, bessere Methoden implementiert usw. usw. usw. Das Problem bei der Montage besteht darin, dass die Implementierung Ewigkeiten in Anspruch nimmt, was Sie jedoch nicht tun werden die Möglichkeit einer nochmaligen Verfeinerung haben.
gnasher729

Es gibt heutzutage nur sehr wenige Fälle, in denen Code in Assembler geschrieben werden muss, aber zu wissen, wie es funktioniert, ist einfach von unschätzbarem Wert und hilft denjenigen, die wissen möchten, wie alles funktioniert, sehr viel. Ich finde es zum Beispiel schwierig, Dinge zu verfolgen, wenn ich nicht weiß, warum es passiert.
Flügelspieler Sendon

21

Sie sollten mit einer Ebene „tiefer“ in dem System vertraut sein, auf dem Sie arbeiten. In einem Rutsch zu weit nach unten zu springen ist nicht schlecht, aber möglicherweise nicht so hilfreich, wie man es sich wünscht.

Ein Programmierer in einer höheren Sprache sollte eine niedrigere Sprache lernen (C ist eine ausgezeichnete Option). Sie müssen nicht den ganzen Weg bis zum Zusammenbau zurücklegen, um eine Vorstellung davon zu bekommen, was unter der Decke vor sich geht, wenn Sie den Computer anweisen, ein Objekt zu instanziieren oder eine Hash-Tabelle oder einen Satz zu erstellen - aber Sie sollten in der Lage sein, Code zu erstellen Sie.

Für einen Java-Programmierer würde das Erlernen von C Ihnen bei der Speicherverwaltung helfen und Argumente übergeben. Wenn Sie einige der umfangreichen Java-Bibliotheken in C schreiben, können Sie nachvollziehen, wann Sie welche Implementierung von Set verwenden müssen (möchten Sie einen Hash oder einen Baum?). Der Umgang mit char * in einer Thread-Umgebung hilft zu verstehen, warum String unveränderlich ist.

Auf die nächste Ebene gebracht ... AC-Programmierer sollten mit Baugruppen vertraut sein, und Baugruppentypen (die häufig in eingebetteten Systemgeschäften zu finden sind) eignen sich wahrscheinlich gut für das Verständnis der Gatter. Wer mit Toren arbeitet, sollte sich mit Quantenphysik auskennen. Und diese Quantenphysiker versuchen immer noch herauszufinden, was die nächste Abstraktion ist.


1
Eine Ebene tiefer ist ungefähr richtig. Ich tendiere dazu, mich für ein Paar zu entscheiden, aber die Annahme, dass x86-Assembler-Kenntnisse die Investition wert sind, im Vergleich zum Studium von MSIL für einen C # -Programmierer, verlangt zu viel. Als jemand, der Montage- und Festkörperphysik an der Uni studiert hat, glaube ich nicht, dass es mir geholfen hat, die Physik des Gate-Designs zu kennen, abgesehen von meinem Abschluss in Elektronik.
Muhammad Alkarouri

@MuhammadAlkarouri Ich dachte nach, um die Leckströme, die Lauflänge, den Widerstand und den Einfluss von Wärme auf das System zu verstehen. Das Verständnis des zugrunde liegenden „Warum“ hilft dabei, Entscheidungen zu treffen, die mehr sind als Regeln für minimale Spurentrennung und Betriebstoleranzen.

5

Da Sie C oder C ++ in den Sprachen, die Sie kennen, nicht erwähnt haben. Ich würde DRINGEND empfehlen, sie gut zu lernen, bevor ich überhaupt an die Montage denke. C oder C ++ bietet alle grundlegenden Konzepte, die in verwalteten Sprachen vollständig transparent sind, und Sie werden die meisten der auf dieser Seite erwähnten Konzepte mit einer der wichtigsten Sprachen verstehen, die Sie in Projekten der realen Welt verwenden können. Es ist ein echter Mehrwert für Ihre Programmierkenntnisse. Bitte beachten Sie, dass Assembly in sehr spezifischen Bereichen verwendet wird und nicht annähernd so nützlich ist wie C oder C ++.

Ich würde sogar noch weiter gehen und sagen, dass Sie nicht in die Versammlung eintauchen sollten, bevor Sie nicht verstanden haben, wie nicht verwaltete Sprachen funktionieren. Es ist fast eine Pflichtlektüre.

Sie sollten die Montage lernen, wenn Sie noch weiter nach unten wollen. Sie möchten wissen, wie genau jedes Konstrukt der Sprache erstellt wird. Es ist informativ, aber es ist eine ganz andere Komplexität.


5

Wenn Sie eine Sprache gut beherrschen, sollten Sie mindestens Grundkenntnisse der Technologie auf einer niedrigeren Abstraktionsebene haben.

Warum? Wenn etwas schief geht, erleichtert die Kenntnis der zugrunde liegenden Mechanik das Debuggen seltsamer Probleme und das Schreiben von effizienterem Code

Wenn Sie Python (/ CPython) als Beispiel verwenden und anfangen, seltsame Abstürze oder eine schlechte Leistung zu erzielen, kann das Wissen über das Debuggen von C-Code sehr hilfreich sein, ebenso wie das Wissen über die Speicherverwaltungsmethode für das erneute Zählen. Dies würde Ihnen auch helfen, zu wissen, wann / ob Sie etwas als C-Erweiterung schreiben müssen, und so weiter ...

Um Ihre Frage in diesem Fall zu beantworten, würde Assembler-Kenntnisse einem erfahrenen Python-Entwickler nicht wirklich weiterhelfen (die Abstraktion geht zu weit zurück - alles, was in Python getan wird, würde zu vielen, vielen Assembler-Anweisungen führen).

..aber, wenn Sie mit C erfahren sind, dann wäre es in der Tat nützlich, "die nächste Ebene nach unten" (Assembly) zu kennen.

Ebenso ist es (sehr) nützlich, Javascript zu kennen, wenn Sie CoffeScript verwenden. Wenn Sie Clojure verwenden, sind Kenntnisse in Java / JVM hilfreich.

Diese Idee funktioniert auch außerhalb von Programmiersprachen. Wenn Sie Assembly verwenden, sollten Sie mit der Funktionsweise der zugrunde liegenden Hardware vertraut sein. Wenn Sie ein Webdesigner sind, ist es eine gute Idee zu wissen, wie die Webanwendung implementiert ist. Wenn Sie ein Automechaniker sind, ist es eine gute Idee, einige Kenntnisse der Physik zu haben


3

Schreiben Sie ein kleines c-Programm und zerlegen Sie die Ausgabe. Das ist alles. Seien Sie jedoch auf einen größeren oder geringeren Grad an "Housekeeping" -Code vorbereitet, der zum Nutzen des Betriebssystems hinzugefügt wird.

Assembly hilft Ihnen zu verstehen, was unter der Haube vor sich geht, da es sich direkt um Speicher, Prozessorregister und dergleichen handelt.

Wenn Sie wirklich Bare-Metal wollen, ohne dass die Komplexität eines Betriebssystems die Dinge kompliziert, versuchen Sie, ein Arduino in Assembler-Sprache zu programmieren .


3

Es gibt keine definitive Antwort, da Programmierer nicht alle von einem Typ sind. MÜSSEN Sie wissen, was sich darunter verbirgt? Wenn ja, dann lerne es. Wollen Sie es nur aus Neugier lernen? Wenn ja, dann lerne es. Wenn es Ihnen keinen praktischen Nutzen bringt, warum dann die Mühe machen? Braucht man das Wissen eines Mechanikers, um Auto zu fahren? Benötigt ein Mechaniker Kenntnisse eines Ingenieurs, nur um an einem Auto zu arbeiten? Dies ist eine ernsthafte Analogie. Ein Mechaniker kann ein sehr guter, produktiver Mechaniker sein, ohne ein tiefes Verständnis für die von ihm gewarteten Fahrzeuge zu haben. Gleiches gilt für Musik. Wollen Sie wirklich die Komplexität von Melodie, Harmonie und Rhythmus ausloten, um ein guter Sänger oder Spieler zu sein? Nein. Einige außergewöhnlich talentierte Musiker können keine Noten lesen, geschweige denn den Unterschied zwischen dem Dorian- und dem Lydian-Modus. Wenn du willst, okay, aber nein, musst du nicht. Wenn Sie ein Webentwickler sind, hat Assembly keinen praktischen Nutzen, den ich mir vorstellen kann. Wenn Sie sich in eingebetteten Systemen oder etwas wirklich Besonderem befinden, ist dies möglicherweise erforderlich, aber wenn dies der Fall wäre, würden Sie es wissen.

Hier ist Joels Sicht auf diesen Wert des Lernens einer nicht-übergeordneten Sprache: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html


2

Eigentlich wäre das Beste für Sie eine Klasse, die (meines Wissens) nirgendwo existiert: Es wäre eine Klasse, die einen kurzen Überblick über die Maschinensprache / Assemblersprache und die Speicheradressierungskonzepte mit einer Tour durch die Compilerkonstruktion kombiniert , Codegenerierung und Laufzeitumgebungen.

Das Problem ist, dass Sie mit einer hochentwickelten, von der Hardware weit entfernten Sprache wie C # oder Python die Tatsache nicht wirklich zu schätzen wissen, dass jede Bewegung, die Sie ausführen, zu Hunderten oder gar Tausenden von Maschinenanweisungen wird, und dass Sie keine Anweisungen geben Es ist nicht so einfach zu verstehen, wie einige Zeilen einer Hochsprache dazu führen können, dass große Mengen an Speicherplatz abgerufen und geändert werden. Es geht nicht so sehr darum, genau zu wissen, was "unter der Decke" vor sich geht, sondern darum, den Umfang des Geschehens zu verstehen und eine allgemeine Vorstellung davon zu haben, welche Arten von Dingen auftreten.


1

Meine Antwort auf diese Frage hat sich vor relativ kurzer Zeit entwickelt. Die vorhandenen Antworten decken das ab, was ich in der Vergangenheit gesagt hätte. Eigentlich wird dies immer noch von der Top-Antwort abgedeckt - dem Punkt "Schätzen Sie die Konstrukte in der übergeordneten Programmierung", aber es ist ein Sonderfall, den ich für erwähnenswert halte ...

Laut diesem Jeff Atwood-Blogbeitrag , der sich auf eine Studie bezieht, ist das Verständnis von Aufgaben ein zentrales Thema für das Verständnis von Programmierung. Lernende Programmierer verstehen entweder, dass die Notation nur die Schritte darstellt, denen der Computer folgt, und die Gründe für die Schritte, oder sie werden immer wieder durch irreführende Analogien zu mathematischen Gleichungen usw. verwirrt.

Nun, wenn Sie folgendes von 6502 Assembler verstehen ...

LDA variable
CLC
ADC #1
STA variable

Das sind wirklich nur die Schritte. Wenn Sie dann lernen, das in eine Zuweisungsanweisung zu übersetzen ...

variable = variable + 1;

Sie brauchen keine irreführende Analogie zu einer mathematischen Gleichung - Sie haben bereits ein korrektes mentales Modell, auf das Sie es abbilden können.

BEARBEITEN - natürlich, wenn die Erklärung, die Sie erhalten, LDA variableim Grunde genommen ACCUMULATOR = variablegenau die ist, die Sie aus einigen Tutorials und Referenzen erhalten, landen Sie wieder dort, wo Sie begonnen haben, und es ist überhaupt keine Hilfe.

Ich lernte 6502 Assembler als meine zweite Sprache, die erste war Commodore Basic, und ich hatte damals nicht wirklich viel davon gelernt - zum Teil, weil es so wenig zu lernen gab, aber auch, weil Assembler damals einfach so viel interessanter wirkte . Teilweise die Zeiten, teilweise, weil ich ein 14-jähriger Aussenseiter war.

Ich empfehle nicht, das zu tun, was ich getan habe, aber ich frage mich, ob das Studium einiger sehr einfacher Beispiele in einer sehr einfachen Assemblersprache eine lohnende Voraussetzung für das Erlernen von höheren Sprachen sein könnte.


0

Wenn Sie kein Compiler-Schreiber sind oder etwas hochoptimiertes (wie einen Datenverarbeitungsalgorithmus) benötigen, bietet das Erlernen der Assembly-Codierung keine Vorteile.

Das Schreiben und Verwalten von Code, der in Assembler geschrieben wurde, ist sehr schwierig. Daher sollten Sie ihn nicht verwenden, auch wenn Sie die Assemblersprache sehr gut beherrschen, es sei denn, es gibt keine anderen Möglichkeiten.

Der Artikel " Optimierung für SSE: Eine Fallstudie " zeigt, was möglich ist, wenn Sie zur Baugruppe gehen. Dem Autor ist es gelungen, den Algorithmus von 100 Zyklen / Vektor auf 17 Zyklen / Vektor zu optimieren.


1
Der Autor hat in der C ++ - Version keine Vektoranweisungen oder Eigenheiten verwendet. Sie benötigen keinen Assembler, um SSE-Code zu schreiben.
gnasher729

@ gnasher729 Ja, brauchst du nicht. Mit Assembly kann das Programm jedoch viel schneller ausgeführt werden. Ein Mensch kann schlauer sein als ein Compiler (in seltenen Fällen).
BЈовић

0

Das Schreiben in Assembler würde Ihnen keine magische Geschwindigkeitssteigerung bringen, da Sie aufgrund der Menge an Details (Registerzuordnung usw.) wahrscheinlich den trivialsten Algorithmus aller Zeiten schreiben werden.

Bei modernen (nach den 70er und 80er Jahren ausgelesenen) Prozessoren liefert die Baugruppe nicht genügend Details, um zu wissen, was vor sich geht (das heißt, bei den meisten Prozessoren). Moderne PUs (CPUs und GPUs) sind in Bezug auf Terminierungsanweisungen recht komplex. Wenn Sie die Grundlagen der Assemblierung (oder Pseudoassemblierung) kennen, können Sie Bücher / Kurse zur Computerarchitektur verstehen, die weitere Kenntnisse vermitteln (Caches, nicht ordnungsgemäße Ausführung, MMU usw.). Normalerweise müssen Sie keine komplexen ISA-Kenntnisse haben, um sie zu verstehen (MIPS 5 ist ein sehr beliebtes IIRC).

Warum Prozessor verstehen? Es könnte Ihnen viel mehr Verständnis geben, was los ist. Angenommen, Sie schreiben die Matrixmultiplikation auf naive Weise:

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Es kann für Ihren Zweck "gut genug" sein (wenn es sich um eine 4x4-Matrix handelt, kann es ohnehin zu Vektoranweisungen kompiliert werden). Es gibt jedoch einige wichtige Programme, mit denen Sie massive Arrays kompilieren - wie können Sie sie optimieren? Wenn Sie den Code in Assembler schreiben, können Sie einige Prozent der Verbesserungen erzielen (es sei denn, Sie würden wie die meisten anderen tun - auch auf naive Weise, wenn Sie die Register nicht ausnutzen, ständig in den Speicher laden / speichern und tatsächlich ein langsameres Programm als in HL-Sprache haben). .

Sie können jedoch die Zeilen umkehren und die Leistung auf magische Weise steigern (warum? Ich lasse es als "Hausaufgabe") - IIRC kann in Abhängigkeit von verschiedenen Faktoren für große Matrizen sogar das 10-fache betragen.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Das heißt, es wird daran gearbeitet, dass Compiler dies tun können ( Graphit für gcc und Polly für alles, was LLVM verwendet). Sie können es sogar in umwandeln (Entschuldigung - ich schreibe Blockieren aus dem Speicher):

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

Zusammenfassend lässt sich sagen, dass Sie mit den Grundlagen einer Baugruppe verschiedene Details aus dem Prozessordesign kennenlernen können, mit denen Sie schnellere Programme schreiben können. Es kann hilfreich sein, die Unterschiede zwischen den Architekturen RISC / CISC oder VLIW / Vektorprozessor / SIMD / ... zu kennen. Allerdings würde ich nicht mit x86 anfangen, da sie in der Regel recht kompliziert sind (möglicherweise auch ARM) - zu wissen, was ein Register usw. ist, reicht meiner Meinung nach für den Start aus.


Ich finde es interessant, dass Sie mehrere Codebeispiele bereitgestellt haben, aber keines davon in Assemblersprache.
Robert Harvey

-1

Normalerweise ist es für das Debuggen SEHR wichtig. Was tun Sie, wenn das System mitten in einer Anweisung abbricht und der Fehler keinen Sinn ergibt? Bei .NET-Sprachen ist das weitaus weniger ein Problem, solange Sie nur sicheren Code verwenden - das System schützt Sie fast immer vor den Vorgängen unter der Haube.


-2

Kurz gesagt, ich denke, die Antwort liegt darin, dass Sie mehr tun können, wenn Sie Montage lernen. Das Erlernen der Assemblierung ermöglicht den Zugriff auf die Bereiche Programmierung eingebetteter Geräte, Eindringen in die Sicherheit und Umgehung, Reverse Engineering und Systemprogrammierung, die nur schwer zu handhaben sind, wenn Sie keinen Assembler kennen.

Das Erlernen, um die Programmleistung zu verbessern, ist bei der Anwendungsprogrammierung zweifelhaft. Meistens gibt es so viele Dinge, auf die Sie sich konzentrieren müssen, bevor Sie diese Optimierungsstufe erreichen, wie beispielsweise die Optimierung Ihres E / A-Zugriffs auf Festplatte und Netzwerk, die Optimierung der GUI-Erstellung, die Auswahl der richtigen Algorithmen und die Maximierung aller Kerne Wenn Sie mit der besten Hardware arbeiten, die Sie für Geld kaufen können, wechseln Sie von interpretierten zu kompilierten Sprachen. Wenn Sie keine Software für andere Endbenutzer erstellen, ist die Hardware im Vergleich zum Stundenlohn eines Programmierers günstig, insbesondere bei Cloud-Verfügbarkeit.

Außerdem müssen Sie die Programmausführungsgeschwindigkeit mit der Lesbarkeit Ihres Codes abwägen, nachdem Sie von einem Bus angefahren wurden, beenden oder zur Codebasis zurückkehren, um sie ein Jahr nach dem Schreiben der letzten Version zu ändern.


-3

Ich würde Lernalgorithmen empfehlen: Sortieren, verknüpfte Listen, binäre Bäume, Hashing usw.

Lernen Sie auch lisp, siehe Struktur und Interpretation von Computerprogrammen groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures. In diesem Videokurs lernen Sie alles, was Sie wissen müssen, einschließlich Algorithmen (wie man alles basierend auf ein paar primitive Befehle, ein lisp-Primitiv und einige Assembler-Provokationen).

Schließlich, wenn Sie Assembler lernen müssen, lernen Sie ein einfaches wie ARM (auch wird es in ungefähr 4-mal mehr Geräten als x86 verwendet).


-8

Nun, die Antwort ist, dass nur, weil die Sprache, die Sie verwenden, am Ende interpretiert oder in Assembler kompiliert werden muss. Egal in welcher Sprache oder auf welcher Maschine.

Das Design der Sprachen ergibt sich aus der Funktionsweise der CPU. Mehr bei Low-Level-Programmen, weniger bei High-Level-Programmen.

Abschließend möchte ich sagen, dass Sie nicht nur den kleinen Assembler kennen müssen, sondern auch die CPU-Architektur, die Sie durch das Erlernen des Assemblers erlernen.

Einige Beispiele: Es gibt viele Java-Programmierer, die nicht verstehen, warum dies nicht funktioniert, und noch weniger als wissen, was passiert, wenn Sie es ausführen.

String a = "X";
String b = "X";
if(a==b)  
    return true;

Wenn Sie einen kleinen Assembler kennen würden, würden Sie immer wissen, dass der Inhalt eines Speicherorts nicht mit der Nummer in der Zeigervariablen übereinstimmt, die auf diesen Speicherort "verweist".

Schlimmer noch, selbst in veröffentlichten Büchern liest man so etwas wie in JAVA. Primitive werden nach Wert und Objekte nach Referenz übergeben, was völlig falsch ist. Alle Argumente in Java werden als Wert übergeben, und Java kann KEINE Objekte an Funktionen übergeben, nur Zeiger, die als Wert übergeben werden.

Wenn Sie jetzt wissen, was los ist, ist es so kompliziert zu erklären, dass die meisten Autoren Sie nur mit einer frommen Lüge belügen.

Die Konsequenzen sind natürlich subtil, können Sie aber später in echte Schwierigkeiten bringen. Wenn Sie wissen, dass Assembler kein Problem ist, steht Ihnen eine lange, lange Nacht des Debuggens bevor.


5
Ihr erster Absatz ist völlig falsch: Sprachen werden nicht in ASM kompiliert, sondern in Maschinencode kompiliert. Interpreter kompilieren auch nicht in ASM, sie interpretieren den Code oder den Bytecode und rufen Funktionen oder Methoden für vorkompilierten Maschinencode auf.

6
Jedes einzelne, was Sie über Java behaupten, ist ebenfalls falsch. Angefangen mit String a = "X"; String b = "X"; if( a==b) return true;dem, == truewas String interningder Compiler tatsächlich tut, wegen etwas , das er nennt. Alle anderen Java-Anweisungen sind ebenfalls falsch. Java hat keine Zeiger, es hat Referenzen, die nicht dasselbe sind. Und nichts davon hat in irgendeiner Weise etwas mit Assembler zu tun. Java übergibt Primitive nach Wert sowie Referenzen nach Wert. Java hat keine Zeiger und kann sie daher nicht weitergeben. Wieder alles irrelevant, um ASM zu kennen.

Ich dachte immer übergeordnete Sprachen, die in Objektcode (Maschinencode) oder Pseudocode kompiliert wurden, und nicht in ASM.
Frank R.

@FrankComputer korrekt, aber die Maschinencode-Bytes ordnen Assembler-Anweisungen ziemlich genau 1: 1 zu, sodass Sie leicht zwischen einem Code-Objekt und ASM (Dekompilieren oder Assemblieren) übersetzen können
dbr

2
@ FrankComputer das letzte Mal sah ich gcc kompiliert C / C ++ / Fortran / Java / Ada / etc zu internen Byte-Code und internen Byte-Code zum Assembler. Anschließend wird dieser Assembler-Code an einen Assembler gesendet, um ihn in Maschinencode zu konvertieren.
Strg-Alt-Delor
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.