Assembler (Übersetzer)



  • Moin zusammen!

    Da ich, schulisch bzw privat mit C und jetzt auch mit Assembler (Programmiersprache; Privat) zu tun habe, sind mir folgende Fragen in den Sinn gekommen:

    - Der FASM (Flat Assembler) liefert seinen Source Code in Assembler mit.
    Gibt es den Source Code in der Programmiersprache C?

    - Gibt es einen Assembler der in der Programmiersprache C geschrieben ist?

    Auch wenn es nach einer vielleicht naive Frage anhört:

    Habt ihr Ansätze / Tipps / Hinweise um den Assembler selbst in C zu schreiben?
    Also wie sich das Übersetzen des Quellcodes in Assemblercode realisieren lässt?

    Diese Fragen dienen der reinen Wissensneugier.

    Danke und Grüße

    Edit: Wenn jemand nach meinen Kenntnisse fragt: C hatte ich ein Semester sowie ein Semester Java in der Hochschule.



  • Fasm ist mir jetzt kein Begriff. Aber wenn er selber in Assembler geschrieben ist, dann ist es halt so, warum sollte jemand dasselbe Projekt in mehreren Programmiersprachen schreiben?

    NASM ist in C geschrieben.

    user1401 schrieb:

    Auch wenn es nach einer vielleicht naive Frage anhört

    Ähm, ja, hört sich etwas naiv an 😉 Bzw. falsch. Ein "Assembler" übersetzt "Assembler" in Maschinencode. Das ist eine Sache. Quellcode in Assemblercode zu übersetzten ist etwas anderes. Falls dich letzteres interessiert, ein Stichwort wäre Compilerbau. Hier gibts auch ein Tutorial zu einem Parser/Interpreter in dem Forum, weiß nicht mehr genau, was das war 😉
    Falls du aus Assemblercode Maschinencode generieren willst, ist es zum einen auch "Compiler" mit Lexer und Parser usw., und zum anderen musst du eben wissen, wie der Maschinencode für deine Zielplattform funktioniert. Die Frage kam hier im Forum auch schon mal. Es ist nicht unbedingt so wahnsinnig interessant. Es gibt von Intel z.B. sehr ausführliche Dokumentationen zu ihren Prozessoren, da müssten alle Infos drinstehen, die du brauchst. Aber es sind sehr viele Informationen und das sind vor allem wahnsinnig viele Details, die eigentlich kein Mensch braucht. Außer eben, man will selber Maschinencode generieren.
    Es wäre vielleicht noch interessanter, LLVM und seine Backends zu verwenden.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (alle ISO-Standards) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    user1401 schrieb:

    - Der FASM (Flat Assembler) liefert seinen Source Code in Assembler mit.
    Gibt es den Source Code in der Programmiersprache C?

    Nein, denn er ist direkt in Assembler geschrieben, nicht in C.

    - Gibt es einen Assembler der in der Programmiersprache C geschrieben ist?

    Da wird es sicherlich jede Menge geben. Falls deine Frage eigentliche sein sollte (frag immer danach, was du wirklich wissen willst!), ob du dir irgendwo den Code eines in C geschriebenen Assemblers angucken kannst: Ja, es gibt auch Open Source Assembler in C. Der GNU Assembler beispielsweise. Erwarte aber keinen anfängerfreundlichen Code.

    Habt ihr Ansätze / Tipps / Hinweise um den Assembler selbst in C zu schreiben?
    Also wie sich das Übersetzen des Quellcodes in Assemblercode realisieren lässt?

    Ich verstehe nicht. Willst du wissen, wie man einen Compiler für C schreibt, also ein Programm, dass C-Quellcode nach Assemblercode oder Maschinensprache übersetzt? Oder willst du wissen, wie man einen Assembler schreibt, also ein Programm, das Assemblercode in Maschinencode übersetzt?

    C-Compiler: Ist ziemlich kompliziert für einen Anfänger, geht wahrscheinlich weit über deine Kenntnisse hinaus. Wenn dich das wirklich interessiert, kannst du mit dem Stichwort "Compilerbau" anfangen zu googeln, aber wie gesagt ist das wahrscheinlich zu schwer, wenn du solche Fragen stellen musst.

    Assembler: In der einfachsten Ausführung ist das einfach eine Tabelle, da jeder Befehl im Assemblercode genau einer bestimmten Sequenz in der Maschinensprache entspricht. Ein guter Assembler hat meistens noch ein paar Komfortfeatures (wie Makros), die dann wieder leicht in Richtung Compilerbau gehen.



  • Danke für deine hilfreiche und umfangreiche Antwort!

    Mich interressiert vor allem, wie ich aus Assembler (Quellcode) Maschinencode (welcher von der Maschine ausgeführt werden kann) übersetzen kann.

    Sprich wie ich einen Compiler programmieren kann, der dies beherscht und (wenn möglich (Crosscompiler,...)) auch andere Systeme / Sprachen beherschen kann.

    Mir geht es um die Logik bzw. Planung / Struktur des (Cross-) Compiler.

    Falls jemand Source Code kennt / hat / weiß wo es ist; würde mich das auch interressieren.

    Danke

    (Naivität lebt hoch 🙄 )



  • @SeppJ:

    Mir geht es darum wie ich bei Assembler einen schreiben kann.

    Nochmal damit es keine Missverständnisse gibt:

    Wir haben z.B. folgenen Code:

    ; example of simplified Windows programming using complex macro features
    
    include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here
    
    .code
    
      start:
    	invoke	MessageBox,HWND_DESKTOP,"Hi! I'm the example program!",invoke GetCommandLine,MB_OK
    	invoke	ExitProcess,0
    
    .end start
    

    Dieser soll mit einem Assembler übersetzt werden, sodass es ausgeführt werden kann.

    Der zweite Punkt ist der, nachdem meine Kenntnisse fortgeschritten ist, nach dem Assembler noch andere Programmiersprachen wie z.B. C (am Anfang vllt "nur" C90) übersetzen kann.

    Danke


  • Mod

    Da gibt's meiner Antwort eigentlich nichts hinzu zu fügen, außer dass dein Codebeispiel gerade zu überfließt von den erwähnten Komfortfunktionen, die von vielen Assemblern unterstützt werden. Da ist ja kein einziger echter Assemblerbefehl in deinem Programm.



  • user1401 schrieb:

    Mich interressiert vor allem, wie ich aus Assembler (Quellcode) Maschinencode (welcher von der Maschine ausgeführt werden kann) übersetzen kann.

    Für einen einfachen Assembler (also keine Makros etc.) brauchst du nicht viel mehr zu machen als ...
    ...jede Zeile in "Befehl" (das erste "Wort") + die "Parameter" zu zerlegen
    ...dann die Parameter zu "analysieren" (ist es ein Direktwert, ein Register eine Speicheradresse, eine "komplexere" Adressierungsart etc.)
    ...und dann damit in einer Tabelle nachzugucken.
    Dann noch ein bisschen Adressberechnung, Bits rumschieben und Werte zusammenverodern und fertig ist dein Assembler.
    OK, etwas vereinfacht, aber da gehört wirklich nicht viel dazu -- es wird ja bloss eine "Textdarstellung" von Maschinensprache 1:1 in Maschinensprache übersetzt. Plus ein paar relativ einfache aber für den Programmierer extrem nützliche Dinge wie z.B. dass der Assembler symbolische Labels unterstützt die man statt numerischen Adressangaben verwenden kann.

    user1401 schrieb:

    Sprich wie ich einen Compiler programmieren kann, der dies beherscht und (wenn möglich (Crosscompiler,...)) auch andere Systeme / Sprachen beherschen kann.

    Wie jetzt, Compiler oder Assembler?
    Einen Cross-Assembler zu schreiben der nicht furchtbar langsamen Code erzeugt ist nicht gerade einfach.
    In jedem Fall, also auch wenn du einen relativ einfachen Cross-Assember schreiben willst (der dann entsprechend schlechten, langsamen Code erzeugt), musst du aber viel mehr von Maschinensprache verstehen als du zu verstehen scheinst.

    => Lern erstmal low-level Assembler.
    Also nix mit "invoke" sondern alles "zu Fuss" schreiben.



  • ich glaube du vermischt hier ein wenig

    Platform:
    -jede Platform hat ihre eigenen Befehlsumfang - nicht kompatible zu anderen
    -der Opcode unterscheidet sich

    Assembler:
    -für eine spezifische Platform (z.B. x86 oder ARM, MIPS)
    -kaum/keine Abstraktion, direkte Maschinenbefehle/Mnemonics

    Compiler:
    -höhrere Abstraktion durch Hochsprache wie z.B. C, C++, Pascal etc.
    -kann fuer verschiedene Platformen Opcode erzeugen

    ein Assembler ist kein Compiler - bitte nicht verwechseln

    Mich interressiert vor allem, wie ich aus Assembler (Quellcode) Maschinencode (welcher von der Maschine ausgeführt werden kann) übersetzen kann.

    schau dir doch einfach mal eine Befehlsliste der Platform deiner Wahl (z.B. x86) an und spiel damit ein wenig herum
    NASM (http://www.nasm.us/) ist der nackigste - auf C basierende Assembler, normalerweise Mnemonic => Opcode
    fuer eine Exe oder sonstige Betriebsystemabhängige Sachen muss du dann noch ein wenig Header usw. um deinen generierten Code bauen

    Beispiel mit Quelltext

    mov_ax_10.asm

    mov ax,10
    

    so direkt mit

    NASM mov_ax_10.asm
    

    assemblieren und mit Hexeditor (http://mh-nexus.de/de/hxd/) das Ergebnis anschauen
    der erzeugt nur diesen Opcode

    B8 0A 00
    

    dein Lexer, Parser liefern dir diese Infos aus dem Quelltext

    Abstract Syntax Tree (AST)

    Menmonic: mov
      Parameter1: Type: r16, Name: ax
      Parameter2: Type: m8, Wert: 10
    

    in der Tabelle (http://x86.renejeschke.de/html/file_module_x86_id_176.html) findest du dazu passend (es gibt noch tausend andere Quellen dieser Art)

    r16 = 16 bit register, imm16 = 16 bit wert usw. die Namen können in anderen Beschreibungen anders lauten

    B8+ rw MOV r16,imm16 Move imm16 to r16.

    also wird dein Opcode schon mal mit 0xB8 anfangen - wie der NASM schon sagt

    wenn du die Tabelle fuer die Opcodes durchgelesen/verstanden hast
    kannst du Opcode erzeugen - sollte du die Tabellen nicht verstehen suche nach anderen Quellen bist du diese Tabelle verstehst - da musst du einfach durch sonst wird es nichts, einfacher geht es nicht

    sollte das Erstellen des Parsers oder der Tabellenzuordnung problematisch sein ist das Thema wohl noch ein wenig zu hoch für dich

    Sprich wie ich einen Compiler programmieren kann, der dies beherscht und (wenn möglich (Crosscompiler,...)) auch andere Systeme / Sprachen beherschen kann.

    Assemblercode laesst sich nicht Crosskompilieren - der ist spezifisch fuer jede Platform, ansonten kannst du z.B. C oder eine "eigene" Sprache in Platform-Opcode uebersetzen - aber erstmal verstehen wie ein Assembler funktioniert - ein Kompiler ist definitiv viel viel schwieriger

    gutes Beispiel ist hier der SmallerC kompiler - der erzeugt NASM-Source
    https://github.com/alexfru/SmallerC



  • alles zusammen auf einer Seite für x86 bis 386 rauf

    http://sparksandflames.com/files/x86InstructionChart.html



  • Danke für die vielen Hinweise und Antworten



  • Gast3 schrieb:

    Assemblercode laesst sich nicht Crosskompilieren

    Crossassemblieren geht aber. Ist für eine neue Architektur auch sinnvoll.

    https://de.wikipedia.org/wiki/Assembler_(Informatik)#Crossassembler



  • Beispiel ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0229c/I1010893.html Damit weißt du, wie man die Bitpattern für die unterschiedliche ARM Befehle aussehen.



  • Compilerbau, Betriebssystementwicklung und auch Spielentwicklung wie in den großen Studios, sind Königsdisziplinen der Informatik. Man kann da auch im Kleinen anfangen, aber wenn man solche Fragen wie du stellen musst, dann ist man sicher noch sehr weit von dem Kenntnisstand entfernt den du brauchst um so etwas auf die Beine zu stellen.

    Du hast anscheinend erst jetzt und hier begriffen was Assembler eigentlich wirklich ist. Lerne erst einmal wie ein Computer +OS wirklich im Groben funktioniert und dann lerne Programmieren. Kannst dich ja nach dem Jahr lernen hier wieder melden, aber wahrscheinlich wirst du dir dann solche Fragen schon selbst beantworten können und dann kommen nämlich die konkreten Fragen bei der Entwicklung, die man hier auch schnell beantworten kann.



  • NAchdem ich mir den Aufbau von Compiler angeschaut und (anscheinend) verstanden
    habe, ergibt sich mir folgende Frage.

    Nachdem der Quellcode analysiert wurde, in Zwischencode etc. verarbeitet wurde, wird es in Assembler bzw. in Nullen und Einsen auf den Rechner geschrieben.

    Wie muss ich mir das vorstellen, das aus dem Syntaxbau bzw. Zwischencode auf dem Rechner geschrieben bzw. als ausführbares Programm?

    (Pseudo: printf("%i", 101); -> 10010101110) 😕

    Danke


  • Mod

    Ich glaube, du nimmst das mit den 0 und 1 viel zu wörtlich. Logisch gesehen sind das erst einmal nur Zahlen, egal in welchem System du sie aufschreibst. So ist die NOP-Anweisung auf x86 eben die Anweisung mit der Nummer 144, egal ob du 0x90, 0b10010000, CXLIV oder wer weiß was schreibst, um diesen Sachverhalt auszudrücken. Ein Maschinenprogramm besteht (auf logischer Ebene) aus einer Folge dieser Werte.
    Wie ein Computer intern arbeitet, ist dann eine ganz andere Geschichte. Da kommen dann die 0en und 1en, wobei das auch eine logische Darstellung ist, die tatsächliche physikalische Ebene sind eher so Dinge wie "Spannung positiv" und "Spannung negativ" oder (magnetischer) "Nordpol" und "Südpol" oder ähnliche Dinge, je nachdem, in welchem Teil der Hardware man gerade ist.



  • Danke SeppJ.

    Wie muss ich es dann mir vorstellen, wie ein Assembler oder wie ein Compiler beim Übersetzen bzw. Linken aus dem z.B. Zwischencode in ausführbaren Code übersetzt?

    Irgendwie habe ich ein "Knoten" bei dieser Denkweise.

    Quellcode -> (Zwischencode) -> Ausführbare Code / Datei

    Anweisung -> "PseudoCode" -> ????

    Wie steht es nun bei meiner obige "Darstellung" vom "PseudoCode" zu den Fragezeichen?



  • Um meine Frage anders zu stellen:

    Was genau macht der Compiler beim Code generieren bzw. wie genau geht dieser vor? (vllt anhand an der Programmiersprache C).

    Danke


  • Mod


Anmelden zum Antworten