2016-04-29 10 views
1

Ich versuche, einen kleinen 8086+ Assembler zu schreiben, wahrscheinlich nur Real-Modus, und kann mich für eine große Teilmenge der möglichen Anweisungen entscheiden.Closer-to-the-Metal alternative Assembler-Syntax für x86?

Die x86-Anweisungen sind komplex und erfordern eine komplexe Tabellenlösung, die in Ordnung ist, aber ich möchte etwas kleiner/einfacher.

Eine meiner Ideen ist es, mit den Opcodes zu beginnen und einen alternativen Satz von Mnemonics/Adressierungsmodi/Registern zu erstellen, der sich enger auf die tatsächlichen Maschinenanweisungen bezieht.

Wurde dies getan und wo kann ich darüber lesen? Mein Bauchgefühl sagt, dass das schon getan sein muss, aber ich kann nichts online finden.

Dinge, die ich schon sah in:

  • AT & T Syntax: löst nicht das Problem, müssen Sie noch eine komplexe Lookup-Tabelle; am Ende ist es im Grunde das gleiche wie Intel-Syntax.

  • CRASM512.ASM: ein cooler 512 Bytes Trick Assembler. Sehr beeindruckend, aber nicht verwendbar (und nicht gemeint). Die Syntax basiert immer noch auf Intel.

  • Verwenden nur einer Teilmenge von "homogen codierten" Anweisungen. Das ist , was ich gerade versuche, und mit einer kleineren und weniger komplexen Tabelle getrieben Ansatz als ein vollwertiger x86-Assembler.

    Das Problem ist, dass ich immer noch auf ungültige Anweisungen überprüfen muss, und x86 ist komplex genug, dass ich nur die Tabelle getriebene Annäherung ein wenig einfacher, nicht einfach machen kann. Es ist also 90% der Komplexität für 10% des Ergebnisses, weil es vor allem die Tabellen sind, die sich im Vergleich zum echten Deal ändert.

+2

8086 Assembler ist einfach im Vergleich zu den meisten Plattformen (und anderen Sprachen), was ist Ihr Ziel dabei? Wenn Sie nur wissen wollen, wie das geht, dann schlage ich vor, eine vereinfachte Teilmenge eines 8086-Assemblers zu erstellen und seine Fähigkeiten so lange zu erweitern, bis Sie einen vollständigen 8086-Assembler haben. Ich konnte einen PIC16F-Assembler in ungefähr 1000 Zeilen von Python (um 2008) schreiben, und einen 80286-Assembler in ungefähr 2500 Zeilen von C (um 2001), so dass diese nicht groß sind. Versuchen Sie, dies in 8086 Assembler zu implementieren? Trotzdem sollte es ziemlich einfach sein, wenn Sie den Code gut organisieren. –

+0

Ja, ein normaler x86-Assembler ist einfach (mit einem tabellengesteuerten Ansatz), aber das ist bereits geschehen. Ich möchte meins VIEL kleiner machen, während es noch verwendbar/nützlich ist, also suche ich nach irgendwelchen Ecken zum Schneiden. Wie auch immer, wenn man sich die x86-Anweisungen im Vergleich zu den Mnemonics anschaut, bittet die Frage nach einem alternativen Mnemonics-Set (etc) einfach darum, gefragt zu werden. –

+1

Ok, also möchtest du dem Metall näher kommen als ... Assembler? Du erkennst, dass es Bare Metal ist, oder? Es ist eine Darstellung der numerischen Befehlscodierung, die so nah wie möglich ist. Vielleicht hilft Ihnen ein Beispiel dessen, was Sie darstellen möchten, dies zu klären? –

Antwort

4

ist ein stark-over-vereinfachte Architektur (for teaching purposes), sondern setzt eine Ihrer Ideen: Statt eine Unmenge verschiedene Formen von mov zu haben, die grundlegend andere Dinge zu tun, es anders Mnemotechnik für die drei verschiedenen hat mov -ähnlichen Opcodes unterstützt:

  • irmovl V, %rB: sofort -> reg
  • rmmovl %rA, D(%rB): reg -> Speicher (Speicher)
  • mrmovl D(%rB), %rA: Speicher -> reg (Last)

Dies ist ein AT & T-Syntax Geschmack von Y86, wo das Ziel 2. geht. AT & Die T-Syntax verwendet % und $ Dekorationen, um Verwechslungen zwischen Namen und Symbolen zu vermeiden. IDK, wenn das einen Parser kleiner oder größer macht.

Wenn Sie diese Idee auf x86 anwenden, können Sie verschiedene Mnemonics für verschiedene Formen derselben Anweisung verwenden.

Wenn Sie mehr über einfach zu parsen als menschliche Lesbarkeit und Ähnlichkeit mit bestehenden ASM-Syntax, dann könnten Sie immer Operanden in der Reihenfolge der Codierung im mod/RM-Byte aufgeführt haben. z.B.

addbir al, 5 ; b = byte, i = immediate, r = register. opcode 80 /0 with al encoded in the mod/rm byte, imm8 
addbia al, 5 ; a = ax/al: opcode 04 imm8 

; w=word, m=memory 
addwrm cx, 0, bx, ; add cx, [0 + bx + (no index)] encoding: 03 mod/rm 
addwmr cx, 0, , si ; add [0 + (no base) + si], cx encoding: 01 mod/rm 

Note die letzten beiden Zeilen: der erste Operand ist immer die "r" in dem mod/rm byte, eher als das Ziel. Es ist eine Art Textdarstellung der Befehlskodierung, keine menschenverwendbare Syntax. Ich denke, das ist die Art von Idee, die Sie anstrebten?

Je nachdem, wie intelligent der Assembler sein soll, können Sie zwischen den Imm8- und Imm16-Formularen für Sofortbefehle auswählen. Für disp8, disp16 oder keine Verschiebungsspeichercodierungen könnte es einfacher sein, eine 0 anstelle eines leeren Eintrags zu verlangen.


Normalerweise will jeder einen Smart-Assembler, der die beste Codierung für Sie nimmt (zum Beispiel die EAX-spezifischen Opcode verwenden, die keinen mod/rm Byte nicht verwendet). esp. für x86-64, REX-Präfixe zu vermeiden, wenn nicht notwendig, oder mov rax, 0x1234 in mov eax, 0x1234 zu optimieren, ist nett.

Es wäre sicherlich Wert in der Verwendung unterschiedlicher Mnemotechniken für Lasten vs. mov-sofort, denn das ist ein common source of confusion for asm beginners. (insb. da MASM und NASM Syntax sich unterscheiden, was mov reg, symbol bedeutet).

+0

Das ist genau das, was ich mir gedacht habe. Ich denke, ich werde einige Zeit damit verbringen müssen, Muster in der Befehlskodierung zu finden und etwas Cleveres herauszufinden. y86 scheint wie eine große Ressource, noch nie zuvor davon gehört, danke! –

+0

@ JonathanJ.Bloggs: y86 ist für alles außer zu Spielzeug Beispiele von Baby-Steps Intro-zu-Asm-Klassen zu stark vereinfacht. Es hat nicht einmal Multiplikations-, Divisions-oder sogar Shift-Anweisungen (außer "fügen Sie die gleichen, gleichen" nach links Verschiebung), so viele Dinge sind unmöglich effizient zu implementieren. Einige Versionen davon haben 'cmov', [also können Sie' setcc' emulieren (http://stackoverflow.com/questions/36585746/the-most-efficient-way-of-counting-positive-negative-and) -zero-number-using-loop/36587614 # 36587614). Es hat nur add, sub, und xor und keine vorzeichenlosen Verzweigungsbedingungen (nur signiert). –

+0

Seit zwei Wochen, weiß ich nicht, ob ich deine Antwort akzeptieren sollte; Ihre Antwort, obwohl hilfreich, gibt meistens Dinge an, an die ich bereits gedacht hatte (und die in der Frage impliziert sind). Deshalb habe ich Ihre Antwort noch nicht als "akzeptiert" markiert. Danke trotzdem! Ich habe nur kurz auf die y86-Dokumente geschaut, jetzt sehe ich, dass du recht hast, es ist viel zu einfach. –