Construire un système informatique avec JS? [fermé]

10

J'ai récemment terminé ce livre intitulé The Elements of Computing Systems où vous construisez un système informatique fonctionnel à partir de zéro, en commençant par les portes logiques de base, en créant votre propre code machine et langage d'assemblage, en passant par le code intermédiaire, et enfin un simple objet orienté langage de programmation qui se compile en code VM. Je l'ai beaucoup apprécié et j'aimerais créer quelque chose de similaire en JavaScript, mais avec plus de fonctionnalités. J'ai déjà écrit un émulateur pour la machine Hack dans JS:

  // Creates a new CPU object that is responsible for processing instructions
  var CPU = function() {

var D = 0;    // D Register    
var A = 0;    // A Register
var PC = 0;   // Program counter


// Returns whether an instruction is valid or not
var isValidInstruction = function(instruction) {
    if (instruction.length != 32)
        return false;

    instruction = instruction.split(""); 

    for (var c = 0; c < instruction.length; c++)
    {
        if (instruction[c] != "0" && instruction[c] != "1")
            return false;
    }

    return true;
};  


// Given an X and Y input and 6 control bits, returns the ALU output
var computeALU = function(x, y, c) {

    if (c.length != 6)
        throw new Error("There may only be 6 ALU control bits");

    switch (c.join(""))
    {
        case "000000": return 0; 
        case "000001": return 1; 
        case "000010": return -1; 
        case "000011": return x; 
        case "000100": return y; 
        case "000101": return ~x;
        case "000110": return ~y;
        case "000111": return -x; 
        case "001000": return -y; 
        case "001001": return x+1; 
        case "001010": return y+1;
        case "001011": return x-1;
        case "001100": return y-1;
        case "001101": return x+y;
        case "001110": return x-y;
        case "001111": return y-x;
        case "010000": return x*y;
        case "010001": return x/y;
        case "010010": return y/x;
        case "010011": return x%y;
        case "010100": return y%x;
        case "010101": return x&y;
        case "010110": return x|y;
        case "010111": return x^y;
        case "011000": return x>>y;
        case "011001": return y>>x;
        case "011010": return x<<y;
        case "011011": return y<<x;

        default: throw new Error("ALU command " + c.join("") + " not recognized"); 
    }
}; 


// Given an instruction and value of Memory[A], return the result
var processInstruction = function(instruction, M) {

    if (!isValidInstruction(instruction))
        throw new Error("Instruction " + instruction + " is not valid");

    // If this is an A instruction, set value of A register to last 31 bits
    if (instruction[0] == "0")
    {
        A = parseInt(instruction.substring(1, instruction.length), 2);

        PC++; 

        return {
            outM: null,
            addressM: A,
            writeM: false,
            pc: PC
        }; 
    }

    // Otherwise, this could be a variety of instructions
    else
    {
        var instructionType = instruction.substr(0, 3);
        var instructionBody = instruction.substr(3);

        var outputWrite = false; 

        // C Instruction - 100 c1, c2, c3, c4, c5, c6 d1, d2, d3 j1, j2, j3 (000..000 x16)
        if (instructionType == "100")
        {
            var parts = [ "a", "c1", "c2", "c3", "c4", "c5", "c6", "d1", "d2", "d3", "j1", "j2", "j3" ];
            var flags = {}; 

            for (var c = 0; c < parts.length; c++)
                flags[parts[c]] = instructionBody[c]; 

            // Compute the ALU output
            var x = D;
            var y = (flags["a"] == "1") ? M : A; 
            var output = computeALU(x, y, [flags["c1"], flags["c2"], flags["c3"], flags["c4"], flags["c5"], flags["c6"]]); 

            // Store the result
            if (flags["d1"] == "1") A = output; 
            if (flags["d2"] == "1") D = output;
            if (flags["d3"] == "1") outputWrite = true; 

            // Jump if necessary
            if ((flags["j1"] == "1" && output < 0) || (flags["j2"] == "1" && output == 0) || (flags["j3"] == "1" && output > 0)) 
                PC = A;
            else
                PC++; 

            // Return output
            return {
                outM: output,
                addressM: A,
                writeM: outputWrite,
                pc: PC
            }; 
        }

        else throw new Error("Instruction type signature " + instructionType + " not recognized");
    }
}; 


// Reset the CPU by setting all registers back to zero
this.reset = function() {
    D = 0;
    A = 0;
    PC = 0;
}; 


// Set the D register to a specified value
this.setD = function(value) {
    D = value;
}; 


// Set the A register to a specified value
this.setA = function(value) {
    A = value;
}; 


// Set PC to a specified value
this.setPC = function(value) {
    PC = value;
};


// Processes an instruction and returns the result
this.process = function(instruction, M) {
    return processInstruction(instruction, M); 
}; 
}; 

Je pensais ajouter des choses comme un système de fichiers, du son, une connectivité Internet et une sortie d'écran RGBA (actuellement, ce n'est que du noir et blanc). Mais dans quelle mesure serait-ce possible, vraiment?

Parce que ce que je pense à faire est de commencer complètement à partir de zéro. Et ce que je veux dire par là est de créer mon propre code machine, puis de travailler jusqu'à un langage de type C et de créer des programmes et des trucs.

Ryan
la source
11
C'est tout à fait faisable. bellard.org/jslinux
World Engineer
4
Allez-y et voyez jusqu'où vous allez. Même si vous échouez dans votre objectif ultime, je suis sûr que vous en apprendrez des tonnes, et il semble que c'est votre principale motivation.
James
2
N'utilisez pas de chaînes, javascript prend en charge les entiers 32 bits et les opérations au niveau du bit sur eux
Esailija
Le nombre est la seule véritable "mauvaise" partie de l'OMI.
Erik Reppen
Aussi, cela me donne envie de demander. Un langage interprété dynamique n'a-t-il jamais eu de couche entre lui et le langage machine?
Erik Reppen

Réponses:

2

Vous pourriez certainement le faire. Vous devez implémenter certains composants de votre système d'exploitation, tels que le chargeur de démarrage, et les interruptions dans un langage de niveau inférieur.

Jetez un œil à l'approche adoptée par le système d'exploitation Singularity de Microsoft sur la façon de développer un système d'exploitation qui s'exécute sur Managed Code.

Bien sûr, il n'est pas nécessaire de verrouiller la gestion de la mémoire en JavaScript, vous pouvez ajouter une API pour la gestion de la mémoire en JavaScript. Vous pouvez choisir d'écrire un compilateur pour JavaScript ou d'écrire une machine virtuelle.

Singularity propose du code source afin que vous puissiez obtenir des informations précieuses en examinant les décisions de conception prises par Microsoft.

Sam
la source