1
Offtopic / Re: Logisim CPU
« am: 20. January 2013, 21:25 »
Entschuldige Bitte, aber Du weißt was ich meine.
21. November 2024, 12:28
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
Mhh man kann auch doch nur bei ein paar bestimmten Befehlen prüfen ob die Operanden gültig sind(also bei Befehlen wo das wirklich nötig ist)Ja, konzentriere Dich ruhig erst mal darauf das der Decoder die echt kritischen Dinge abfängt und den Rest kannst Du erst mal dem Assembler überlassen (also das dieser bestimmte Operanden-Kombinationen bei bestimmten Befehlen einfach nicht umsetzt, grundsätzlich sollte der Assembler keine Befehle umsetzen die die CPU bekanntermaßen nicht ausführen möchte oder die sonstwie problematisch sind). Mach Dir doch einfach dazu noch ein paar Gedanken und schreibe bei den Befehlen wo es Einschränkungen (von der CPU) geben soll diese mit dazu.
jetzt kann man auch alle register als adressregister benutzen.Sehr gut, Du musst ja nicht gleich alles in Deiner CPU unterstützen was der OpCode theoretisch her gibt.
Ich dachte, deine Architektur möchte die Speicherverwaltung etwas anders erledigen?Ja, das ist der Plan. Trotzdem wird auch meine Speicherverwaltung gewisse Features anbieten (müssen) damit ein Treiber z.B. die physische Adresse zu einer virtuellen bekommt oder wenn in Linux gewisse Dinge mit einem kleinen Trick beschleunigt werden können dann kann ich das möglicherweise bei mir auch. Außerdem geht es mir nicht primär um meine eigene Plattform sondern allgemein um das Thema möglichst einfach vorhandene Treiber (egal aus welcher Quelle) in ein Hobby-OS zu bekommen.
Sicher kannst du die ganzen schmutzigen Details so implementieren, wie Linux das tut, aber dann kannst du theoretisch auch Linux benutzen.Das möchte ich doch gar nicht, ich will doch nur eine User-Space-Library die vom Linux-Kernel gerade genug bietet damit ein Linux-Treiber funktioniert. Die Variante von „Linux on L4“ ist aus meiner Sicht höchstens ein erster Ansatz um überhaupt erst mal das Ziel erreichen zu können (und um erstmal alles das zu programmieren was diese Library für mein OS bieten muss) aber keine vernünftige Dauerlösung.
Wieso nur hab ich das geahnt?! Der Linux-Kernel ist doch das Vorzeigeprojekt der Open-Source-Scene aber eine anständige Doku ist für so ein riesen Ding wohl doch nicht mehr machbar. Schade, da der Linux-Kernel eigentlich die einzigste wirklich umfangreiche Quelle für Open-Source-Treiber ist.Die kritische Frage ist doch eher ob diese subtilen Dinge auch sauber dokumentiert sind.Natürlich nicht, sonst wären sie ja nicht subtil
Denk mal so: Du wirst auf deinem aktuellem PC kein Hobby-OS produktiv einsetzen. Wenn es überhaupt reale Hardware bekommt, dann ist das ältere Hardware.Naja, nicht jeder hat einen älteren Zweitrechner parat nur um mal eben ein Hobby-OS aus dem iNetz auszuprobieren. Aber wenn Du an einen Produktiveinsatz denkst dann hast Du natürlich recht, wobei sich das eventuell mit Hobby-OS minimal beißt.
Einen beschleunigten 2D-Treiber gibt es ab Kernel 3.8, vgl. hier. Bei 3D sieht die Situation genauso aus wie bei allen anderen ARM-Herstellern.Okay, bin überzeugt.
Also eine ähnlich bescheidene Situation wie bei FUSE, zwar ein interessantes Konzept mit viel Potential aber es gibt einfach nicht genug reales Zeugs damit sich daraus auch wirklich was ernstzunehmendes ergibt. Schade!Die libusb kenne ich auch aber das es auf dieser Basis "richtige" Treiber gibt wusste ich noch nicht.Da gibt es ganz viel Userspace-Kram, also Scanner und sowas. Mit HID, MSC und dem üblichen Zeug sieht das anders aus, weil das recht tief in den Subsystemen verwurzelt ist. Das gibt es schon, aber es bringt nichts, weil die Programme zwar die Hardware ansteuern, aber keine wirklichen Treiber sind.
ich meinte den umgekehrten Fall, paddr->vaddr. Linux hat die Speicherverwaltung so designt, dass da nur eine Konstante drauf addiert wird, was die Berechnung billig macht. Für IOMMUs gilt vermutlich das gleiche.Also auch hier muss ich ehrlich sagen das es mir schwer fällt das zu glauben. Was ist mit reinen 32Bit-System auf denen der physische 4GB-Adressraum komplett ausgeschöpft ist? Ich kann mir nicht vorstellen das im Kernel-Space (der ja nur 2GB groß ist) auch nur alle MMIO-Ranges der HW-Geräte linear rein passen (den RAM lassen wir da mal außen vor). Und die IOMMU spielt in dieser Richtung keine Rolle, nebst dessen das wenn sie so simpel benutzt wird kann man sich das auch gleich ganz sparen.
Wozu sollte ich Code schreiben, den ich selber gar nicht brauche?Ist natürlich eine berechtigte Frage. Trotzdem würde ich es als Vorteil erachten wenn das OS nicht einfach alle existierenden Treiber laden und starten muss und ich glaube auch nicht das eine kleine Tabelle (das Wort Datenbank war doch etwas übertrieben) mit den Class-Codes (für generische Treiber) oder Vendor/Device-IDs (für spezifische Treiber) so viel aufwendiger wäre.
Ich weiß, dass deine Herangehensweise eher ist, so lange zu designen, dass man nie etwas umgesetzt bekommtdas war nich lieb
Dachte an Shift-Befehle so wie wikinger beschrieben hatte...Okay, ich denke das Svenska auch an diesen Shifter-Operanden von ARM dachte den die speziellen PPC-Befehle haben 5 Operanden und sowas gibt es wimre beim klassischen ARM32 nicht (diese 5 Operanden würden bei ARM32 zusammen 23 Bit belegen).
Wofür braucht man eigentlich die Sprungbefehle JA,JAE,JB,JBE. Kann man da nicht für JA auch ein JE Befehl nehmen und für JB ein JL?JA (>) und JE (==) sind zwei unterschiedliche Dinge und deswegen wirst Du auch beide brauchen. JL und JB sind auch unterschiedlich da ersteres für signed und letzteres für unsigned ist. Bitte beschäftige Dich mal mit der Zahlendarstellung im Zweierkomplement für signed und unsigned.
Mhh wenn ich jetzt schon 2 Quellregister hab könnte ich eigentlich ja auch 2 Zielregister einbauenSolange Du nur bei Registern bleibst sollten in Deine 32Bit-Befehle locker 4 Operanden rein passen aber es gibt nur wenige Befehle die so viele Operanden wirklich benötigen und in Deiner Pipeline (also in der internen dekodierten Befehlsdarstellung) musst Du trotzdem immer 4 Operanden vorsehen (auch bei Befehlen die das nicht nutzen). Damit wäre ein R1 * R2 := R3:R4 möglich (R3 ist der High-Part des Produkts und R4 der Low-Part).
was passiert eigentlich wenn man bei den 2. Zielregister das selbe Register angibt wie beim ersten Zielregister?Das musst Du als CPU-Designer festlegen. Deswegen wolltest Du doch diesen Job, oder?
(z.B. dass vaddr->paddr niemals einen page table walk durchführt und daher schnell ist)Also wenn damit gemeint ist das eine virtuelle Adresse in die zugehörige physische Adresse umgewandelt wird glaube ich nicht mal das gar kein Page-Teble-Walk durchgeführt wird, in irgendeiner Art von Datenstruktur (was natürlich nicht zwangsläufig eine Page-Table für die CPU sein muss) muss diese Information schließlich verwaltet werden. Spätestens wenn eine I/O-MMU ins Spiel kommt ist diese Funktion nicht mehr trivial. Auch müsste überlegt werden ob diese Performance noch erreicht wird wenn die virtuelle Adresse zu einem der User-Spaces gehört.
Zu sagen, CDI habe deshalb diese Zielgruppe, ist aber falsch. CDI hat keine Zielgruppe.Sorry, da habe ich mich offensichtlich falsch ausgedrückt. Mir ist schon klar dass das keine absichtliche Entscheidung der Entwickler war primär die HW der Virtualisierer zu unterstützen sondern das es einfach ein logischer Schritt war da die Entwickler wohl oft (aber sicher nicht ausschließlich) mit einer virtuellen Maschine arbeiten. Es ging mir eher darum dass das momentan real vorhandene Treiber-Arsenal von CDI einen gefühlten Schwerpunkt auf diese Art der Geräte hat.
wenn mit dem Segmentwechsel also nicht der Rang gewechselt wird wie dann?Der aktuelle Ring wird immer mit dem Wechsel von CS geändert aber da gibt es eine Menge Regeln zu beachten (die von der CPU durchgesetzt werden) damit nicht jeder (Schad)-Code hier alles tun darf. Der Wechsel von CS kann automatisch passieren z.B. bei einem Interrupt/Exception oder einem HW-Kontext-Wechsel oder auch manuell angetriggert werden wie mit einem FAR-CALL.
im Beispielkernel wird mit diesem Code in den Ring3 gewechseltIch glaube das ist schon Dein erstes Verständnisproblem. Wenn ich den Kommentar in dem Code richtig deute dann ist dieser Code Bestandteil des Kernels und wird im Ring 0 ausgeführt und sorgt nur dafür das in den Segmentregistern DS und ES auch passende Selectoren drin sind damit der Kernel-Code (der ja DS und ES implizit benutzt) richtig funktioniert.
wieso wird beim Segmentregister ax kein Invalid Opcode ausgelöst.AX ist kein Segmentregister. siehe http://www.lowlevel.eu/wiki/X86#Segmentregister
Hat dass was mit dem InterruptFlag zu tun dass im Interrupt Context die CPU automitisch die Segmentregister sichtbar macht?Die Segmentregister sind in jedem Ring sichtbar (also lesbar) und auch änderbar (also beschreibbar), eine Exception kommt nur dann wenn auf Speicher zugegriffen werden soll und der im Hintergrund geladene Descriptor (der über den Selector selektiert wird) ungültig ist oder nicht die passenden Zugriffsrechte anbietet. Mit dem Interrupt-Flag hat das nichts zu tun.
Da gibt es irgendeine Art Bibliothek für L4 (wimre), die den Linuxkernel darstellt, und wenn man Treiber gegen die linkt, kann man die halt im Userspace ausführen und Linuxtreiber unter L4 benutzen.Hm, das ist doch schon mal ein interessanter Schritt in die richtige Richtung, auch wenn es ein paravirtualisiertes Linux ist, also auf eine Art von User-Mode-Linux hinausläuft was ich ja eigentlich nicht möchte. Um z.B. einen Ethernet-Treiber zu bekommen möchte ich mir eigentlich nicht z.B. den IP-Stack des Linux-Kernel als Ballast in meinen User-Mode-Prozess holen, ich denke schon das es besser wäre gezielt die Funktionen die mein OS selber bieten will aus dem Linux-Kernel auszublenden und dann nur das raus zu filetieren was als Abhängigkeiten übrig bleibt. Zu dem was mein OS (bzw. meine User-Mode-libc) selber bieten gehört IMHO auch die Speicherverwaltung, nur Dinge wie eben das mappen von physischen Speicherressourcen der betreffenden Hardware muss ich passend abfangen und mit einem Syscall an mein OS behandeln. Mir ist klar das diese Vorgehensweise trotzdem einiges an Arbeit erfordert und auch mein Mapping-Code je nach Geräte-Type unterschiedliche Dinge bieten muss, trotzdem halte ich das für einen vernünftigen Ansatz um nahezu beliebige Treiber von Linux in mein OS zu holen.
Außerdem verlassen sich Treiber u.U. auf bestimmte Eigenheiten der Speicherverwaltung (z.B. dass vaddr->paddr niemals einen page table walk durchführt und daher schnell ist), die bei dir nicht gegeben sind.Also davon bin ich jetzt noch nicht überzeugt. Letztendlich kocht Linux auch nur mit Wasser, also warum sollte ich diese Features/Eigenheiten nicht auch hinbekommen?
Um Linux-Treiber automatisiert übernehmen zu können, musst du in deiner Semantik so nah am Original sein, dass du dir die Kopie auch gleich sparen kannst.
Ich behaupte, dass die durchschnittlichen Nutzer von Aldi/Saturn/Mediamarkt/...-PCs nicht die Zielgruppe für Hobby-OSe sind.Okay, Punkt für Dich.
Außerdem fängt das Problem schon mit NVidia-Chipsätzen an.Schon klar, aber wäre es nicht cool wenn tyndur trotz NVidia-Chipsatz eine vernünftige Graphik bieten könnte? Mal davon abgesehen das tyndur überhaupt Graphik richtig unterstützen müsste (ja ich weiß das es da erste Ansätze gibt).
Nicht alle interessanten Treiber existieren für x64Aber beim heutigen Verbreitungsgrad von x64 sind die Lücken bereits recht dünn. Welcher HW-Hersteller kann es sich den leisten das seine HW von aktuellem Windows nicht unterstützt wird?
und bei ARM wäre ich auch sehr überrascht, wenn sich dort ein halbwegs gebrauchbares Arsenal finden würdeOkay, aber immerhin soll z.B. der Tegra 3 unterstützt werden und für diesen z.B. einen halbwegs brauchbaren Grafik-Treiber zu bekommen ist doch schon mal was.
Das heißt, du willst den kompletten Subsystemcode mit rauskopieren? Du kannst es ja mal versuchen, ob du auf diese Weise irgendwohin kommst, aber an irgendeiner Stelle musst du einen Strich ziehen. Die komplette Speicherverwaltung willst du ja vermutlich nicht kopieren.Ich denke das gerade vom betreffenden Subsystem eh nicht so viel Code kommt, wenn wir mal beim Beispiel des Ethernet-Treibers bleiben dann will ich doch gerade den IP-Stack usw. selber anbieten. Aus meiner Sicht sind eher die Funktionen kritisch die wirklich irgendwo im Kernel liegen und nicht so offensichtlich zu Ethernet-Treibern gehören. Die Speicherverwaltung aus dem Linux-Kernel zu kopieren geht natürlich gar nicht, IMHO noch nicht mal bei einem paravirtualisiertem Linux-Kernel und weil man gerade die eh für alle Treiber benötigt sollte es auch nicht so arg schwer fallen hier einmal was anständiges zu Entwickeln. Außerdem hoffe ich das sich die API zur Speicherverwaltung nur selten ändert (schon weil es da extrem viele Aufrufe gibt die man ändern müsste, da vertraue ich einfach auf die natürliche Faulheit des Menschen).
Ich glaube, wir reden aneinander vorbei, Erik.Ja, das glaube ich jetzt auch. Fragt sich nur was Tufelix dachte.
Ich rede von Instruktionen wie rlwimi oder rlwinm auf PPC.Ja, diese beiden Befehle sind cool. rlwimi hab ich auf meiner CPU auch aber etwas anders, es geht dabei ja im Prinzip darum aus einem Register von einem beliebigen Bitoffset eine bestimmte Anzahl an Bits (zusammenhängend aber ggf. mit Umlauf) aus einem Register raus zu holen und in ein anderes Register an einem anderen beliebigen Bitoffset rein zu packen (auch wieder zusammenhängend mit optionalem Umlauf) und die übrigen Bits des Zielregisters unverändert zu lassen. lrwinm hab ich aber nicht als Einzelbefehl da sich sowas auch einfach mit einer Rotation und einem anschliessendem AND darstellen lässt (wobei ich das dank des Shifter-Operanden, den ich doch vorgesehen habe, auch als Einzelbefehl haben kann aber dafür die Maske bereits in einem anderen Register vorhanden sein muss) und ich auch nicht so ganz sicher bin ob man sowas oft braucht.
der große Vorteil eines Monolithen ist, dass du interne Funktionen ohne Overhead aufrufen kannst, es also bestimmte Funktionalität nur einmal im gesamten Kernel geben muss. Da sind Bugfixes maximal effektiv.Also wenn diese Funktionen in einer DLL liegen dann sind sie aus mehreren User-Mode-Treibern mit genau so wenig Overhead aufzurufen und belegen auch nur einmal RAM/Cache und lassen sich genau so zentral warten. Sorry, aber das zählt nich. Der große Nachteil dieses Funktions-Sharings ist das wenn ein Subsystem-Entwickler sich so eine Funktion ausgedacht hat und diese dann plötzlich von den Treibern anderer Subsysteme auch benutzt wird das dann plötzlich (möglicherweise sogar ohne es zu wissen) der erste Entwickler seine Funktion nicht mehr einfach so modifizieren kann da das plötzlich unvorhergesehene Rückwirkungen auf ganze andere Dinge im Kernel hat. Diese Art von Spagetti-Code ist grundsätzlich nicht schön und ich persönlich würde gerne 0,2% System-Performance opfern wenn dafür ein stabileres System entsteht.
Viele API-Änderungen sind aber nur relativ klein bzw. lassen sich in den Treibern ohne größeren Aufwand automatisiert umsetzenIch hätte jetzt eher daran gedacht das ich aus einer bestimmten Kernel-Version bestimmte Treiber heraus filetiere, indem man ein Tool benutzt dem man sagt welche Dateien man unverändert bekommen will (den Treiber) und dieses Toll dann die Abhängigkeiten im restlichen Kernel iterativ durchgeht und genau das was benötigt wird mit ausschneidet. Letzteres abzüglich der Funktionen die ich selber anbieten muss und auch nur bei diesen Funktionen muss ich zuerst (händisch) prüfen ob sich dort die API und/oder die Funktionalität geändert hat.
Schlimmer ist, dass die ABI nicht stabil ist, was Binärtreiber verunmöglicht.Einige HW-Hersteller haben mehr oder minder erfolgreich vorgeführt das auch dieses Problem lösbar ist.
Theoretisch kannst du jeden Treiber mit einem halben Linux verheiraten und im Userspace laufen lassen, ob das aber mehr Spaß macht als den Treiber zu reversen und neu zu entwickeln, kann ich nicht einschätzen.Es geht mir nicht um den Spaß sondern darum ein Ziel mit möglichst geringem Aufwand zu erreichen und ich will auch nicht den halben Linux-Kernel sondern nur genau das was der Treiber benötigt und nicht eh von mir kommen muss (weil gewisse Dinge eben zu meinem OS passen müssen, alles andere würde auf nahezu vollwertiges User-Mode-Linux hinauslaufen).
Vermutlich kommst du da mit den BSD-Treibern eher weiter, die haben da - soweit ich das einschätzen kann - kleinere Schnittstellen. Andererseits ist z.B. der nouveau-Treiber von den Entwicklern als Kernel- und Userspace-Treiber ausgelegt worden, damit die bei der Entwicklung "mal eben schnell" eine Änderung testen können.Okay, es gibt also mehr Quellen als nur den Linux-Kernel, wenn mein oben beschriebenes Tool flexibel genug ist sollte auch das kein Problem sein.
Ich denke, wenn man sich auf Treiber einer Klasse (z.B. Ethernet) beschränkt, kann man Linux-Treiber portieren. Wenn man aber alle/viele verschiedene Treiber übernehmen will, läuft das auf eine Reimplementation von Linux im eigenen Kernel raus.Naja, also wenn dann geht es IMHO schon darum die typischen PCs die Media-Markt/Saturn/ALDI/... in den letzten X Jahren verkauft haben zu unterstützen damit mein kleines Hobby-OS auf möglichst vielen potentiellen PCs läuft. Wenn wir uns mal ansehen für welche HW es CDI-Treiber gibt dann muss man ganz klar sagen das deren Zielgruppe die virtuellen PCs von VMware und Co sind. Klar auch das ist ein Markt, wenn man damit (und den anderen Nachteilen von CDI) zufrieden ist dann ist CDI eine interessante Wahl aber wenn man mehr will dann ist es eventuell ratsam doch mal die Alternativen zu prüfen.
Windows-Treiber haben den Vorteil der Verfügbarkeit, sind aber meist hinreichend schlecht/instabil programmiert.Um ersteres geht es mir doch und ob ich als Hobby-OS-Dever im zweiten Punkt mit eigenen Treibern so viel besser abschneiden würde steht auf einem anderen Blatt (deswegen bin ich ja so an den Linux-Treibern interessiert, die sind ebenfalls gut verfügbar und meistens von mindestens ebenwürdiger Qualität).
Außerdem ist es trotzdem eine ziemlich heftige API, die man unterstützen muss (Binärformate, ...).Das ist wohl war. Die Windows-Treiber-API gibt es in verschiedenen Geschmacksrichtungen und jede Treiber-Sorte benötigt eine eigene API und dann hat man oft sogar noch die Wahl ob der Treiber im User-Mode oder im Kernel-Mode laufen soll. Aber gemessen an dem Aufwand den man investieren müsste um alle gewünschten Treiber selber zu entwickeln ist das vielleicht gar nicht mal so viel wie es scheint. Nebst dessen das man sich vielleicht bei ReactOS bedienen kann.
Portabel ist es dann auch nicht, aber bei einem Hobby-OS tut das nicht unbedingt weh.Zumindest x86 in 32Bit und 64Bit und demnächst auch ARM in 32Bit und 64Bit sind doch schon mal was. Was will den der klassische Hobby-OS-Dever (der keine eigene Plattform bauen möchte, so wie wir beide) mehr?
Wobei ich keine Ahnung habe, wie doof sowas umzusetzen ist.Ziemlich doof, glaub mir.
mein CPU wird erstmal ohne Pipeline arbeiten, da wird es sicherlich keine Probleme wegen der abhängigkeit geben...Ja, bei mit ohne Pipeline sollte das keine Probleme mit der Performance o.ä. machen.
Werde dann wohl auch die 3-Operanten Befehle einbauen...Das alleine bringt schon einiges an Performance weil weniger Befehle für die selbe Sache benötigt werden.
Barrel-shifter könnte ich eigentlich auch einbauenIch denke das solltest Du fürs erste lassen, damit wird Deine CPU um einiges komplexer und vor allem wird die Codierung der Befehle deutlich komplexer. Versuch doch erst mal eine möglichst einfache CPU zuverlässig ans laufen zu bekommen bevor Du Dir die nächste Schwierigkeitsstufe vornimmst. ARM hat diese Shifter-Operanden auch nur bei manchen Befehlen und für Konstanten, letzteres Problem hast Du nicht weil Du in Deine 32Bit Befehle eine 16Bit-Konstante immer ohne Verrenkungen komplett rein bekommst.
dann werd ich auf die ersten 4 bits der Konstanten-bits die distanz-bits legen.Hä, wie meinen?
Nun kann man eigentlich etwas an den Load und Store-Bits verbessern?Versuch doch erst mal Dein Konzept als ganzes mit den jüngsten Vorschlägen dieses Thread neu aufzubauen und dann sehen wir wie weiter verbessert werden kann.
... Selbstverständlich machen sie auch ausgiebig Gebrauch davon, ...War nicht gerade das der Haupt-Kritik-Punkt den die Pioniere der Micro-Kernel an den damaligen OSen hatten? Und in den mindestens 30 Jahren haben die OS-Dever die Monolithen schreiben nichts gelernt? Es ist ja nicht so das mich das überraschen tät (so sind Menschen eben) aber entsetzt bin ich da jetzt doch.
Das andere Problem ist, dass die Schnittstellen innerhalb von Kernel nicht stabil sindDas ist aus meiner persönlichen Sicht der größte Kritikpunkt am Linux-Kernel überhaupt (mal davon abgesehen das er ein Monolith ist ) und ich wette viele Firmen die Hardware herstellen sehen das ähnlich.
und soviel Ich weiß geht das übers SMBios.Dafür gibt es auf der x86-Platform nahezu unzählig viele Wege, je nach Baujahr des PC kann das auch das SMBios sein. Heute ist ACPI aktuell.
aber wie weiß das SMBios ob gerade ein aufgebrezeltes 3D-Spiel oder nur HintergrundProzesse laufen?Für die Priorität der ausgeführten Prozesse interessiert sich das SMBios gar nicht, wichtig ist nur ob überhaupt irgendein Prozess sinnvolle Arbeit mit der CPU durchführt oder ob die CPU schlafen geschickt wird.
Hat das was mit der NOP Instruktion zu tun?Nein, wenn dann eher mit HLT. Wann immer die CPU einen HLT-Befehl ausführt wechselt diese in einen (einstellbaren) Schlafmodus. Dank heutigem Multicore und Hyperthreading ist das aber insgesamt eine recht komplexe Angelegenheit geworden, in der ACPI-Spec finden sich zu diesem Thema sicher ein paar hundert Seiten dehnen Du bestimmt nähere Einzelheiten entnehmen kannst (falls Du dieses typisch verkorkste Spezifikations-Englisch entschlüsseln kannst).
Mittlerweile gibt es so viele allgemeine Fragen über X86 oder Prozessoren allgemein(zB wie man sie baut^^),dass es sinnvoll wäre ein eigenes Board zu öffnen, damit nicht alles in Offtopic verschwindet.Also für ein eigenes Board das sich primär um reine Hardwarethemen dreht sehe ich nicht genug Bedarf und da Offtopic auch ansonsten nicht gerade überrannt wird denke ich das diese Themen hier recht gut aufgehoben sind.
... dann fallen da sämtliche Heimcomputer und alle CPUs raus, die man üblicherweise als 8-Bit-CPUs bezeichnet ...Ja, aber das liegt daran das man zur Klassifizierung üblicherweise die Datenpfadbreite in der ALU heranzieht. Ich persönlich bin aber der Meinung dass das nicht so ganz korrekt ist, zumindest die vom CPU-Kern nativ unterstützte Adressbreite sollte ebenfalls etwas berücksichtigt werden. Stell Dir mal vor es würde jemand eine CPU bauen die zwar nur über 8Bit breite Register und eine entsprechende ALU verfügt aber dafür in der Lage ist immer 4 dieser Register zu einem Pointer zusammenzufassen um damit 4GB Speicher flach zu adressieren und dazu vielleicht sogar noch vollwertiges Paging beherrscht (so das sogar ein normales unbeschränktes Linux drauf laufen könnte), würdest Du das immernoch als 8Bit-CPU bezeichnen?
... dass ein OS unter diesen Bedingungen ziemlich unmöglich ist.Vor allem auch ziemlich nutzlos. Mehr als eine einfache Library (die ins eigentliche Programm fest mit einkopiliert werden muss) die ein paar der Funktionen eines OS anbietet (wie z.B. preemptives Multitasking oder einfache Kommunikationsmechanismen) macht auf CPUs wie dem AVR einfach keinen Sinn.
Ich kenne keine 8-Bit-CPU, die ausschließlich 8-Bit hat, also mit 8-Bit-Opcodes und 8-Bit-Registern und 8-Bit-Daten.Ich auch nicht, also lassen wir das einfach so wie es ist.
Hm, auf einer 8-Bit-CPU noch von Words statt einfach Bytes zu reden fühlt sich irgendwie auch ein bisschen schräg an.Wenn "Word" im Sinne von "kleinste adressierbare Einheit" gemeint ist ergibt das durchaus Sinn. Für Audio gab es mal spezielle DSPs die 64kWords adressieren konnten aber diese Words immer 24Bit groß waren oder denke an die 4Bit-CPUs für Taschenrechner u.ä.
Nun wenn ich jetzt in einem Befehl einen 16 bit wert in den ram laden möchteDu meinst eine Konstante direkt in den Speicher schreiben? Welchem Zweck sollte so ein Befehl dienen? Ich kenne außer x86 keine CPU die sowas kann (obwohl, wimre kann die PDP-11 sowas auch), zumindest kenne ich keine RISC-CPU die sowas kann.
Nun in Logisim gibts ja das Multiplizierer- und Dividierer-Bauteil (bei denen legt man einfach 2 werte an die eingäge und ohne takt bzw verzögerung wird das ergebniss an den ausgang angelegt und bleibt solange bestehen bis die werte am eingang sich verändern), die wollte ich in die ALU mit einbauen.Dann bau die beiden Befehle mit ein. Falls Du diese CPU später mal in einem echten FPGA haben möchtest dann ist die Multiplikation (wie schon geschrieben) kein Problem und für die Division kann ich Dir gerne ein wenig voll parametrierbaren VHDL-Code geben.
Und ich stell negative Zahlen meistens im Zweierkomplement dar.Ja, der ist wirklich gut, ich hab fast unterm Tisch gelegen!
Nun ich eigentlich nur fünf, JE, JG, JGE, JL und JLE.Ich fürchte das wird nicht reichen. Da fehlt zumindest ein JNE (falls mal etwas nicht gleich sein soll) und für die anderen 4 fehlen noch 4 weitere Varianten für unsigned (JA/JAE/JB/JBE) und eventuell noch die Varianten zum direkten testen der anderen Flagbits (mit JE/JNE prüft man nur das Z-Flag). Du solltest Dir generell mal das Zusammenspiel der klassischen 4 Flagbits und der zugehörigen 14 Bedingungen ansehen (bei x86 gibt es noch zusätzlich das exotische Parity-Bit und eben 16 Bedingungen aber das muss kein Vorbild sein). Auch solltest Du Dich mal damit beschäftigen wie die verschiedenen Rechenbefehle die Flags setzen und wie man daraus Rückschlüsse auf signed und unsigned ziehen kann.
Und sie sollten mit Registervergleichen arbeiten, will daher diese Jump-Einheit einbauen.Falls Du damit meinst das Du direkt den Inhalt von zwei beliebigen Registern vergleichen willst (oder einem beliebigen Register und ner kleinen Auswahl an Konstanten wie +1/0/-1) dann finde ich das ne ganz tolle Idee, damit könntest Du die Flags gleich komplett sparen und würdest eine Engstelle bei den Abhängigkeiten zwischen den Befehlen beseitigen.
Mhh ich glaub ich bau diese Pop und Push befehl ein.Also ich persönlich rate davon ab aber das hatte ich ja schon erklärt.
Nun hab an 16 bit gedacht und die Befehle feste 32 bit breite.Cooool, da kannst Du ja bei den Befehlen aus dem Vollen schöpfen. Dann solltest Du bei der Anzahl der Register lieber ein klein wenig großzügiger sein. Da Du so in 16 OpCode-Bits immer den Befehl ansich und noch 2 Register unterbringen kannst sollten alle Befehle die mit Konstanten arbeiten diese auch immer mit voller 16Bit-Größe enthalten können.
naja welche Flags brauch ich den?Wenn Du wirklich bedingte Sprünge baust die den Vergleich mit enthalten dann gar keine, ansonsten die üblichen 4.
Welche Vor und nach Teile hat eigentlich so ne 16 bit architektur im gegensatz zu 8 bit?Kostet mehr Geld (also Transistoren auf echtem Silizium) und kann mehr leisten. Auf ner winzigen 8Bit-CPU würde ich erst gar nicht anfangen etwas zu programmieren das man hinterher als OS bezeichnen möchte, ja ich weiß das es sowas gibt aber mit einem richtigen OS hat das meiner persönlichen Meinung nach noch nicht viel zu tun sondern ist eher ne Art Runtime-Library.
Wird dein Projekt jetzt eher ein µC (also mit Ports) oder ein µP (also mit Bus)?Und wo ist da für die eigentliche CPU der Unterschied?