Eigenen Assembler programmieren



  • Hallo,

    ich habe mich gerade gefragt, ob es möglich ist einen eigenen Assembler (z.B. in C++) zu programmieren ? Der Assembler sollte den von mir geschriebenen Assembler-Quellcode in Maschinencode umwandeln und dabei eine EXE-Datei (für MS-DOS) erzeugen. Das müsste doch eigentlich möglich sein, oder ?

    Soweit ich weiß erstellt der Assembler zuerst eine Objektdatei in der die Mnemonics in Maschinenbefehle umgesetzt werden. Dann werden noch die Adressen der einzelnen Variablen und Sprungziele berechnet. Aus dieser Objektdatei wird dann das fertige Programm (EXE-Datei) erstellt.

    Habe ich das richtig verstanden, oder läuft der Vorgang anders ab ?

    Auf jeden Fall müsste es dann doch möglich sein einen eigenen Assembler zu programmieren, oder ? (Auch wenn es vermutlich nicht ganz einfach sein wird)

    Ich danke euch für eure Antworten,
    MfG arenas



  • Natürlich ist es möglich einen Assembler zu programmieren, wo sollen die denn sonst herkommen 😕

    Der Ablauf dabei ist eigentlich egal, Hauptsache es kommt dabei die Exe raus. Aber ja, normal werden erst alle Sources in "Objektdateien" umgewandelt, und diese dann gelinkt.

    Aber wie gesagt, du kannst theoretisch auch hergehen, alle Sources zu einer einzigen Datei zusammenkopieren und diese dann sofort in die Exe umwandlen. Halt halt dann entsprechenden Einschränkungen...



  • Kennt ihr eine Website auf der genau erklärt wird wie man einen Assembler (für MS-DOS Programme) programmiert ?



  • arenas schrieb:

    auf der genau erklärt wird

    Vergiss es. Es wird so gut wie nie irgendwas so konkretes "genau" erklärt. Du musst dich erst selber in vieles reindenken, dann kannst du dir zusammenreimen, wie du was machst.



  • Laut meinem Lehrbuch berechnet der Linker die Anfangsadressen der verwendeten Segmente und schreibt diese dann anschließend in die Kopfzeile der ausführbaren Datei. Doch wohin schreibt der Linker diese Informationen genau hin ?

    An den ersten zwei Bytes einer ausführbaren MS-DOS Datei steht ja immer die magische Zahl ("MZ"), aber an welcher Position muss zum Beispiel die Anfangsadresse des Datensegmentes stehen ?

    Das muss doch irgendwo dokumentiert sein, oder ?



  • Schaust du in der EXE Documentation von MSDN und z.B: hier nach...



  • Dann wollen die einzelnen Befehle ja auch noch gecodet werden, weil sie sich aus unterschiedlichen Bestandteilen zusammen setzen können.

    X86-64 Instruction Encoding
    http://wiki.osdev.org/X86-64_Instruction_Encoding

    Referenzen:
    AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions
    http://support.amd.com/en-us/search/tech-docs
    http://support.amd.com/TechDocs/24594.pdf

    Intel 64 and IA-32 Architectures Software Developer's Manuals
    http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

    Dirk



  • Am Anfang könnte man sich aber auch nur mit 80386 beschäftigen:

    Instruction Prefix                0 oder 1 Byte
       Address-Size Prefix               0 oder 1 Byte
       Operand-Size Prefix               0 oder 1 Byte
       Segment Prefix                    0 oder 1 Byte
       Opcode                            1 oder 2 Byte
    
       Mod R/M                           0 oder 1 Byte
       SIB, Scale Index Base (386+)      0 oder 1 Byte
       Displacement                      0, 1, 2 oder 4 Byte (4 nur 386+)
       Immediate                         0, 1, 2 oder 4 Byte (4 nur 386+)
    
    Format of Postbyte(Mod R/M aus Intel-Doku)
    ------------------------------------------
    MM RRR MMM
    
    MM  - Memeory addressing mode
    RRR - Register operand address
    MMM - Memoy operand address
    
    RRR Register Names
    Filds  8bit  16bit  32bit
    000    AL     AX     EAX
    001    CL     CX     ECX
    010    DL     DX     EDX
    011    Bl     BX     EBX
    100    AH     SP     ESP
    101    CH     BP     EBP
    110    DH     SI     ESI
    111    BH     DI     EDI
    
    ---
    
    16bit memory (No 32 bit memory address prefix)
    MMM   Default MM Field
    Field Sreg     00        01          10             11=MMM is reg
    000   DS       [BX+SI]   [BX+SI+o8]  [BX+SI+o16]
    001   DS       [BX+DI]   [BX+DI+o8]  [BX+DI+o16]
    010   SS       [BP+SI]   [BP+SI+o8]  [BP+SI+o16]
    011   SS       [BP+DI]   [BP+DI+o8]  [BP+DI+o16]
    100   DS       [SI]      [SI+o8]     [SI+o16]
    101   DS       [DI]      [DI+o8]     [SI+o16]
    110   SS       [o16]     [BP+o8]     [BP+o16]
    111   DS       [BX]      [BX+o8]     [BX+o16]
    Note: MMM=110,MM=0 Default Sreg is DS !!!!
    
    32bit memory (Has 67h 32 bit memory address prefix)
    MMM   Default MM Field
    Field Sreg     00        01          10             11=MMM is reg
    000   DS       [EAX]     [EAX+o8]    [EAX+o32]
    001   DS       [ECX]     [ECX+o8]    [ECX+o32]
    010   DS       [EDX]     [EDX+o8]    [EDX+o32]
    011   DS       [EBX]     [EBX+o8]    [EBX+o32]
    100   SIB      [SIB]     [SIB+o8]    [SIB+o32]
    101   SS       [o32]     [EBP+o8]    [EBP+o32]
    110   DS       [ESI]     [ESI+o8]    [ESI+o32]
    111   DS       [EDI]     [EDI+o8]    [EDI+o32]
    Note: MMM=110,MM=0 Default Sreg is DS !!!!
    
    ---
    
    SIB is (Scale/Base/Index)
    SS BBB III
    Note: SIB address calculated as:
    <sib address>=<Base>+<Index>*(2^(Scale))
    
    Fild   Default Base
    BBB    Sreg    Register   Note
    000    DS      EAX
    001    DS      ECX
    010    DS      EDX
    011    DS      EBX
    100    SS      ESP
    101    DS      o32        if MM=00 (Postbyte)
    SS      EBP        if MM<>00 (Postbyte)
    110    SS      ESI
    111    DS      EDI
    
    Fild  Index
    III   register   Note
    000   EAX
    001   ECX
    010   EDX
    011   EBX
    100              never Index SS can be 00
    101   EBP
    110   ESI
    111   EDI
    
    Fild Scale coefficient
    SS   =2^(SS)
    00   1
    01   2
    10   4
    11   8
    


  • Ich denke auch dass man sich das einfach selber durch ausprobieren beibringen muss. So hab ich es auf jeden Fall gelernt



  • freecrac schrieb:

    Am Anfang könnte man sich aber auch nur mit 80386 beschäftigen:

    Man kann sich auch einen Nagel ins Knie schlagen und die Schlüssel dranhängen. 😉

    Wenns um Spaß und Lernen geht, würde ich mir jedoch eher einen Prozessor raussuchen, der ein schönes reguläres Befehlsformat hat.



  • top pot schrieb:

    freecrac schrieb:

    Am Anfang könnte man sich aber auch nur mit 80386 beschäftigen:

    Man kann sich auch einen Nagel ins Knie schlagen und die Schlüssel dranhängen. 😉

    Nun musst du uns aber auch noch veraten, wie du damit einen eigenen Assembler programmierst, mit dem man eine EXE-Datei für MS-DOS erstellen kann.
    Mit einer Frikadelle zum Drehen könnte man bestimmt auch Radio Assemblystan reinbekommen, aber mit deinem Schlüssel am Nagel, wie soll das denn gehen, es fehlt leider das passende Schlüsselloch?!

    Wenns um Spaß und Lernen geht, würde ich mir jedoch eher einen Prozessor raussuchen, der ein schönes reguläres Befehlsformat hat.

    Welcher Prozessor für MS-DOS hat denn ein schöneres, oder reguläreres Befehlsformat als ein 80386?

    Dirk


Anmelden zum Antworten