Autor Thema: Lowest Level - Eigener Compiler  (Gelesen 23191 mal)

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« am: 13. July 2005, 21:30 »
Hallo, hat sich ja ganz schön was getan, seit ich das letzte Mal hier war, weiter so.

Zu Thema:
Ich denke ihr werded wohl für die Low Level Programmierung Compiler/Assembler wie den GCC oder TASM benutzen, oder?

Ich habe mir vor einiger Zeit einen eigenen Assembler geschrieben und dann auf dessen Basis einen C Compiler (den ich später für ein eigenes OS benutzen will).

Der Compiler hat zwar einige kleine Einschränkungen, kann aber ansonsten alles, was im ANSI Standard steht und noch mehr wie zB:


// Funktionszeiger:
void func(char* str,int anz){...}
void main(void){
  void(char*,int) fptr;
  fptr=func;
  fptr("hallo",5);
}

// Mischung von ASM und C:
int a,b;
asm{
  mov eax,0x10
  mov [a],eax
  xor ebx,ebx
}
b=ebx;


Wer Interesse hat kann ihn sich ja mal ansehen und mir seine Meinung schreiben:
http://wwwstud.fh-zwickau.de/~micmo/compiler.html

MM

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #1 am: 13. July 2005, 22:43 »
Das ist aber schon mal eine grosse Leistung. Hinter Compilern steckt jede Menge Theorie, die verstanden sein will! ;)
Und die Notation des Inline Assemblers gefaellt mir so auch viel besser als beim GCC! :)
Aber lowest level waer wohl eher chip design!  :twisted:
*post*

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #2 am: 13. July 2005, 22:54 »
Jaja, Einsen und Nullen mit nem Stock in den Sand malen...  :wink:

Aber ansonsten geht es von der PC Programmierung nur noch 'lower' wenn man das Programm mit nem Debugger schreibt, denke ich.

Was den Inlineassembler angeht, da hab ich mich ganz an das gute alte Turbo C gehalten, denn dies gewurschtel mit dem GCC mag ich auch nicht.

MM

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #3 am: 14. July 2005, 06:59 »
Nette Sache.
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

Legend

  • Beiträge: 635
    • Profil anzeigen
    • http://os.joachimnock.de
Gespeichert
« Antwort #4 am: 14. July 2005, 08:48 »
Wobei mir ein C++ Compiler noch lieber waere!  8)
*post*

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 14. July 2005, 13:19 »
Aaaaaahhh!! Der Compiler kann ja schon viel mehr als meiner  :?
Gefällt mir aber trotzdem  :wink:
Da ich bei meinem Compiler gerade mit Mathe beschäftigt bin, würds mich mal interessieren wie du zum Beispiel diese Zeile in Assembler compilierst:
Var=200*(Var2+x/2)-4
Ich versuche im Moment die Zeile in einzelne Teile zu zerlegen und erst mal die innersten Klammern zu bearbeiten. Also so:
"Var2+x/2" in Asm machen, dann "push Ergebnis"
Den Rest dann dazu machen: 200*pop-4

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #6 am: 14. July 2005, 14:06 »
Naja, das Problem löst sich eigentlich von ganz alleine, wenn man das Prinzip mit dem Tokenbaum verstanden hat.
Dies ist übrigends die Ausgabe die mein Compiler mit der Option -stt anzeigt:


mtl: 'var=200*(var2+x/2)-4;'
var
200*(var2+x/2)-4
200*(var2+x/2)
(var2+x/2)
x/2

│ ├-1 <int> 4
├-1 <int> -
│ │ │ │ ├-1 <int> 2
│ │ │ ├-1 <int> /
│ │ │ │ ├-1 <int> x
│ │ ├-1 <int> +
│ │ │ ├-1 <int> var2
│ ├-1 <int> *
│ │ ├-1 <int> 200
├-1 <int> =
├-1 <int> var


Wie zu erkennen ist sind die Operatoren nach ihrer Wertigkeit angeordent, wobei die Klammern diese überschreiben. In der Abarbeitung des Baumes werden nun also nur noch die einzelnen Operationen durchgeführt, wie man aus dem Listing unten erkennen kann.
Es wird also erst der linke (?) Ast durchgegangen, bis eine 2 im eax zurück kommt, dann wird sie gepuscht, der rechte Ast am Knoten bearbeitet, was den Inhalt von x liefert, dann wird gepopt und dann dividiert, das Ergebnis wird wieder in eax zurück geliefert, klar soweit?


0001: main()
main_begin:
6689E5           mov ebp,esp
{
 < create  int x (4) >
 < create  int var2 (4) >
 < create  int var (4) >
6681EC0C000000   sub esp,0c
 < local stack: 4 >
0003: var=200*(var2+x/2)-4;
66B804000000     mov eax,04
6650             push eax
66B8C8000000     mov eax,0c8
6650             push eax
66B802000000     mov eax,02
6650             push eax
66678B45F4       mov eax,[ebp-0c]
665B             pop ebx
6631D2           xor edx,edx
66F7F3           div ebx
6650             push eax
66678B45F8       mov eax,[ebp-08]
665B             pop ebx
6603C3           add eax,ebx
665B             pop ebx
66F7E3           mul ebx
665B             pop ebx
662BC3           sub eax,ebx
66678945FC       mov [ebp-04],eax
6681C40C000000   add esp,0c
66C3             ret
}
0004: end of main()


Ich hoffe das Prinzip ist klar geworden. Wie genau machst du das? Aus deiner Beschreibung heraus denke ich ohne Baum, oder?
Kann man deinen Compiler irgendwo sehen?

MM

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 14. July 2005, 14:16 »
Okay danke. Also bisher macht der Compiler nichts mit Mathe, außer ein paar Überprüfungen usw. Das Tokenbaum-Prinzip sieht interessant aus, ich denke ich werde es auf jeden Fall aufnehmen.

Vom Compiler gibt es bisher leider nicht viel zu sehen. Ich habe einen einfachen Präprozessor inkl. Tutorial praktisch fertig und der Compiler befindet sich in der Entwicklung. Das ganze ist für eine eigene Sprache, die L3 heißt (die Sprache ist für den Compilerbau recht einfach). Bisher kann ich:
- Variablen erstellen
- Variablen Werte zuweisen (das geht schon mit dem Mathe-Anfang)
- Inline Assembler

z.b. kann ich schon diesen Code compilieren:

DimInt x
DimInt y
x=5
y=4
asm{
mov eax, [_x]
mov ebx, [_y]
add eax, ebx
mov [_x], eax
}

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #8 am: 14. July 2005, 14:56 »
Das sieht mir irgendwie sehr nach Basic aus, kann das sein?

Und was das mit 'Mathe' betrifft, muss man den Begriff denke ich etwas weiter fassen. Ich nenne es einfach 'Ausdruck' bzw 'Expression', denn eine Anweisung wie diese "x=(a==0?0x10:0x20);" hat meiner Meinung nach nicht viel mit 'Mathe' zu tun.

Und erzeugt dein Compiler auch schon ausführbaren Code, und wenn ja, wie machst du das?

MM

Buster

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 14. July 2005, 18:31 »
Respekt! Da hast du echt viel Arbeit reingesteckt, find ich super. Wo hast du die ganze Theorie her um so ein Teil überhaupt schreiben zu können? Von deiner Uni (s. Link), Bücher, Internetdokus oder sogar nur Trial and Error? ;D
F***ed Up Beyond All Recognition!

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #10 am: 14. July 2005, 19:24 »
Bei meiner FH gibt es ein sehr cooles PMode Tutorial:
http://www.fh-zwickau.de/doc/prmo/pmtutor/text/
Aber nichts in Richtung Compiler.

Aber angefangen hatte ich auch erst vor Jahren mit einem Assembler, den ich dann immer weiter entwickelt hatte und der nun den Gundstein für meinen Compiler gebildet hatte.
Die Idee mit dem Zerlegen in die Token und das Aufbauen eines Baumes hatte ich irgendwo mal im Internet aufgeschnappt. Den Rest habe ich mir selber ausgedacht (natürlich nicht das Konzept mit Objektdateien Linker usw, sondern wie es intern funktioniert).

Ich habe zwar auch Automatentheorie usw gelernt, wo man uns immer sagte, "Das braucht man für den Compilerbau" aber ich muss sagen, man braucht es nicht ...  :wink:

MM

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 14. July 2005, 19:42 »
Zitat von: [MM]
Das sieht mir irgendwie sehr nach Basic aus, kann das sein?

Und was das mit 'Mathe' betrifft, muss man den Begriff denke ich etwas weiter fassen. Ich nenne es einfach 'Ausdruck' bzw 'Expression', denn eine Anweisung wie diese "x=(a==0?0x10:0x20);" hat meiner Meinung nach nicht viel mit 'Mathe' zu tun.

Und erzeugt dein Compiler auch schon ausführbaren Code, und wenn ja, wie machst du das?

MM

Jup, die Sprache ist an Basic angelehnt aber in Basic gibts kein Inline-Asm ^^

Der Compiler erzeugt nicht direkt ausführbaren Code sondern Assembler-Files, die man dann mit Nasm & co assemblieren kann.
Im Prinzip lese ich die Input-Datei (Includes gibt es, werden aber vom Präprozessor vorher aufgelöst also hat man nur einen File) Zeile für Zeile ein und versuche einen Befehl zu erkennen:

while(!FileIn->eof())
{
// Zeile lesen
FileIn->getline(&line[0], MAX_LINE_LENGTH, '\n');

// ----- INLINE ASSEMBLER -----
if(strcmp(line, strInlineAsm) == 0)
{
DoInlineAsm();
continue;
}

// ...

// Nichts erkannt -> Fehler
// ...
}

Wenn z.B. Inline-Assembler erkannt wurde, wird eine Funktion aufgerufen, die den Befehl in Assembler umsetzt.

Buster

  • Beiträge: 4
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 14. July 2005, 21:09 »
Geile Sache! Im wievielten Jahr oder Semester studierst du schon und was studierst du auf dieser FH? Interessiert mich unverschämt! ;D Btw das Tutorial kenn ich, ist wirklich eins der besten die ich im Internet kenne. Da bist du ja an einer fähigen FH gelandet, die sehr viel Potential hat. =D
F***ed Up Beyond All Recognition!

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #13 am: 14. July 2005, 21:26 »
Ich studiere erst seit einem Jahr an der FH-Zwickau (sind grad Prüfungen am Ende des 2. Semesters). Ich habe aber davor in Ulm als Assembler/C Programmierer von Microcontrollern gearbeitet (also auch sehr LowLevel  :wink: ). Bin nämlich von Beruf "Technischer Assistenten für Informatik".

Und als Studiengang habe ich "Systeminformatik" gewählt (im Hauptstudium). Das ist so weit ich weiß sehr selten in Deutschland, ich kenne keine andere FH die das anbietet. Da werden dann solche Sachen gemacht wie:

- Systemprogrammierung
- Objektorientierte Systeme
- Verteilte Systeme
- Neuronale Netze
- Treiberentwicklung

Und das PMode Tutorial ist Teil der Unterlagen von Systemprogrammierung.
Wie das aber in Zukunft aussieht weiß ich nicht, denn ich bin im letzten Diplomjahrgang und ich weiß nicht, was im Zuge mit Bachelor/Master da umgestellt wird.

Unter http://www.fh-zwickau.de/doc/prmo/start.htm gibt es auch noch ein MMX Tutorial, aber das kennst du dann ja bestimmt auch. Ansonsten sind die Sachen nur im Intranet zugänglich.

MM

PS @ DarkThing:
Wenn du noch vor hast Maschinencode zu generieren kann ich dir die folgende Referenz von Intel empfehlen:
http://www.intel.com/design/pentiumii/manuals/243191.htm
Am Ende gibt es eine Befehlsreferenz der x86 (>386) Serie mit allen Befehlen und Adressierungsarten in Maschinencode. Hat mir bei der Entwicklung meines Assemblers sehr geholfen.

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 15. July 2005, 13:42 »
Zitat von: [MM]

Wenn du noch vor hast Maschinencode zu generieren kann ich dir die folgende Referenz von Intel empfehlen:
http://www.intel.com/design/pentiumii/manuals/243191.htm
Am Ende gibt es eine Befehlsreferenz der x86 (>386) Serie mit allen Befehlen und Adressierungsarten in Maschinencode. Hat mir bei der Entwicklung meines Assemblers sehr geholfen.

thx, Ich hab zwar erstmal nicht vor einen Assembler zu schreiben, aber ich finde den File trotzdem recht interessant und vielleicht werde ich ihn ja später brauchen :wink:

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 16. July 2005, 20:05 »
Hm, ich muss bald auch einen Compiler schreiben, jedoch nicht um Executeables zu erzeugen, sondern um die Scriptsprache für ein Online Spiel, das ich programmiere zu compilieren. Ich hatte früher schon funktionierende Ansätze, jedoch fand ich das Parsen der Tokens und die Codegenerierung ziehmlich schwierig. Ich werde mir deinen Compiler mal ansehen. =)

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 16. July 2005, 20:12 »
Ich glaube du brauchst eher einen Interpreter für eine Scriptsprache. Und Interpreter haben nicht sehr viel mit Compilern gemeinsam, da Compiler den Code in Maschinensprache/Assembler übersetzen und Interpreter nur Funktionen z.B. einer API aufrufen.

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 16. July 2005, 20:14 »
Nein, ich will keinen Interperter XD
Ich compiliere den Code in eine Art Bytecode, der dann von einer VM ausgefürt wird.

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 17. July 2005, 14:57 »
Okay ^^
Dann brauchst du wirklich einen Compiler  :wink: Das ganze dürfte dann dem Compiler von [MM]  entsprechen nur dass du deinen Bytecode statt dem Intel Opcode erzeugst.

@MM:
Gibt es irgendwelche Tuts über Tokentrees oder so?

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #19 am: 17. July 2005, 21:02 »
Nicht das ich wüßte. Musst dir halt nur mal überlegen wie die Wertigkeiten sind, und das ganze auf Papier mal durchspielen. Einen Tipp kann ich aber noch geben:
Bei +,- bzw *,/ sollte man auf jeden Fall die gleiche Wertigkeit verwenden, sonst kommt es zu seltsamen Effekten, wie ich feststellen musste...  :wink:

Ansonsten kann ich dir nur raten, dass du dir mal ansiehst, wie mein Compiler die Debugausgabe mit dem Parameter "-stt" macht. Damit sollte man schon die meisten kniffeligen Stellen erkennen können.

Ich werde den Compiler übrigends in den kommenden Semesterferien nochmal komplett überarbeiten, denn ich hab letztens doch noch einige gravierende Mängel in der Zeigerarithmetik gefunden.

MM

 

Einloggen