JS ile bir bilgisayar sistemi mi inşa ediyorsunuz? [kapalı]


10

Son zamanlarda, temel mantık kapılarından başlayarak, kendi makine kodunuzu ve Montaj dilinizi oluşturmaya, ara koda ve son olarak basit bir nesne yönelime kadar, sıfırdan çalışan bir bilgisayar sistemi kurduğunuz Bilgi İşlem Sistemleri Elemanları adlı bu kitabı bitirdim. VM kodunu derleyen programlama dili. Çok keyif aldım ve JavaScript'te benzer bir şey oluşturmak istiyorum, ancak daha fazla özellik ile. JS'de Hack makinesi için bir emülatör yazdım:

  // 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); 
}; 
}; 

Bir dosya sistemi, ses, internet bağlantısı ve bir RGBA ekran çıkışı (şu anda sadece siyah beyaz) gibi şeyler eklemeyi düşünüyordum. Ama bu ne kadar uygun olur, gerçekten?

Çünkü yapmayı düşündüğüm tamamen sıfırdan başlamak . Bununla demek istediğim, kendi makine kodumu oluşturmak, sonra C benzeri bir dile doğru çalışmak ve aslında çalışma programları ve şeyler oluşturmak.


11
Tamamen uygulanabilir. bellard.org/jslinux
Dünya Mühendisi

4
Sadece gidin ve ne kadar uzağa gittiğinizi görün. Nihai hedefinizde başarısız olsanız bile, tonlarca öğreneceğinizden eminim ve bu ana motivasyonunuz gibi görünüyor.
James

2
Dizeleri kullanmayın, javascript 32 bit tam sayıları ve bitsel işlemleri destekler
Esailija

Sayı tek gerçek "kötü" kısım IMO'sudur.
Erik Reppen

Ayrıca, bu bana sormak istiyorum. Dinamik olarak yorumlanan herhangi bir dilin dil ile makine dili arasında hiç katmanı yoktu mı?
Erik Reppen

Yanıtlar:


2

Kesinlikle yapabilirsin. İşletim sisteminizin önyükleme yükleyicisi gibi belirli bileşenlerini uygulamanız ve daha düşük bir dilde kesintiler yapmanız gerekir.

Yönetilen Kod üzerinde çalışan bir işletim sisteminin nasıl geliştirileceği konusunda Microsoft'un Tekillik İşletim Sistemi tarafından benimsenen yaklaşıma bir göz atın .

Tabii ki, bellek yönetimini JavaScript'e bağlamanız gerekmiyor, JavaScript'e bellek yönetimi için bir API ekleyebilirsiniz. JavaScript için bir derleyici yazmayı veya sanal bir makine yazmayı seçebilirsiniz.

Tekillik kaynak koduna sahiptir, böylece Microsoft'un aldığı tasarım kararlarına bakarak değerli bilgiler edinebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.