it-swarm.dev

Ressourcen zum Erlernen des Programmierens in Maschinencode?

Ich bin ein Student, der sich mit Programmieren beschäftigt und es liebt, von Java bis C++ und bis C). Ich ging rückwärts zu den Barebones und dachte daran, weiter bis zur 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 lernen. Mein Traum ist es, zu lernen, wie man in Binär (Maschinencode) programmiert oder vielleicht Bare Metal programmiert (Mikrocontroller physisch programmiert) oder BIOS oder Bootloader oder ähnliches schreibt.

Das einzig mögliche, was ich nach so vielen Recherchen 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, von denen ich nichts weiß? Gibt es Ressourcen zum Erlernen des Programmierens im Maschinencode? Vorzugsweise auf einem 8-Bit-Mikrocontroller/Mikroprozessor.

Diese Frage ähnelt meiner, aber ich interessiere mich zuerst für praktisches Lernen und dann für das Verstehen der Theorie.

25
AceofSpades

Leute programmieren nicht im Maschinencode (es sei denn, sie sind masochistisch). Sie verwenden (oder entwickeln) Tools zum Generieren von Maschinencode (Compiler oder Assembler, einschließlich entwicklungsübergreifender Tools) oder Bibliotheken, die Maschinencode generieren (LLVM, libjit, GNU lightning, .... Daher sind auch Ressourcen zur Erzeugung, Kompilierung, Optimierung von Optimierungen und Mikroarchitekturen von Maschinencode relevant.

Und sehr oft generiert ein guter Optimierungs-Compiler besseren Maschinencode als Sie. Sie werden wahrscheinlich keinen Assembler-Code mit 200 Zeilen besser schreiben können als einen guten Optimierer.

Wenn Sie den Maschinencode verstehen möchten, lernen Sie zuerst Assembly. Es ist sehr nah am Maschinencode. 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). Ein guter Weg ist oft, asm Anweisungen (insbesondere GCC Extended Assembly -Funktion) innerhalb einer C-Funktion zu verwenden. Lesen des Assembly-Codes (generiert von gcc -S -O2 -fverbose-asm) kann auch hilfreich sein.

Das Linux Assembly HowTo ist eine gute Sache zu lesen.

Die Befehlssatzarchitektur des aktuellen Prozessors (d. H. Der vom Chip verstandene Befehlssatz) ist ziemlich 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). Vielleicht lernt man zuerst einen hypothetischen Befehlssatz wie z. Knuths MMIX ist einfacher.

27

Wie bereits erwähnt Assembly lernen .

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 erforderlich sind.

Die Versammlung ist also ein symbolic representation of machine code.

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

  1. Verstehe, was es ist. Es ist sehr low-level und gibt dir ein sehr tiefgreifendes Verständnis von a Computer. Vielleicht möchten Sie mit Wikipedia beginnen und dann diese kurze Passage lesen.
  2. Lerne es! Die besten Lesungen sind wahrscheinlich Die Kunst der Assemblersprache und Assemblersprache Schritt für Schritt: Programmieren unter Linux
  3. Codierung erhalten!
13
Dynamic

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

Ich habe zuerst 6502 Assembler-Sprache auf dem BBC-Mikrocomputer (Modell B, 32K) gelernt. Es hatte eine großartige 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 taten, um einen Lemming über jeden Bildschirm im Raum laufen zu lassen (sie waren vernetzt), wenn die Maschinen 10 Minuten lang nicht benutzt worden waren . Es führte zu Kichern unter meinen Freunden der siebten Klasse.

Als ich zu Hause einen Commodore 64 bekam, erfuhr ich, dass er eine 6510-CPU hatte, auf der auch die Assemblersprache 6502 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 die Hardware der Videoanzeige bei Unterbrechungen ein wenig verändert, um interessante Farbbalkeneffekte zu erzielen, die zu funky Chip-Musik animiert wurden. Beeindruckend, aber nicht so nützlich.

Ich habe dann einen Acorn Archimedes A310 bekommen, der eine ARM2-CPU hatte, also habe ich dieselbe großartige BASIC-Implementierung mit integriertem Makro-Assembler verwendet wie das BBC Micro (dasselbe Erbe). Ich habe es geschafft, ein paar Spiele zusammenzustellen, für die ein künstlerischer Freund Grafiken zur Verfügung gestellt hat, sowie einige sinusförmige Trippy-Demos. Beide waren schwer zu programmieren und schlechter Code konnte die Maschine 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 in C++ und damit in C eingeführt. Ich konnte damit Sun/Solaris und einige andere große Mainframe-Computer programmieren. Ich habe keine Ahnung, auf welchen CPU-Architekturen diese Maschinen ausgeführt wurden - ich musste nie Assembler verwenden oder Maschinencode lesen, da mir die C++ - Tools die Leistung gaben, die ich für die Erstellung professioneller Anwendungen benötigte.

Nach Uni habe ich an Windows und verschiedenen Unix-Varianten gearbeitet. C und C++ arbeiteten auf all diesen Maschinen und schließlich Java auch.

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

Ich habe dann einen Job bei ARM-basierten Chipsätzen für Smart-TVs angenommen (im Jahr 2000). Obwohl meine Erfahrung mit ARM2 hier relevant gewesen sein mag, war der Job C-basiert. Ich fand heraus, dass all das Herumstö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 Rolle 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 API-Ebene 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 in C-Code sprangen (nachdem sie Trap-Vektoren eingerichtet hatten, um Endianität und Sicherheit zu gewährleisten) Anweisungsmodus und Aufbau eines Stapels).

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, und ich muss auch nicht wissen, dass der Compiler unseren Code in das übersetzt, was er sein muss. Wenn es abstürzt, erhalte ich den Fehler in einem Debugger oder durch Laufzeitdiagnose (Ausnahmen, Signale usw.).

Zum Spaß entwickle ich iOS-Anwendungen in der kurzen Freizeit, die ich zu Hause habe. 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 nie einen Maschinencode gesehen.

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

Die Anzahl der Stellenangebote, die einem erstaunlichen Programmierer für Assemblersprache/Maschinencode zur Verfügung stehen, ist im Vergleich zu JavaScript, Java, C #, C++ oder ObjC winzig.

Ich würde Ihnen raten, dies eher zu einem Hobby/Nebeninteresse als zu einem Hauptziel zu machen.

8
JBRWilkinson

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 eine Menge kleiner Details verwickelt sein, aber Sie werden trotzdem alle großen Ideen lernen, die Sie zum Schreiben von Code in anderen Architekturen benötigen.

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 durchsuchen.

Unter anderem haben wir behandelt, 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 abdecken möchten, wurden die meisten Vorlesungen von einem der Lieblingsdozenten der Studenten gehalten und es macht Spaß, sie selbst zu sehen.

6
Tikhon Jelvis

Ich bin ein Student, der sich mit Programmieren beschäftigt und es liebt, von Java bis C++ und bis C). Ich ging rückwärts zu den Barebones und dachte daran, weiter bis zur Assembly zu gehen.

Hervorragender Weg. Mein Sprung (Sturz?) Von C nach Assembly und niedriger war ein Universitätskurs Computerorganisation und -design , basierend auf dem Buch mit dem gleichen Namen.

Empfehlen Sie dieses Buch wärmstens für die ersten Kapitel über die grundlegende MIPS-Assembly, bis hin zu Pipelining und Speicherarchitektur. Noch besser wäre es, einen Kurs zum gleichen Thema zu belegen oder einige Vorträge online zu finden.

Siehe auch MARS MIPS Simulator , um sich beim Schreiben die Hände schmutzig zu machen.

6
Matt Stephenson

Wenn Sie verstehen möchten, wie die Maschine vollständig funktioniert, warum gehen Sie nicht auf die niedrigstmögliche Ebene und bauen sich bis zu Ihrem Standort auf (z. B. C, C++)?

Damit meine ich: Warum bauen Sie nicht Ihren eigenen 4-Bit-Addierer mit Transistoren auf einer Schaltung (nur Google it, wenn Sie nach Anweisungen/Tutorial suchen)?

Bauen Sie danach einen kleinen Computer mit etwas RAM, lernen Sie dann Assembly und schreiben Sie ein oder zwei Programme damit.

4
Daniel Scocco

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

Und ich habe gerade gelesen diese Frage zu electronic.stackexchange was auch von Nutzen sein könnte

1
br3w5

Ich habe einen dafür erstellten Befehlssatz, einen Simulator und einige Tutorials zu den Grundlagen, eine Anleitung 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 einige Mainstream-Befehlssätze. Einige oder alle davon sind gut geeignet, um asm zu lernen (wenn Sie wirklich das Gefühl haben, x86 lernen zu müssen, lernen Sie es zuletzt und verwenden Sie zuerst einen Simulator wie den, den ich gegabelt habe, 8088/86, und fahren Sie dann fort). Das Lernen gegen einen Simulator hat Vor- und Nachteile. Ein wichtiger Vorteil, insbesondere wenn Sie anfangen, ist, dass Sie nichts zum Absturz bringen und eine gute Sichtbarkeit haben. Wenn Sie mit dem Kopf voran in eine eingebettete Plattform, einen Mikrocontroller usw. springen, um einen neuen Befehlssatz zu erlernen, müssen Sie die Hürden überwinden, nicht sehen zu können, was vor sich geht, was zu einer langen Liste von Möglichkeiten führt, um zu scheitern ...

1
old_timer