Сборка компьютерной системы с 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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.