예제 #1
0
 public StartForm()
 {
     InitializeComponent();
     CenterToScreen();
     Assembler assembler = new Assembler();
 }
예제 #2
0
 private void btnLoadFile_Click(object sender, EventArgs e)
 {
     Assembler.filePath = Assembler.loadFile();
 }
예제 #3
0
        public static void assemble()
        {
            List <List <String> > asmMatrix    = Assembler.parseFile(filePath);
            List <List <String> > binaryMatrix = new List <List <string> >();

            List <List <string> > tagsMatrix = new List <List <string> >();

            List <int>    immValuesI = new List <int>();
            List <string> immValuesV = new List <string>();

            for (int j = 0; j < asmMatrix.Count(); j++)
            {
                for (int i = 0; i < asmMatrix[j].Count(); i++)
                {
                    asmMatrix[j][i] = asmMatrix[j][i].ToUpper();
                }
            }

            foreach (var line in asmMatrix)
            {
                List <String> row = new List <string>();

                foreach (var s in line)
                {
                    string temp = null;
                    temp = String.Copy(s);
                    row.Add(temp);
                }
                binaryMatrix.Add(row);
            }

            for (int i = 0; i < asmMatrix.Count; i++)
            {
                string instructionName = asmMatrix[i][0];
                if (instructions.ContainsKey(instructionName))
                {
                    binaryMatrix[i][0] = instructions[instructionName];

                    switch (asmMatrix[i].Count())
                    {
                    case 3:
                        // if the instruction has 2 operands
                        var firstOperand = asmMatrix[i][1];

                        //we get the address mode of the operand
                        binaryMatrix[i].Insert(1, getAdressingMode(firstOperand));

                        switch (binaryMatrix[i][1])
                        {
                        case "10":
                            //indirect
                            char[] delimiters = { '(', ')', 'R' };
                            var    reg        = asmMatrix[i][1].Split(delimiters);
                            if (!checkCorrectRegisterNumber(reg[2], i))
                            {
                                binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg[2]), 2);
                                if (binaryMatrix[i][2].Length < 4)
                                {
                                    // 'binary' value must be represented on 4 bits
                                    binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                }
                            }
                            break;

                        case "11":
                            //indexed
                            char[] delimiters1 = { '(', ')', 'R' };
                            var    reg1        = asmMatrix[i][1].Split(delimiters1);

                            //reg[2] we have the register NO.
                            if (!checkCorrectRegisterNumber(reg1[2], i))
                            {
                                binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg1[2]), 2);

                                // 'binary' value must be represented on 4 bits
                                if (binaryMatrix[i][2].Length < 4)
                                {
                                    binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                }
                                string con = "";
                                if (reg1[0] != "")
                                {
                                    //const value in front of (
                                    con = System.Convert.ToString(Convert.ToInt32(reg1[0]), 2);
                                }
                                else
                                {
                                    //const value after )
                                    con = System.Convert.ToString(Convert.ToInt32(reg1[reg1.Length - 1]), 2);
                                }
                                if (con.Length < 16)
                                {
                                    // constant value must be represented on 16 bits
                                    con = con.PadLeft(16, '0');
                                }
                                immValuesI.Add(i + 1);
                                immValuesV.Add(con);
                            }

                            break;

                        case "00":
                            //error: first operand must not be a imm value
                            string       errText = "First operand must not be a imm value (line: " + (i + 1) + " )";
                            DialogResult result  = MessageBox.Show(errText, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            if (result == DialogResult.OK)
                            {
                                Application.Restart();
                                hasApplicationRestarted = true;
                            }
                            break;

                        case "01":
                            //direct
                            var reg2 = asmMatrix[i][1].Split('R');
                            if (!checkCorrectRegisterNumber(reg2[1], i))
                            {
                                binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg2[1]), 2);
                                if (binaryMatrix[i][2].Length < 4)
                                {
                                    // 'binary' value must be represented on 4 bits
                                    binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                }
                            }
                            break;
                        }

                        var secondOperand = asmMatrix[i][2];

                        //we get the address mode of the operand
                        binaryMatrix[i].Insert(3, getAdressingMode(secondOperand));

                        switch (binaryMatrix[i][3])
                        {
                        case "10":
                            //indirect
                            char[] delimiters = { '(', ')', 'R' };
                            var    reg        = secondOperand.Split(delimiters);
                            if (!checkCorrectRegisterNumber(reg[2], i))
                            {
                                binaryMatrix[i][4] = System.Convert.ToString(Convert.ToInt32(reg[2]), 2);
                                if (binaryMatrix[i][4].Length < 4)
                                {
                                    // 'binary' value must be represented on 4 bits
                                    binaryMatrix[i][4] = binaryMatrix[i][4].PadLeft(4, '0');
                                }
                            }
                            break;

                        case "11":
                            //indexed
                            char[] delimiters1 = { '(', ')', 'R' };
                            var    reg1        = secondOperand.Split(delimiters1);

                            //reg[2] we have the register NO.
                            if (!checkCorrectRegisterNumber(reg1[2], i))
                            {
                                binaryMatrix[i][4] = System.Convert.ToString(Convert.ToInt32(reg1[2]), 2);

                                // 'binary' value must be represented on 4 bits
                                if (binaryMatrix[i][4].Length < 4)
                                {
                                    binaryMatrix[i][4] = binaryMatrix[i][4].PadLeft(4, '0');
                                }
                                string con1 = "";
                                if (reg1[0] != "")
                                {
                                    //const value in front of (
                                    con1 = System.Convert.ToString(Convert.ToInt32(reg1[0]), 2);
                                }
                                else
                                {
                                    //const value after )
                                    con1 = System.Convert.ToString(Convert.ToInt32(reg1[reg1.Length - 1]), 2);
                                }
                                if (con1.Length < 16)
                                {
                                    // constant value must be represented on 16 bits
                                    con1 = con1.PadLeft(16, '0');
                                }
                                immValuesI.Add(i + 1);
                                immValuesV.Add(con1);
                            }

                            break;

                        case "01":
                            //direct
                            var reg2 = secondOperand.Split('R');
                            if (!checkCorrectRegisterNumber(reg2[1], i))
                            {
                                binaryMatrix[i][4] = System.Convert.ToString(Convert.ToInt32(reg2[1]), 2);
                                if (binaryMatrix[i][4].Length < 4)
                                {
                                    binaryMatrix[i][4] = binaryMatrix[i][4].PadLeft(4, '0');
                                }
                            }
                            break;

                        case "00":
                            //second operand can be a constant value
                            //those bits can have any value since the adressing mode is an immediate one
                            binaryMatrix[i][4] = "0000";

                            string con = asmMatrix[i][2];
                            con = System.Convert.ToString(Convert.ToInt32(asmMatrix[i][2]), 2);
                            if (con.Length < 16)
                            {
                                // constant value must be represented on 16 bits
                                con = con.PadLeft(16, '0');
                            }

                            immValuesI.Add(i + 1);
                            immValuesV.Add(con);
                            break;
                        }
                        break;


                    case 2:

                        if (binaryMatrix[i][0].Length == 10)     //instructions that do not permit a imm value as operand
                        {
                            if (asmMatrix[i][0] != "JMP" && asmMatrix[i][0] != "CALL")
                            {
                                string operand = asmMatrix[i][1];
                                binaryMatrix[i].Insert(1, getAdressingMode(operand));

                                switch (binaryMatrix[i][1])
                                {
                                case "10":
                                    //indirect
                                    char[] delimiters = { '(', ')', 'R' };
                                    var    reg        = asmMatrix[i][1].Split(delimiters);
                                    if (!checkCorrectRegisterNumber(reg[2], i))
                                    {
                                        binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg[2]), 2);
                                        if (binaryMatrix[i][2].Length < 4)
                                        {
                                            // 'binary' value must be represented on 4 bits
                                            binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                        }
                                    }

                                    break;

                                case "11":

                                    //indexed
                                    string       errText = "Operand's addressing mode must not be indexed (line: " + (i + 1) + " )";
                                    DialogResult result  = MessageBox.Show(errText, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                                    if (result == DialogResult.OK)
                                    {
                                        Application.Restart();
                                        hasApplicationRestarted = true;
                                    }
                                    break;

                                case "01":
                                    //direct
                                    var reg1 = asmMatrix[i][1].Split('R');
                                    if (!checkCorrectRegisterNumber(reg1[1], i))
                                    {
                                        binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg1[1]), 2);
                                        if (binaryMatrix[i][2].Length < 4)
                                        {
                                            // 'binary' value must be represented on 4 bits
                                            binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                        }
                                    }
                                    break;

                                case "00":
                                    //error: operand must not be a imm value
                                    string       errText1 = "Operand must not be a imm value (line: " + (i + 1) + " )";
                                    DialogResult result1  = MessageBox.Show(errText1, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                                    if (result1 == DialogResult.OK)
                                    {
                                        Application.Restart();
                                        hasApplicationRestarted = true;
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                //the instruction is a CALL or a JMP
                                if (asmMatrix[i][0] == "JMP")
                                {
                                    string operand = asmMatrix[i][1];
                                    if (operand.Contains("("))
                                    {
                                        if (operand[0].Equals('(') && operand[operand.Length - 1].Equals(')'))
                                        {
                                            //indirect
                                            binaryMatrix[i].Insert(1, "10");

                                            char[] delimiters = { '(', ')', 'R' };
                                            var    reg        = operand.Split(delimiters);
                                            if (!checkCorrectRegisterNumber(reg[2], i))
                                            {
                                                binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg[2]), 2);
                                                if (binaryMatrix[i][2].Length < 4)
                                                {
                                                    // 'binary' value must be represented on 4 bits
                                                    binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                                }
                                            }
                                        }
                                        else
                                        {
                                            //indexed
                                            binaryMatrix[i].Insert(1, "11");

                                            char[] delimiters = { '(', ')', 'R' };
                                            var    reg        = operand.Split(delimiters);

                                            //reg[2] we have the register NO.
                                            if (!checkCorrectRegisterNumber(reg[2], i))
                                            {
                                                binaryMatrix[i][2] = System.Convert.ToString(Convert.ToInt32(reg[2]), 2);
                                                if (binaryMatrix[i][2].Length < 4)
                                                {
                                                    // 'binary' value must be represented on 4 bits
                                                    binaryMatrix[i][2] = binaryMatrix[i][2].PadLeft(4, '0');
                                                }
                                                string con = "";
                                                if (reg[0] != "")
                                                {
                                                    //const value in front of (
                                                    con = System.Convert.ToString(Convert.ToInt32(reg[0]), 2);
                                                }
                                                else
                                                {
                                                    //const value after )
                                                    con = System.Convert.ToString(Convert.ToInt32(reg[reg.Length - 1]), 2);
                                                }
                                                if (con.Length < 16)
                                                {
                                                    // constant value must be represented on 16 bits
                                                    con = con.PadLeft(16, '0');
                                                }
                                                immValuesI.Add(i + 1);
                                                immValuesV.Add(con);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //tags
                                        immValuesI.Add(i + 1);
                                        immValuesV.Add("constant value");
                                    }


                                    if (asmMatrix[i][0] == "CALL")
                                    {
                                        ;
                                    }
                                }
                            }
                        }

                        break;

                    case 1:
                        break;
                    }
                }
            }

            putConstantValues(binaryMatrix, immValuesV, immValuesI);
            tagsMatrix = findTags(binaryMatrix);

            //here we handle tags for branches and jumps

            for (int i = 0; i < binaryMatrix.Count(); i++)
            {
                if (binaryMatrix[i][0].Length > 8 && binaryMatrix[i][0].Length != 16)
                {
                    for (int j = 0; j < tagsMatrix.Count(); j++)
                    {
                        if (binaryMatrix[i][1] == tagsMatrix[j][0])
                        {
                            binaryMatrix[i][1] = "000000";
                            List <string> x = new List <string>();
                            x.Add(System.Convert.ToString(Convert.ToInt32(tagsMatrix[j][1]), 2).PadLeft(16, '0'));
                            binaryMatrix[i + 1] = x;
                        }
                    }
                }
                else if (binaryMatrix[i][0].Length == 8) //branches
                {
                    for (int k = 0; k < tagsMatrix.Count(); k++)
                    {
                        if (binaryMatrix[i][1] == tagsMatrix[k][0])
                        {
                            int    currentPC = i * 2;
                            int    lineOfTag = Int32.Parse(tagsMatrix[k][1]);
                            int    codif     = currentPC - lineOfTag;
                            string value     = null;
                            if (codif >= 0)
                            {
                                value = System.Convert.ToString(codif, 2).PadLeft(8, '0');
                            }
                            else
                            {
                                value = System.Convert.ToString(codif, 2);
                                if (value.Length > 8)
                                {
                                    value = value.Substring(value.Length - 8, 8);
                                }
                            }

                            binaryMatrix[i][1] = value;
                        }
                        else //branch with imm value
                        {
                        };
                    }
                }
            }

            if (!hasApplicationRestarted)
            {
                //generate and write.bin file
                List <string> linesToWrite = matrixToList(binaryMatrix);
                binaryFileWriter(linesToWrite, filePath);
                MessageBox.Show("Assembly done!");
            }
            else
            {
            };
        }