Побудова комп'ютерної системи з JS? [зачинено]


10

Нещодавно я закінчив цю книгу під назвою «Елементи обчислювальних систем», де ви будуєте робочу комп'ютерну систему з нуля, починаючи від базових логічних воріт, до створення власного машинного коду та мови складання, до проміжного коду і, нарешті, простого об'єктно-орієнтованого мова програмування, що компілюється до коду VM. Мені дуже сподобалось, і я хотів би створити щось подібне в JavaScript, але з більшою кількістю функцій. Я вже написав емулятор для машини Hack в 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); 
}; 
}; 

Я думав над тим, як додати такі речі, як файлова система, звук, підключення до Інтернету та вихід на екран RGBA (наразі це лише чорно-білий). Але наскільки це було б реально?

Бо те, що я думаю про те, починаю повністю з нуля. І що я маю на увазі під цим - створити власний машинний код, потім працювати весь шлях до мови, подібної С, і фактично створювати робочі програми та інше.


11
Це цілком можливо. bellard.org/jslinux
World Engineer

4
Просто займіться цим і подивіться, як далеко ви дістанетесь. Навіть якщо ви не зможете досягти своєї кінцевої мети, я впевнений, що ви навчитеся тонам, і це здається, що це ваша основна мотивація.
Джеймс

2
Не використовуйте рядки, javascript підтримує 32 бітні цілі числа та побітові операції над ними
Esailija

Номер - єдина реальна "погана" частина ІМО.
Ерік Reppen

Крім того, це змушує мене запитати. Чи жодна динамічна інтерпретована мова ніколи не мала шару між нею та машинною мовою?
Ерік Reppen

Відповіді:


2

Ви точно можете це зробити. Вам потрібно буде реалізувати певні компоненти вашої операційної системи, такі як завантажувач і перервати мову нижчого рівня.

Погляньте на підхід, який використовує операційна система сингулярності Microsoft щодо розробки операційної системи, що працює на керованому коді.

Звичайно, немає ніякої вимоги, що вам потрібно зафіксувати управління пам'яттю в JavaScript, ви можете додати API для управління пам'яттю до JavaScript. Ви можете вибрати компілятор для JavaScript або написати віртуальну машину.

У сингулярності є вихідний код, щоб ви могли отримати цінну інформацію, переглядаючи дизайнерські рішення, які приймав Microsoft.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.