JS로 컴퓨터 시스템을 구축 하시겠습니까? [닫은]


10

필자는 최근 기본 논리 게이트부터 자체 기계 코드 및 어셈블리 언어 생성, 중간 코드 및 간단한 객체 지향에 이르기까지 처음부터 작동하는 컴퓨터 시스템을 구축하는 컴퓨팅 시스템 요소라는 책을 완성했습니다. 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
문자열을 사용하지 마십시오. 자바 스크립트는 32 비트 정수와 비트 연산을 지원합니다
Esailija

숫자는 유일한 "불량한"부분 IMO입니다.
Erik Reppen

또한 이것은 내가 물어보고 싶어합니다. 동적 해석 언어와 해당 언어 사이에 계층이없는 적이 있습니까?
Erik Reppen

답변:


2

당신은 확실히 할 수 있습니다. 부팅 로더와 같은 운영 체제의 특정 구성 요소를 구현하고 하위 언어로 인터럽트해야합니다.

관리 코드에서 실행되는 운영 체제를 개발하는 방법에 대해 Microsoft 의 Singularity Operating System이 취한 접근 방식을 살펴보십시오 .

물론 메모리 관리를 JavaScript로 시작해야 할 필요는 없으며 메모리 관리를위한 API를 JavaScript에 추가 할 수 있습니다. JavaScript 용 컴파일러를 작성하거나 가상 머신을 작성하도록 선택할 수 있습니다.

특이점에는 사용 가능한 소스 코드가 있으므로 Microsoft가 내린 디자인 결정을 살펴보면 귀중한 통찰력을 얻을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.