Xây dựng hệ thống máy tính với JS? [đóng cửa]


10

Gần đây tôi đã hoàn thành cuốn sách có tên Các yếu tố của hệ thống máy tính nơi bạn xây dựng một hệ thống máy tính hoạt động từ đầu, bắt đầu từ các cổng logic cơ bản, để tạo mã máy và ngôn ngữ hội của riêng bạn, đến mã trung gian và cuối cùng là hướng đối tượng đơn giản ngôn ngữ lập trình biên dịch xuống mã VM. Tôi rất thích nó và tôi muốn tạo ra một cái gì đó tương tự trong JavaScript, nhưng với nhiều tính năng hơn. Tôi đã viết một trình giả lập cho máy Hack trong 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); 
}; 
}; 

Tôi đã suy nghĩ về việc thêm những thứ như hệ thống tập tin, âm thanh, kết nối Internet và đầu ra màn hình RGBA (hiện tại nó chỉ có màu đen và trắng). Nhưng làm thế nào khả thi điều này sẽ thực sự?

Bởi vì những gì tôi nghĩ về việc làm đang bắt đầu hoàn toàn từ đầu. Và điều tôi muốn nói là tạo mã máy của riêng tôi, sau đó làm việc theo hướng ngôn ngữ giống như C và thực sự tạo ra các chương trình và công cụ làm việc.


11
Nó hoàn toàn khả thi. bellard.org/jslinux
Kỹ sư thế giới

4
Chỉ cần đi cho nó và xem bạn nhận được bao xa. Ngay cả khi bạn thất bại trong mục tiêu cuối cùng của mình, tôi chắc chắn bạn sẽ học được rất nhiều, và có vẻ như đó là động lực chính của bạn.
James

2
Không sử dụng chuỗi, javascript hỗ trợ số nguyên 32 bit và hoạt động theo bit trên chúng
Esailija

Số là phần IMO thực sự "xấu".
Erik Reppen

Ngoài ra, điều này làm cho tôi muốn hỏi. Có bất kỳ ngôn ngữ diễn giải động bao giờ không có một lớp giữa nó và ngôn ngữ máy?
Erik Reppen

Câu trả lời:


2

Bạn chắc chắn có thể làm điều đó. Bạn cần triển khai một số thành phần nhất định trong hệ điều hành của mình, chẳng hạn như bộ tải khởi động và ngắt ở ngôn ngữ cấp thấp hơn.

Có một cái nhìn về cách tiếp cận của Hệ điều hành Singularity của Microsoft về cách phát triển một hệ điều hành chạy trên Mã quản lý.

Tất nhiên, không có yêu cầu nào bạn phải áp dụng quản lý bộ nhớ vào JavaScript, bạn có thể thêm API để quản lý bộ nhớ vào JavaScript. Bạn có thể chọn viết trình biên dịch cho JavaScript hoặc viết máy ảo.

Singularity có sẵn mã nguồn để bạn có thể có được cái nhìn sâu sắc có giá trị từ việc xem xét các quyết định thiết kế mà Microsoft đưa ra.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.