Ressourcen zum Erlernen des Programmierens im Maschinencode? [geschlossen]

24

Ich bin ein Student, der gerade erst programmiert hat und es liebt, von Java über C ++ bis hinunter zu C. Ich ging rückwärts zu den Barebones und überlegte, weiter hinunter zu Assembly zu gehen.

Aber zu meiner Überraschung sagten viele Leute, es sei nicht so schnell wie C und es nütze nichts. Sie schlugen vor, entweder das Programmieren eines Kernels oder das Schreiben eines C-Compilers zu erlernen. Mein Traum ist es, zu lernen, wie man binär programmiert (Maschinencode) oder Bare Metal programmiert (Mikrocontroller physikalisch programmiert) oder BIOS- oder Bootloader oder ähnliches schreibt.

Das Einzige, was ich nach so viel Recherche gehört habe, ist, dass ein Hex-Editor der Maschinensprache am nächsten kommt, die ich in diesem Zeitalter finden konnte. Gibt es andere Dinge, die ich nicht kenne? Gibt es Ressourcen zum Programmieren von Maschinencode? Vorzugsweise auf einem 8-Bit-Mikrocontroller / Mikroprozessor.

Diese Frage ähnelt meiner, aber ich bin daran interessiert, zuerst praktisch zu lernen und dann die Theorie zu verstehen.

AceofSpades
quelle
2
Was genau ist das Problem hier? Wenn Sie fragen, ob es möglich ist, Maschinencode einzugeben, lautet die Antwort wahrscheinlich "Ja". Wenn Sie nach Tutorials fragen, dann a) stellen Sie klar, dass dies Ihre Frage ist, aber b) es ist keine konstruktive Frage.
ChrisF
6
Ist C nicht metallisch genug?
Tom Squires
6
Ich program bare metaljedes Mal, wenn ich meine Server-Box kicke. Wirkt Wunder!
Yannis
7
Haben Sie jemals darüber nachgedacht, noch weiter nach unten zu gehen? Hacke
SK-logic
3
@ SK-logic, ja, die Maschinencode-Programmierung würde nach ca. 1 Stunde unerträglich werden. Sie haben Recht, eine bessere und produktivere Idee ist es, sich der CPU-Implementierung zuzuwenden. Es gibt auch virtuelle Versionen des 6502 ( visual6502.org ) sowie Leute, die CPU's mit moderner diskreter Logik konstruieren wollen oder müssen ( bradrodriguez.com/papers/piscedu2.htm )
Angelo

Antworten:

27

Die Leute programmieren keinen Maschinencode (es sei denn, sie sind masochistisch). Sie verwenden (oder entwickeln) Werkzeuge, um Maschinencode zu generieren (Compiler oder Assembler, einschließlich entwicklungsübergreifender Werkzeuge), oder Bibliotheken, die Maschinencode generieren (LLVM, libjit, GNU Lightning, ....). Daher sind auch Ressourcen zur Generierung, Kompilierung, Optimierung und Mikroarchitektur von Maschinencode relevant.

Und sehr oft generiert ein guter, optimierender Compiler besseren Maschinencode, als Sie es könnten. Sie sind wahrscheinlich nicht in der Lage, einen Assembler-Code mit 200 Zeilen besser zu schreiben als einen guten Optimierer.

Wenn Sie den Maschinencode verstehen möchten, lernen Sie zuerst die Montage. Es kommt dem Maschinencode sehr nahe. Verwenden Sie es mit Bedacht, nur für Dinge, die Sie nicht in C codieren können (oder in einer höheren Sprache, wie Ocaml, Haskell, Common Lisp, Scala). Eine gute Möglichkeit ist häufig die Verwendung von asmAnweisungen (insbesondere der erweiterten GCC- Assembly- Funktion) in einer C-Funktion. Das Lesen des Assembler-Codes (generiert von gcc -S -O2 -fverbose-asm) kann ebenfalls hilfreich sein.

Das Linux Assembly HowTo ist eine gute Lektüre.

Die Befehlssatzarchitektur des aktuellen Prozessors (dh der Befehlssatz, den der Chip versteht) ist recht komplex. Übliche sind x86 (ein typischer PC im 32-Bit-Modus), X86-64 (ein Desktop-PC im 64-Bit-Modus), ARM (Smartphones, ...), PowerPC usw. Sie sind alle recht komplex (aus historischen und wirtschaftlichen Gründen ) Gründe dafür). Vielleicht ist es einfacher, zuerst einen hypothetischen Befehlssatz wie z. B. Knuths MMIX zu lernen .

Basile Starynkevitch
quelle
8
"Die Leute programmieren nicht in C (...). Sie benutzen moderne Sprachen, vielleicht mit C-Backend"
Abyx
Ich stimme definitiv zu. Und mein aktuelles Arbeitsprojekt (MELT, siehe gcc-melt.org ) ist eine DSL-Übersetzung nach C.
Basile Starynkevitch 20.12.11
Ich habe einige Verweise auf ISAs
Basile Starynkevitch 20.12.11
6
Was ist mit denen, die erstellen und Assembler möchten? Es gibt Gründe, Maschinencode zu lernen, obwohl sie nicht so häufig vorkommen.
Jetti
Ich würde sagen, dass es eine Befehlssatzarchitektur lernt (unter Verwendung der Assembly-Mnemonik). Sie lernen selten explizit die genaue Kodierung von Instruktionen (zB dass NOP 0x90 ist). Viele müssen es wissen, wenn Sie einen Assembler oder einen Maschinencode-Generator schreiben. (Ebenso müssen Sie selten die UTF8-Codierung von Unicode auswendig lernen.)
Basile Starynkevitch
13

Wie bereits erwähnt, lerne Assembly .

Eine Assemblersprache ist eine einfache Programmiersprache für Computer, Mikroprozessoren, Mikrocontroller und andere programmierbare Geräte. Es implementiert eine symbolische Darstellung der Maschinencodes und anderer Konstanten, die zum Programmieren einer bestimmten CPU-Architektur benötigt werden.

Die Versammlung ist also eine symbolic representation of machine code.

Möglicherweise fragen Sie jetzt: "Ok, wie lerne ich das alles?" Ich bin so froh, dass du gefragt hast:

  1. Verstehe was es ist. Es ist sehr einfach und vermittelt Ihnen ein tiefgreifendes Verständnis eines Computers. Vielleicht möchten Sie mit Wikipedia beginnen und dann diese kurze Passage lesen .
  2. Lern es! Die beste Lektüre ist wahrscheinlich Die Kunst der Assemblersprache und der Assemblersprache. Schritt für Schritt: Programmieren mit Linux
  3. Holen Sie sich die Codierung!
Dynamisch
quelle
Ich habe diesen anderen Thread gelesen und bin auf diesen gestoßen: programmers.stackexchange.com/a/82573/43388 Gibt es etwas in der Art, für das ich ein Tutorial finden könnte? Aber ich muss zuerst die Montage lernen, um den Übergang zu erleichtern.
AceofSpades
1
Danke, ich denke, ich muss das Zusammenbauen auf vielfachen Wunsch lernen. +1
AceofSpades
8

Ich empfehle dringend, dass Sie Ihr Ziel überdenken und hier ist der Grund:

Ich habe zum ersten Mal 6502 Assembler-Sprache auf dem BBC-Mikrocomputer (Modell B, 32K) gelernt. Es hatte eine fantastische BASIC-Implementierung, die einen Makro-Assembler enthielt. Wir hatten sie in der Schule, also schrieb ich alle möglichen schelmischen Programme, die Dinge wie die direkte Manipulation des Bildschirmpuffers ausführen, um einen Lemming-Spaziergang über jeden Bildschirm im Raum zu machen (sie waren vernetzt), wenn die Maschinen 10 Minuten lang nicht benutzt wurden . Bei meinen Freunden der siebten Klasse kam es zu Kichern.

Als ich zu Hause einen Commodore 64 bekam, erfuhr ich, dass er eine 6510-CPU hatte, auf der auch 6502-Assemblersprache lief, aber mit einigen interessanten Extras. Ich musste einen Assembler kaufen (kam auf eine Kassette ) und die Programme über BASIC aufrufen. Mit den großartigen Visionen, ein Bestseller-Spiel zu schreiben, gelang es mir schließlich, mehrere Demos zu erstellen, bei denen sich im Bit-Twiddle-Modus die Hardware der Videoanzeige bei Unterbrechungen registriert, um interessante Farbleisteneffekte zu erzielen, die zu funky Chip-Musik animiert wurden. Beeindruckend, aber nicht so nützlich.

Dann bekam ich einen Acorn Archimedes A310 mit einer ARM2-CPU, sodass ich dieselbe großartige BASIC-Implementierung mit eingebautem Makro-Assembler verwendete wie die BBC Micro (dasselbe Erbe). Es gelang mir, ein paar Spiele zusammenzustellen, für die ein künstlerischer Freund Grafiken zur Verfügung stellte, sowie einige sinusförmige Trippy-Demos. Beide waren schwer zu programmieren und fehlerhafter Code konnte den Computer ausschalten (versehentlich das Hardware-Reset-Register auslösen usw.) und alles verlieren, wenn ich nicht gespeichert hatte (auf Diskette!).

An der Universität wurde ich mit C ++ und damit C vertraut gemacht. Ich konnte damit Sun / Solaris und einige andere große Großrechner programmieren. Ich habe keine Ahnung, auf welcher CPU-Architektur diese Maschinen liefen - ich musste nie Assembler verwenden oder Maschinencode lesen, da die C ++ - Tools mir die Leistung gaben, die ich für die Erstellung professioneller Anwendungen benötigte.

Nach Uni habe ich an Windows und verschiedenen Unix-Versionen gearbeitet. C und C ++ funktionierten auf all diesen Rechnern und schließlich auch auf Java.

Ich habe dann an Windows und Dreamcast mit C ++ und DirectX mit umfassender Toolkette zum Debuggen gearbeitet.

Ich nahm dann eine Stelle an, bei der ich mit ARM-basierten Chipsätzen für Smart-TVs arbeitete (im Jahr 2000). Obwohl meine Erfahrung mit ARM2 hier relevant gewesen sein mag, war der Job C-basiert. Ich stellte fest, dass das Stöbern mit Hardware, das ich auf den Archimedes gemacht hatte, auch in C mit einfachen Bit-Twiddling-Operationen durchgeführt werden konnte. Ein Teil meiner Aufgabe bestand darin, die Codebasis auf Windows, Playstation 2, Linux, andere TV- und mobile Chipsätze zu migrieren. Alle diese Plattformen waren sowohl mit einem C-Compiler (häufig GCC) als auch mit einer bestimmten API-Version zum Schreiben auf den zugrunde liegenden Computer verfügbar - die eingebettete Welt ist selten ein Kernel-Betriebssystem. Ich musste nie den vollständigen Maschinencode für eine bestimmte Plattform kennen, außer einen Bootloader und ein Mini-BIOS zu schreiben, die beide bei der ersten verfügbaren Gelegenheit (nach dem Einrichten von Trap-Vektoren) in C-Code sprangen.

Der nächste Job war die Arbeit mit C ++, C # und JavaScript unter Windows. Kein Maschinencode.

Der aktuelle Job arbeitet mit C ++, JavaScript, Python, LUA, HTML und anderen Sprachen auf verschiedenen Plattformen. Ich habe keine Ahnung, welchen Maschinencode diese Plattformen ausführen, noch muss ich wissen - der Compiler übersetzt unseren Code in das, was er sein muss. Wenn es abstürzt, erkenne ich den Fehler in einem Debugger oder über eine Laufzeitdiagnose (Ausnahmen, Signale usw.).

Zum Spaß entwickle ich iOS-Anwendungen in meiner Freizeit. Es verwendet Objective-C und eine API, die über mehrere Chipsätze hinweg funktioniert. Anscheinend sind sie ARM-basiert, aber ich habe in meiner Entwicklung noch keinen Maschinencode gesehen.

Während es eine faszinierende Übung ist, Assemblersprache zu lernen, gibt es jetzt viel höhere Tools und Sprachen, mit denen Sie um eine Größenordnung (oder zwei) produktiver arbeiten können.

Die Anzahl der Stellenangebote, die einem erstaunlichen Assembler- / Maschinencode-Programmierer zur Verfügung stehen, ist im Vergleich zu JavaScript, Java, C #, C ++ oder ObjC äußerst gering.

Ich rate Ihnen, dies eher zu einem Hobby / Nebeninteresse als zu einem Hauptziel zu machen.

JBRWilkinson
quelle
6
Es ist ein Hobby. Ich interessiere mich für die Funktionsweise der Dinge und lerne, sie, wenn möglich, auf sehr grundlegender Ebene zu manipulieren. +1
AceofSpades
6

Mein Vorschlag? Lernen Sie MIPS und lernen Sie, wie Sie einen (einfachen) MIPS-Prozessor erstellen. Es ist tatsächlich einfacher als es scheint.

Der Vorteil von MIPS gegenüber einigen anderen Architekturen ist die Einfachheit. Sie werden nicht in viele kleine Details verstrickt sein, aber Sie werden trotzdem all die großen Ideen lernen, die Sie brauchen, um Code in anderen Architekturen zu schreiben.

Zufälligerweise war dies das letzte Projekt für meine (dritte) Intro-CS-Klasse. Wenn Sie möchten, können Sie die Aufgabe lesen und die Vorlesungen als Videos oder Folien durchblättern .

Unter anderem haben wir uns damit beschäftigt, wie MIPS-Code in Binärcode umgewandelt wird. Wir mussten sogar einen (sehr einfachen) Maschinencode für die Prüfungen dekodieren.

Auch wenn Sie nicht alles behandeln möchten, wurden die meisten Vorlesungen von einem der Lieblingsdozenten der Studenten gehalten und es macht Spaß, sie sich selbst anzusehen.

Tikhon Jelvis
quelle
Vielen Dank für die Links und die Erklärung, wo ich anfangen soll. +1
AceofSpades
6

Ich bin ein Student, der gerade erst programmiert hat und es liebt, von Java über C ++ bis hinunter zu C. Ich ging rückwärts zu den Barebones und überlegte, weiter hinunter zu Assembly zu gehen.

Hervorragender Weg zu nehmen. Mein Sprung (Sturz?) Von C nach Assembly und darunter war ein Universitätskurs Computer Organization and Design , basierend auf dem gleichnamigen Buch .

Empfehlen Sie dieses Buch in hohem Maße für die ersten Kapitel über die grundlegende MIPS-Assemblierung bis hin zur Pipelining- und Speicherarchitektur. Noch besser wäre es, einen Kurs über das gleiche Thema zu belegen oder einige Vorlesungen online zu finden.

Schauen Sie sich auch den MARS MIPS Simulator an, um Ihre Hände schmutzig zu machen.

Matt Stephenson
quelle
4

Wenn Sie verstehen möchten, wie die Maschine vollständig funktioniert, warum gehen Sie nicht auf die niedrigste Ebene und arbeiten sich bis zu Ihrer Position vor (z. B. C, C ++)?

Damit meine ich: Warum baust du nicht deinen eigenen 4-Bit-Addierer mit Transistoren auf einer Schaltung (google es einfach, wenn du nach Anweisungen / Anleitungen suchst)?

Bauen Sie danach einen kleinen Computer mit etwas RAM und beginnen Sie dann mit dem Erlernen von Assembly und schreiben Sie ein oder zwei Programme damit.

Daniel Scocco
quelle
Wenn das Originalposter einen Computer von Grund auf neu erstellt, muss er seine eigene Baugruppe definieren (und nicht nur lernen).
Basile Starynkevitch
@daniels Ich verstehe die Argumentation, indem ich lerne, aus Bits etwas hinzuzufügen, was wirklich niedrig ist. +1
AceofSpades
Eine Alternative zum Erstellen eines Computers von Grund auf könnte das Erlernen eines alten Prozessors (und seiner Assemblersprache) wie des Z80 oder 6502 sein, der immer noch einfach genug ist, um verstanden zu werden. Ich denke, es gibt sogar Emulatoren, mit denen Sie spielen können.
Giorgio
@AceofSpades Eine großartige Möglichkeit zum einfachen Erstellen von CPUs und CPU-Komponenten (z. B. ein Addierer) ist Redstone in Minecraft. Ich würde dies empfehlen. Ich habe angefangen, an einigen einfachen Maschinen in Minecraft zu arbeiten, und dies hat mein Verständnis für die Theorie und Logik hinter Computern erheblich verbessert.
Aaron
1

Ich habe einen dafür erstellten Befehlssatz, einen Simulator und einige Tutorials zu den Grundlagen, eine Anweisung oder ein Konzept pro Lektion. Geben Sie einfach das Programm ein, führen Sie es aus und lernen Sie, was es tut. Fahren Sie mit der nächsten Lektion fort.

http://www.github.com/dwelch67/lsasim

Ich habe auch Simulatoren für ein paar Mainstream-Befehlssätze. Alle oder einige davon eignen sich gut zum Erlernen von ASM (wenn Sie wirklich das Gefühl haben, x86 lernen zu müssen, lernen Sie es zuletzt und verwenden Sie einen Simulator wie den, den ich gegabelt habe, 8088/86, bevor Sie fortfahren). Gegen einen Simulator zu lernen hat Vor- und Nachteile. Ein großer Vorteil, besonders zu Beginn, ist, dass Sie nichts zum Absturz bringen und eine hervorragende Sicht haben. Wenn Sie mit dem Kopf voran in eine eingebettete Plattform, einen Mikrocontroller usw. springen und einen neuen Befehlssatz erlernen, müssen Sie die Hürden überwinden, die entstehen, wenn Sie nicht sehen können, was vor sich geht.

Oldtimer
quelle
1

Code von Charles Petzold ist eine sehr gute Einführung in das Thema und beschreibt den Prozess des Aufbaus eines Computers, einschließlich des Aufbaus von Addierern, Zählern und RAM-Arrays, und führt in Maschinencode und Assemblersprache sowie deren Beziehung zu höheren Sprachen ein. Es ist auch eine großartige Lektüre über die Geschichte des Rechnens.

Und ich habe gerade diese Frage auf electronics.stackexchange gelesen, die auch von Nutzen sein könnte

br3w5
quelle