JSでコンピューターシステムを構築していますか?[閉まっている]


10

私は最近、この本「The Elements of Computing Systems」を完成させました。基本的な論理ゲートから、独自の機械語コードとアセンブリ言語の作成、中間コード、そして最後に単純なオブジェクト指向に至るまで、ゼロから機能するコンピューターシステムを構築します。 VMコードにコンパイルするプログラミング言語。私はそれをたくさん楽しんだので、JavaScriptで同様の何かを作成したいと思いますが、より多くの機能を備えています。私は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
ちょうどそれのために行き、あなたがどこまで行くか見てください。たとえあなたが最終的な目標に失敗したとしても、きっとあなたはたくさんのことを学ぶでしょう、そしてそれがあなたの主な動機のように思えます。
James

2
文字列を使用しないでください
。JavaScript

数は、唯一の本当の「悪い」部分IMOです。
Erik Reppen 2013

また、これは私に尋ねたいと思います。動的インタープリター型言語と機械語の間にレイヤーがなかったことがありますか?
Erik Reppen 2013

回答:


2

あなたは確かにそれを行うことができました。ブートローダーや割り込みなど、オペレーティングシステムの特定のコンポーネントを低レベルの言語で実装する必要があります。

マネージコードで実行されるオペレーティングシステムを開発する方法について、MicrosoftのSingularityオペレーティングシステムが採用しているアプローチをご覧ください。

もちろん、メモリ管理をJavaScriptにボルトで固定する必要はありません。メモリ管理用のAPIをJavaScriptに追加できます。JavaScript用のコンパイラを作成するか、仮想マシンを作成するかを選択できます。

Singularityにはソースコードが用意されているので、Microsoftが行った設計上の決定を見れば、貴重な洞察を得ることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.