Unterschiedliche Prozessoren



  • Hallo.
    Ich will mich in nächster Zeit mit Maschinensprache beschäftigen unteranderem da ich jetzt endlich meinen Assembler/Disassembler fertigstellen will(okay, weit bin ich noch nicht). Dazu hab ich noch ein paar algemeine Fragen.

    1. Wie können die gleichen Programme auf unterschiedlichen Prozessoren laufen, wenn diese unterschiedliche Befehlssätze haben?
    2. Wie kann ich auf den Arbeitspeicher zugreifen (hab ich komischerweise noch in keinem Tutorial gelesen)?
    3. Wie kann ich direkt auf die Grafikkarte zugreifen (also ohne OpenGl o.ä.)?

    Wäre schön wenn mir die Fragen beantwortet werden könnten.
    Danke 🙂



    • 1. Gar nicht. Aber z.B. haben alle x86 Prozessoren den selben Befehlssatz (oder zumindest ein großer Teil ist gleich), das selbe gilt auch z.B. für ARM-Prozessoren, uns. Deshalb sind Programme dann zwischen diesen Prozessoren auch kompatibel, allerdings gibts auch Einschränkungen, wenn z.B. ein Programm mit SSE2 Unterstützung kompiliert wird, wird es auf zu alten Prozessoren auch noch nicht laufen, weil sie diesen Befehlssatz nicht unterstützen.
    • 2. Ich verstehe die Frage nicht. Bei x86 unterstützden das Unmengen an Befehlen, z.B.
    mov [eax], ebx
    

    schreibt ebx an den Speicher mit Adresse eax.
    Für RISC Architecture gibts dagegen normal einen "load value at address in register" und einen "store value from regsiter at address" Befehl.

    • 3. Kurze Antwort: gar nicht. Lange Antwort: Das läuft meistens über "Memory mapped IO" oder "Port mapped IO". Allerdings sind die Grafiktreiber a) viel zu komplex und b) die architektur geheim gehalten, da hast du so ziemlich keinen Chance ohne deren Treiber was Sinnvolles auf die Beine zu stellen.


    1. Wenn ein Programm in einer Hochsprache geschrieben ist, kann man es grundsätzlich für unterschiedliche Befehlssätze compilieren. Mit Assembler ist das nicht möglich.

    2. Bei x86 kann MOV auch von einer Adresse in ein Register (und umgekehrt) übertragen. Bei RISC Architekturen gibt es oft separate load und store Befehle.

    3. Das ist eher ein Betriebssystem Thema. Die Kontrollregister und/oder der Speicher der Grafikkarte wird in den Adressraum eingeblendet und man kann dann wie in 2) beschrieben mit der Grafikkarte Daten austauschen. Wie genau man mit den jeweiligen Grafikkarten kommunizieren muss ist aber wenig öffentlich bekannt und dokumentiert. Meistens beschränkt man sich da auf VGA und SVGA etc., weil diese noch standardisiert sind.

    Edit: Zu lang zum Tippen gebraucht...



  • Danke für die Antworten.
    Und irgendwie hab ich immer gedacht, dass man mit mov nur die Register des Prozessors ansprechen kann.
    Also wenn ich jetzt einen Assembler schreibe und den auch benutzen werde, dann brauch er ja eig. nur x86 zu unterstützen, oder?
    Da dies ja die meisten haben(oder fast alle?).
    Also was ich machen will:
    Ich will einen Skript-Importer für mein Spiel schreiben. Meine Idee ist, die Skripte am Start des Programms in Maschinencode zu compilieren (bzw. assemblen).
    Dann werde ich das Ergebnis in temporären EXE-Dateien ablagern. Diese werden dann immer an der richtigen Stelle ausgeführt. Das wäre glaub ich nämlich die schnellste Lösung.
    Ich muss nur hinkriegen aus diesen EXE-Dateien auf das Hauptprogramm zuzugreifen können(Variablen, Funktionen...).
    Hab das mir aber schonmal angekuckt und es sieht einigermaßen einfach aus und ist auch schnell zu bewältigen.



  • coder++ schrieb:

    Also wenn ich jetzt einen Assembler schreibe und den auch benutzen werde, dann brauch er ja eig. nur x86 zu unterstützen, oder?

    Wenn du dich auf normale PCs beschränkst, ja.

    coder++ schrieb:

    Also was ich machen will:
    Ich will einen Skript-Importer für mein Spiel schreiben. Meine Idee ist, die Skripte am Start des Programms in Maschinencode zu compilieren (bzw. assemblen).
    Dann werde ich das Ergebnis in temporären EXE-Dateien ablagern. Diese werden dann immer an der richtigen Stelle ausgeführt. Das wäre glaub ich nämlich die schnellste Lösung.
    Ich muss nur hinkriegen aus diesen EXE-Dateien auf das Hauptprogramm zuzugreifen können(Variablen, Funktionen...).
    Hab das mir aber schonmal angekuckt und es sieht einigermaßen einfach aus und ist auch schnell zu bewältigen.

    Das was du da beschreibst ist vom Prinzip her JIT Compiling. Schnell gemacht und einfach ist das eher nicht.



  • Da hast du Recht.
    Aber wenn ich dann einen Compiler geschrieben hab...
    Trotzdem werde ich wahrscheinlich erst mal einen anderen Compiler nehmen.
    Und nicht dass ihr denkt, es soll keine mega Hochsprache sein mit Klassen und so.
    Nur eine kleine Skript-Sprache.

    Ist das aber eig. auch das schnellste?
    Und wie würde man sonst Skript-Sprachen machen, wenn nicht durch Maschinencode?



  • Und wie würde man sonst Skript-Sprachen machen, wenn nicht durch Maschinencode?

    Interpretiert. Da kannst du das ganze leicht sehr dynamisch halten. Aber für maximale Geschwindigkeit gibts dann wie schon gesagt JIT-Compiling, also Maschinencode.

    Aber in Exen kompilieren ist ne schlechte Idee. Wenn schon kannst du das gleich alles im Speicher halten, das ist deutlich einfacher...

    Wenn du was wirklich effizentes willst nimm eine schon bestehende Skriptsprache 😉



  • Okay danke nochmal.
    Werd mir das alles moch überdenken.



  • Oh und danke für den Link zu JIT-Compiling.
    Ich hab mir jetzt auch erst mal ein Buch über Assemblerprogrammierung auf x86 Prozessoren geholt. Das les ich nun und kucke dann später die Opcodes nach, um einen Assembler schreiben zu können.
    Aber eins hab ich noch nicht verstanden.
    Wie funktioniert JIT-Compiling jetzt.
    Es wurde etwas erwähnt davon, dass das die exe modifiziert wird.
    Würde aber wahrscheinlich nicht so einfach sein.
    Ich hab nur einen Vorteil: ich will meine Skripte nur einmal (am Start des Programms) kompilieren.
    So könnte es die Arbeit möglicherweise vereinfachen.
    Im Grunde sollen die Skripte durch "Hooks" funktionieren. Die jeweiligen Funktionen werden dann in der exe gesucht und an der richtigen Stelle das Kompilat eingefügt(also werden immer nur Teile kompiliert).



  • Das les ich nun und kucke dann später die Opcodes nach, um einen Assembler schreiben zu können.

    Kannst du auch im Internet nachschauen. Schau mal diese X86 Opcode Referenz an.

    Es wurde etwas erwähnt davon, dass das die exe modifiziert wird.

    Im Grunde sollen die Skripte durch "Hooks" funktionieren. Die jeweiligen Funktionen werden dann in der exe gesucht und an der richtigen Stelle das Kompilat eingefügt(also werden immer nur Teile kompiliert).

    Ich hör immer exe... Vergiss das mal schnell wieder, mit exe hat das nichts zu tun!!
    Exe ist das Format für eine Windows Anwendung, will du aus deine Scripts eigenständige Windowsanwendungen machen ?
    Letztendlich würde ich mir einfach eine kleine Funktion in Assembler programmieren die in der Lage ist Funktionen mit variabler Parameterlänger aufzurufen. C/C++ unterstützt das dynamisch bekanntlich nicht wirklich. Deshalb eine Hilfsfunktionen die sich um die Konvertierung und Übergabe der Parameter kümmert.
    Danach generierst du zur Laufzeit aus dem Script Maschinencode, diesen speicherst du dann in einem Array, der Speicher sollte allerdings ausführbar sein.. Wenn die Funktion aufgerufen werden soll rufst du die Hilfsfunktion auf, gibst ihr die Adresse der kompilierten Scriptfunktion und alle nötigen Parameter. Diese werden dann automatisch auf den Stack gepusht, die Scriptfunktion ausgeführt und dir das Ergebnis zurückgegeben.



  • C/C++ unterstützt das dynamisch bekanntlich nicht wirklich

    void my_crazy_fun(char* in, int in_size, char* out, int out_size)
    

    Asm-Jit gibt es auch als fertige Bibliotheken.



  • knivil schrieb:

    void my_crazy_fun(char* in, int in_size, char* out, int out_size)
    

    Jaja, aber wenn die Scriptfunktion selber variable Parameter hat und man nicht jede Funktion nach diesem Schema implementieren will/kann ?
    Dann braucht man erst ne Wrapperfunktion

    Asm-Jit gibt es auch als fertige Bibliotheken.

    Aber da gibts auch keinen Lerneffekt. 🙄
    Man kann auch gleich ne bestehende Scriptsparaceh nutzen, dann muss man (fast) gar nichts programmieren...



  • Oh danke.
    Ich hoffe das klingt jetzt nicht dümmlich, aber meinst du jetzt,dass ich die kompilierten Skripte IM Programm direkt an den Prozessor gebe?
    Wusste halt nicht, dass es geht.
    Nochmals danke.
    Und falls ich es wieder nicht verstanden habe, dann macht es mir nichts aus wieder korrigiert(bzw. belehrt) zu werden.
    Das ist halt das Problem an Hochsprachen: Man muss sich nicht mit dem Prozessor direkt beschäftigen.
    Deswegen lerne ich ja jetzt auch Assembler.



  • Jaja, aber wenn die Scriptfunktion selber variable Parameter hat und man nicht jede Funktion nach diesem Schema implementieren will/kann ?

    Wenn man sich beispielsweise Lua anschaut, dann ist das so geloest (mehr oder weniger), genannt Lua-Stack. Konsistente Arbeitsweise, einheitliches Interface fuer dieses Objekt, ... win

    Dann braucht man erst ne Wrapperfunktion

    Brachste sowieso, wenn Komponenten und Scriptfaehigkeit entkoppelt sind.

    Aber da gibts auch keinen Lerneffekt.

    Sie sind meist als Sourcen verfuegbar. Erzeugen eben nur Maschinencode und kuemmern sich um Details wie Aufrufkonventionen, Stackalignment, ausfuehrbarer Speicher ... Und anscheinend hat coder++ davon noch nicht soviel Ahnung.

    Man kann auch gleich ne bestehende Scriptsparaceh nutzen, dann muss man (fast) gar nichts programmieren...

    Lol.



  • knivil schrieb:

    Und anscheinend hat coder++ davon noch nicht soviel Ahnung.

    Ja das stimmt, deswegen lerne ich ja auch Assembler und weil es mich auch interessiert.



  • coder++ schrieb:

    Danke für die Antworten.
    Und irgendwie hab ich immer gedacht, dass man mit mov nur die Register des Prozessors ansprechen kann.

    Wenn die x86-Register als Adressregister verwendet werden, wird damit auf eine Speicheradresse zugegriffen.
    Adressregister für 16 Bit:
    BX, SI, DI ; default DS Datensegment
    SP, BP ; default SS Stacksegment

    Adressregister für 32 Bit:
    EAX, EBX, ECX, EDX, ESI, EDI
    ESP, EBP

    Also wenn ich jetzt einen Assembler schreibe und den auch benutzen werde, dann brauch er ja eig. nur x86 zu unterstützen, oder?
    Da dies ja die meisten haben(oder fast alle?).

    Es gibt viele x86 und ich meine, dass die MMX-Register/Befehle schon früh mit hinzukamen und seitdem für quasi alle x86-Rechner zur Verfügung stehen.
    (Pentium MMX als minimale Systemanforderung ist bestimmt nicht zu viel verlangt.)
    Beispiel:

    0F 6F 06   movq mm0,[esi] ; holt 8 Bytes aus der Adresse in DS:ESI
    0F 7F 07   movq [edi],mm0 ; schreibt 8 Bytes zur Adresse in DS:EDI
    

    Dirk



  • freecrac schrieb:

    Es gibt viele x86 und ich meine, dass die MMX-Register/Befehle schon früh mit hinzukamen und seitdem für quasi alle x86-Rechner zur Verfügung stehen.
    Dirk

    Der MMX Befehlssatz ist schon seit vielen Jahren obsolet und sollte durch SSE und seine Nachfolger ersetzt werden.



  • SSE2 schrieb:

    freecrac schrieb:

    Es gibt viele x86 und ich meine, dass die MMX-Register/Befehle schon früh mit hinzukamen und seitdem für quasi alle x86-Rechner zur Verfügung stehen.
    Dirk

    Der MMX Befehlssatz ist schon seit vielen Jahren obsolet und sollte durch SSE und seine Nachfolger ersetzt werden.

    Ach wirklich, dann sind wohl alle x86-32Bit ebenfalls schon obsolet und morgen dann alle x64, wenn dann nur noch ARM-CPUs verkauft werden und auf gar keinem Neu-Rechner mehr Windows installiert ist?

    Sonst kann die Systemanforderung natürlich auch auf AMD AThlon XP, bzw. auf Pentium 3 erhöht werden, womit der AMD K6, K6-2(+), K6-III(+), AMD Duron Spitfire, Morgan, Applebred, AMD Athlon Pluto/Orion, Thunderbird, und von Intel der Pentium MMX(P55C), Pentium II (Klamath), Mobile Pentium MMX (Tillamook), Pentium II (Deschutes), Mobile Pentium II, Celeron (Covington), Pentium II Xeon (Drake) und Celeron (Mendocino) noch nicht mit unterstützt wird, weil diese CPUs zwar schon MMX, aber noch kein SSE mitbringen.

    Dirk



  • Joah, danke nochmal.


Log in to reply