Сборка компьютерной системы с 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 (в настоящее время это только черно-белое изображение). Но насколько это возможно, правда?

Потому что я думаю о выполнении начинает полностью с нуля. Под этим я подразумеваю создание своего собственного машинного кода, затем продвижение до языка, подобного C, и создание рабочих программ и прочего.

Райан
источник
11
Это вполне возможно. bellard.org/jslinux
мировой инженер
4
Просто пойди и посмотри, как далеко ты доберешься. Даже если вы не достигнете своей конечной цели, я уверен, что вы многому научитесь, и это звучит так, как будто это ваша основная мотивация.
Джеймс
2
Не используйте строки, javascript поддерживает 32-битные целые и побитовые операции с ними
Esailija
Номер единственная настоящая «плохая» часть ИМО.
Эрик Реппен
Кроме того, это заставляет меня хотеть спросить. У какого-нибудь динамического интерпретируемого языка никогда не было слоя между ним и машинным языком?
Эрик Реппен

Ответы:

2

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

Взгляните на подход, принятый Microsoft в Singularity Operating System , по разработке операционной системы, работающей на управляемом коде.

Конечно, нет необходимости требовать управления памятью в JavaScript, вы можете добавить API для управления памятью в JavaScript. Вы можете написать компилятор для JavaScript или написать виртуальную машину.

Singularity имеет исходный код, так что вы можете получить ценную информацию, взглянув на проектные решения, которые приняла Microsoft.

Сэм
источник