用C#实现一个简易的Mips汇编器

用C#实现一个简易的Mips汇编器,咳咳,该汇编器不支持外部文件引入,目前只支持数据段(.data)、代码段(.text),话不多说,我们直接看怎么实现。

另外,本汇编器为本人大二下的MipsCpu实验一部分,实为不易,转载还望标明出处。

Mips31个寄存器

在这里插入图片描述
本图为Mars汇编软件截图。

Mips指令入门

在这里插入图片描述
图为哈尔滨工业大学(深圳)MipsCpu实现指令截图。

Mips内存安排

在这里插入图片描述
代码段首地址从0x00400000开始;
数据段首地址从0x10010000开始;

C#实现

项目结构

在这里插入图片描述

Token.cs,定义Mips汇编语言的Token

using System;
using System.Collections.Generic;
using System.Text;

namespace AssembleHelper
{
    //变量
    public class Var
    {
        public string Name { get; set; }
        public string InitVal { get; set; }
        public BaseType Type { get; set; }
        public string Addr { get; set; }
    }
    //标号
    public class Label
    {
        public string Name { get; set; }
        public string Address { get; set; }
    }
	//数据类型
    public enum BaseType
    {
        WORD,
        BYTE
    }

    //Mips Instrcution
    public enum Instrcution
    {
        //RType
        add,
        addu,
        sub,
        subu,
        and,
        or,
        xor,
        nor,
        slt,
        sltu,
        sll,
        srl,
        sra,
        sllv,
        srlv,
        srav,
        jr,
        //IType
        addi,
        addiu,
        andi,
        ori,
        xori,
        sltiu,
        lui,
        lw,
        sw,
        beq,
        bne,
        bgtz,
        //JType
        j,
        jal
    }
	//寄存器
    public enum Register
    {
        zero,
        at,
        v0,
        v1,
        a0,
        a1,
        a2,
        a3,
        t0,
        t1,
        t2,
        t3,
        t4,
        t5,
        t6,
        t7,
        s0,
        s1,
        s2,
        s3,
        s4,
        s5,
        s6,
        s7,
        t8,
        t9,
        k0,
        k1,
        gp,
        sp,
        fp,
        ra
    }
}

ConvertHelper.cs,作为进制转换类,帮助我们处理进制转换

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AssembleHelper
{
    public static class ConvertHelper
    {
        /// <summary>
        /// 把十进制、八进制、十六进制数转化为length位的16进制数
        /// </summary>
        /// <param name="integer">字符型整数</param>
        /// <param name="length">Hex位数</param>
        /// <returns></returns>
        public static string ConvertIntegerToHex(string integer, int length = 8)
        {
            //补码表示
            string hexCode = "";
            bool isSigned = integer[0] == '-';
            if (isSigned)
            {
                integer = integer.Substring(1);
            }
            //16进制
            if ((integer.ToLower()).StartsWith("0x"))
            {
                string binaryCode = "";
                string negBinaryCode = "";
                string hex = integer.Substring(2);
                for (int i = hex.Length - 1; i >= 0; i--)
                {
                    binaryCode = binaryCode.Insert(0, HexToBinary(hex[i]));
                }
                while (binaryCode.Length <= length * 4 - 1)
                {
                    binaryCode = binaryCode.Insert(0, "0");
                }
                if (isSigned)
                {
                    negBinaryCode = ReverseBinary(binaryCode);
                    hex = BinaryToHex(negBinaryCode);
                }
                else
                {
                    hex = BinaryToHex(binaryCode);
                }
                hexCode = hex;
            }
            //8进制 0 1 2 3 4 5 6 7
            else if ((integer.ToLower()).Length > 1 && (integer.ToLower()).StartsWith("0"))
            {
                string binaryCode = "";
                string negBinaryCode = "";
                string oct = integer.Substring(1);
                string hex = "";
                for (int i = oct.Length - 1; i >= 0; i--)
                {
                    binaryCode = binaryCode.Insert(0, OctToBinary(oct[i]));
                }
                while (binaryCode.Length <= length * 4 - 1)
                {
                    binaryCode = binaryCode.Insert(0, "0");
                }
                if (isSigned)
                {
                    negBinaryCode = ReverseBinary(binaryCode);
                    hex = BinaryToHex(negBinaryCode);
                }
                else
                {
                    hex = BinaryToHex(binaryCode);
                }
                hexCode = hex;
            }
            //10进制
            else
            {
                string binaryCode = "";
                string negBinaryCode = "";
                string dec = integer;
                string hex = "";
                long d = Convert.ToInt64(dec);
                //binaryCode =  DecToBinary(dec);
                binaryCode = Convert.ToString(d, 2);

                while (binaryCode.Length <= length * 4 - 1)
                {
                    binaryCode = binaryCode.Insert(0, "0");
                }
                if (isSigned)
                {
                    negBinaryCode = ReverseBinary(binaryCode);
                    hex = BinaryToHex(negBinaryCode);
                }
                else
                {
                    hex = BinaryToHex(binaryCode);
                }
                hexCode = hex;
            }
            return hexCode;
        }
		//补码
        public static string ReverseBinary(string binaryCode)
        {
            List<char> negBinaryCode = binaryCode.ToList();
            int index = -1;
            string hex = "";
            for (int i = negBinaryCode.Count - 1; i >= 0; i--)
            {
                if (negBinaryCode[i] == '1')
                {
                    index = i;
                    break;
                }
            }
            for (int i = index - 1; i >= 0; i--)
            {
                if (binaryCode[i] == '1')
                {

                    negBinaryCode[i] = '0';
                }
                else
                {
                    negBinaryCode[i] = '1';
                }
            }
            for (int i = negBinaryCode.Count - 1; i >= 0; i--)
            {
                hex = hex.Insert(0, negBinaryCode[i].ToString());
            }
            return hex;
        }
		//16进制Char字符转化为二进制
        public static string HexToBinary(char hex)
        {
            string binary = "";
            switch (hex)
            {
                case '0':
                    binary = "0000";
                    break;
                case '1':
                    binary = "0001";
                    break;
                case '2':
                    binary = "0010";
                    break;
                case '3':
                    binary = "0011";
                    break;
                case '4':
                    binary = "0100";
                    break;
                case '5':
                    binary = "0101";
                    break;
                case '6':
                    binary = "0110";
                    break;
                case '7':
                    binary = "0111";
                    break;
                case '8':
                    binary = "1000";
                    break;
                case '9':
                    binary = "1001";
                    break;
                case 'a':
                    binary = "1010";
                    break;
                case 'b':
                    binary = "1011";
                    break;
                case 'c':
                    binary = "1100";
                    break;
                case 'd':
                    binary = "1101";
                    break;
                case 'e':
                    binary = "1110";
                    break;
                case 'f':
                    binary = "1111";
                    break;
                case 'A':
                    binary = "1010";
                    break;
                case 'B':
                    binary = "1011";
                    break;
                case 'C':
                    binary = "1100";
                    break;
                case 'D':
                    binary = "1101";
                    break;
                case 'E':
                    binary = "1110";
                    break;
                case 'F':
                    binary = "1111";
                    break;
                default:
                    break;
            }
            return binary;
        }
        //8进制转化为2进制,输入为一个Char
        public static string OctToBinary(char oct)
        {
            string binary = "";
            switch (oct)
            {
                case '0':
                    binary = "000";
                    break;
                case '1':
                    binary = "001";
                    break;
                case '2':
                    binary = "010";
                    break;
                case '3':
                    binary = "011";
                    break;
                case '4':
                    binary = "100";
                    break;
                case '5':
                    binary = "101";
                    break;
                case '6':
                    binary = "110";
                    break;
                case '7':
                    binary = "111";
                    break;
                default:
                    break;
            }
            return binary;
        }

        /// <summary>
        /// 32位binary2Hex
        /// </summary>
        /// <param name="binary"></param>
        /// <returns></returns>
        public static string BinaryToHex(string binary)
        {
            string hex = "";
            int i = binary.Length - 4;
            while (i >= 0)
            {
                switch (binary.Substring(i, 4))
                {
                    case "0000":
                        hex = hex.Insert(0, "0");
                        break;
                    case "0001":
                        hex = hex.Insert(0, "1");
                        break;
                    case "0010":
                        hex = hex.Insert(0, "2");
                        break;
                    case "0011":
                        hex = hex.Insert(0, "3");
                        break;
                    case "0100":
                        hex = hex.Insert(0, "4");
                        break;
                    case "0101":
                        hex = hex.Insert(0, "5");
                        break;
                    case "0110":
                        hex = hex.Insert(0, "6");
                        break;
                    case "0111":
                        hex = hex.Insert(0, "7");
                        break;
                    case "1000":
                        hex = hex.Insert(0, "8");
                        break;
                    case "1001":
                        hex = hex.Insert(0, "9");
                        break;
                    case "1010":
                        hex = hex.Insert(0, "a");
                        break;
                    case "1011":
                        hex = hex.Insert(0, "b");
                        break;
                    case "1100":
                        hex = hex.Insert(0, "c");
                        break;
                    case "1101":
                        hex = hex.Insert(0, "d");
                        break;
                    case "1110":
                        hex = hex.Insert(0, "e");
                        break;
                    case "1111":
                        hex = hex.Insert(0, "f");
                        break;
                    default:
                        break;
                }
                i -= 4;
            }
            return hex;
        }
    }
}

Scanner.cs,扫描器实现

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;

namespace AssembleHelper
{
    public class Scanner
    {
        StreamReader StreamReader;
        public string CurrentString;
        public string[] OpNums = new string[]{};
        public string OpType = "";
        public int innerLine = 0;       //忽略空格
        public int Line = 0;            //不忽略空格
        public bool IsData = true;

        public Scanner(string code, bool isData = true)
        {
            StreamReader = File.OpenText(code);
            IsData = isData;
        }

        public void ResetLine()
        {
            innerLine = 0;
            Line = 0;
        }


        public void ScanLine()
        {
            
            CurrentString = StreamReader.ReadLine();

            if (CurrentString == null)
            {
                return;
            }

            //删除空行
            CurrentString = CurrentString.Trim();
            while (CurrentString.Length == 0)
            {
                Line++;
                CurrentString = StreamReader.ReadLine();
                if (CurrentString == null)
                {
                    return;
                }
                CurrentString = CurrentString.Trim();
            }

            //删除整行注释
            while (CurrentString.Trim().StartsWith('#'))
            {
                CurrentString = StreamReader.ReadLine();
            }

            //删除空行
            CurrentString = CurrentString.Trim();
            while (CurrentString.Length == 0)
            {
                Line++;
                CurrentString = StreamReader.ReadLine();
                if (CurrentString == null)
                {
                    return;
                }
                CurrentString = CurrentString.Trim();
            }

            //扫描文本
            if (!IsData)
            {
                if (!CurrentString.Contains(":"))
                    innerLine++;        //是标号行数不变
            }
            //扫描数据
            Line++;

            //删除一行里面的注释
            List<char> currentStringList = CurrentString.ToList();
            int firstAnnotation = currentStringList.FindIndex(s => { return s == '#'; });
            if (firstAnnotation != -1)
            {
                CurrentString = CurrentString.Substring(0, firstAnnotation); //删除注释
            }

            Console.WriteLine(CurrentString + ": " + ConvertHelper.ConvertIntegerToHex((innerLine * 4 | 0x0040000).ToString()));
            
            try
            {
                int firstSpace = currentStringList.FindIndex(s =>
                {
                    return s == ' ';
                });
                string opType = CurrentString.Substring(0, firstSpace);
                string opNum = CurrentString.Substring(firstSpace).Trim();

                //切割
                string[] opNums = opNum.Split(",");
                for (int i = 0; i < opNums.Length; i++)
                {
                    opNums[i] = opNums[i].Trim();
                }
                OpNums = opNums;
                OpType = opType;

                if (!OpNums[1].Contains("$") && ((CurrentString.Contains("sw") || CurrentString.Contains("lw"))))
                {
                    innerLine++;    //拆成两行  
                }

                if ((opType.ToLower() == (Instrcution.andi).ToString() || (opType.ToLower() == (Instrcution.addi).ToString()
                    || (opType.ToLower() == (Instrcution.addiu).ToString() || (opType.ToLower() == (Instrcution.ori).ToString() ||
                    (opType.ToLower() == (Instrcution.sltiu).ToString()))))))
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                    //immHex > 0xFFFF;
                    // FFFF0000 <= immHex <= FFFFFFFF
                    // 00000000 <= immHex <= 0000EFFF
                    if ((immHex.CompareTo("FFFF0000") >= 0 && (immHex.CompareTo("FFFFFFFF") <= 0) ||
                        (immHex.CompareTo("00000000") >= 0 && (immHex.CompareTo("0000FFFF") <= 0))))
                    {
                        //合法
                    }
                    else
                    {
                        innerLine += 2; //拆成三行
                    }
                        
                }
            }
            catch(Exception ex)
            {

            }
            //Console.WriteLine(innerLine);
            
            
        }


    }
}

InsturctionTranslator.cs,指令翻译

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;

namespace AssembleHelper
{
    public class InstructionTranslator
    {
        Scanner Scanner;
        FileStream DataFileStream;      //数据段16进制码
        FileStream TextFileStream;      //代码段16进制码
        FileStream TextSegCodeStream;   //代码段代码
        Dictionary<string, Var> SymbolTable = new Dictionary<string, Var>();
        Dictionary<string, Label> LabelTable = new Dictionary<string, Label>();
        const string DataTxt = "G:\\ComputerHardWare\\AssembleHelper\\AssembleHelper\\data.txt";
        const string TextTxt = "G:\\ComputerHardWare\\AssembleHelper\\AssembleHelper\\text.txt";
        const string TextSegCode = "G:\\ComputerHardWare\\AssembleHelper\\AssembleHelper\\textSeg.txt";
        string Buffer = "";


        public InstructionTranslator(string code)
        {
            Scanner = new Scanner(code, true);
            DataFileStream = new FileStream(DataTxt, FileMode.Create, FileAccess.Write);//创建写入文件
            TextFileStream = new FileStream(TextTxt, FileMode.Create, FileAccess.Write);//创建写入文件
            TextSegCodeStream = new FileStream(TextSegCode, FileMode.Create, FileAccess.Write);//创建写入文件
        }

        public void Translate()
        {
            Scanner.ScanLine();
            Console.WriteLine("---data---");
            if (Scanner.CurrentString.Contains(".data"))
            {
                BuildSymbolTable();
            }
            Console.WriteLine("---label---");
            BuildLabelTable();
            Console.WriteLine("---Transdata---");
            TranslateData();
            Console.WriteLine("---Transtext---");
            TranslateText();
            
        }

        bool isByte = false;
        private void TranslateData()
        {
            using (StreamWriter sw = new StreamWriter(DataFileStream))
            {
                int currentAddr = 0; 
                foreach (KeyValuePair<string, Var> var in SymbolTable)
                {
                    if (isByte == false)
                    {
                        if (var.Value.Type == BaseType.BYTE)
                        {
                            var.Value.Addr = "0x" + Convert.ToString(currentAddr | 0x10010000, 16);
                            currentAddr += 1;
                            if (var.Value.InitVal != null)
                                Buffer = Buffer.Insert(0, var.Value.InitVal.Substring(var.Value.InitVal.Length - 2, 2));
                            isByte = true;
                        }
                        else
                        {
                            var.Value.Addr = "0x" + Convert.ToString(currentAddr | 0x10010000, 16);
                            currentAddr += 4;
                            sw.WriteLine(var.Value.InitVal);
                        }
                    }
                    else
                    {
                        if (var.Value.Type == BaseType.BYTE)
                        {
                            var.Value.Addr = "0x" + Convert.ToString(currentAddr | 0x10010000, 16);
                            currentAddr += 1;
                            if (var.Value.InitVal != null)
                                Buffer = Buffer.Insert(0, var.Value.InitVal.Substring(var.Value.InitVal.Length - 2, 2));
                        }
                        else
                        {
                            isByte = false;
                            //在这里先写Buffer的值 
                            if (Buffer != "")
                            {
                                string data = "";
                                while (Buffer.Length % 8 != 0)
                                {
                                    Buffer = Buffer.Insert(0, "0");
                                }
                                int i = Buffer.Length - 8;
                                while (i >= 0)
                                {
                                    data = Buffer.Substring(i, 8);
                                    sw.WriteLine(data);
                                    i -= 8;
                                }
                            }
                            var.Value.Addr = "0x" + Convert.ToString(currentAddr | 0x10010000, 16);
                            currentAddr += 4;
                            sw.WriteLine(var.Value.InitVal);
                            Buffer = "";
                        }
                    }
                }
            }
        }

        private void TranslateText()
        {
            using (StreamWriter sw = new StreamWriter(TextFileStream))
            {
                Scanner = new Scanner(TextSegCode, false);
                Scanner.ScanLine();
                while (true)
                {
                    //string[] instruction = Scanner.CurrentString.Split(",");
                    /*List<char> currentStringList = Scanner.CurrentString.ToList();
                    int firstSpace = currentStringList.FindIndex(s =>
                    {
                        return s == ' ';
                    });
                    string opType = Scanner.CurrentString.Substring(0, firstSpace);
                    string opNum = Scanner.CurrentString.Substring(firstSpace).Trim();

                    //切割
                    string[] opNums = opNum.Split(",");
                    for (int i = 0; i < opNums.Length; i++)
                    {
                        opNums[i] = opNums[i].Trim();
                    }*/
                    string opType = Scanner.OpType;
                    string[] opNums = Scanner.OpNums;
                    string hexCode = "";
                    //如果是sw,lw,而且尾巴是Ident的形式
                    if((opType.ToLower() == (Instrcution.sw).ToString() || opType.ToLower() == (Instrcution.lw).ToString())&&
                        SymbolTable.ContainsKey(opNums[1]))
                    {
                        //lui $1, 0x00001001
                        sw.WriteLine("3c011001");
                        opNums[1] = SymbolTable[opNums[1]].Addr + "($1)";
                    }
                    else if((opType.ToLower() == (Instrcution.andi).ToString()|| (opType.ToLower() == (Instrcution.addi).ToString() 
                        || (opType.ToLower() == (Instrcution.addiu).ToString() || (opType.ToLower() == (Instrcution.ori).ToString() ||
                        (opType.ToLower() == (Instrcution.sltiu).ToString()))))))
                    {
                        string originalOpType = opType;
                        string[] originalOpNums = opNums;
                        
                        string immHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                        if ((immHex.CompareTo("FFFF0000") >= 0 && (immHex.CompareTo("FFFFFFFF") <= 0) ||
                        (immHex.CompareTo("00000000") >= 0 && (immHex.CompareTo("0000FFFF") <= 0))))
                        {
                            //合法
                        }
                        else
                        { //lui $1, immHex.upper
                            opType = "lui";
                            opNums = new string[] { "$1", "0x" + immHex.Substring(0, 4) };
                            hexCode = TranslateSentence(opType, opNums);
                            sw.WriteLine(hexCode);

                            //ori $1, $1, immHex.low
                            opType = "ori";
                            opNums = new string[] { "$1", "$1", "0x" + immHex.Substring(4, 4) };
                            hexCode = TranslateSentence(opType, opNums);
                            sw.WriteLine(hexCode);

                            if (originalOpType.ToLower() == (Instrcution.andi).ToString())
                            {
                                opType = "and";
                            }
                            else if (originalOpType.ToLower() == (Instrcution.addi).ToString())
                            {
                                opType = "add";
                            }
                            else if (originalOpType.ToLower() == (Instrcution.addiu).ToString())
                            {
                                opType = "add";
                            }
                            else if (originalOpType.ToLower() == (Instrcution.ori).ToString())
                            {
                                opType = "or";
                            }
                            else if (originalOpType.ToLower() == (Instrcution.sltiu).ToString())
                            {
                                opType = "slt";
                            }
                            opNums = originalOpNums;
                            opNums[2] = "$1";

                        }
                        
                    }
                    
                    hexCode = TranslateSentence(opType, opNums);
                    sw.WriteLine(hexCode);

                    Scanner.ScanLine();
                    if (Scanner.CurrentString == null)
                    {
                        break;
                    }
                }
            }
        }


        private void BuildLabelTable()
        {
            using(StreamWriter sw = new StreamWriter(TextSegCodeStream))
            {
                //Scanner.ScanLine();
                if (Scanner.CurrentString.StartsWith(".text"))
                {
                    Scanner.ScanLine();
                }
                Scanner.IsData = false;
                while (true)
                {
                    if (Scanner.CurrentString.Contains(":"))
                    {
                        InsertLabel(Scanner.CurrentString);
                    }
                    else
                    {
                        sw.WriteLine(Scanner.CurrentString);
                    }
                    Scanner.ScanLine();
                    if (Scanner.CurrentString == null)
                    {
                        break;
                    }
                }
            }
            
        }

        private void InsertLabel(string currentString)
        {
            string[] cutSentence = currentString.Split(":");
            string labelName = cutSentence[0];
            int decAddr = (Scanner.innerLine + 1) * 4;
            decAddr |= 0x00400000;
            string labelAddr = ConvertHelper.ConvertIntegerToHex(decAddr.ToString());
            labelAddr = labelAddr.Insert(0, "0x");
            Label label = new Label
            {
                Name = labelName,
                Address = labelAddr  
            };
            LabelTable.Add(labelName, label);
        }

        private void BuildSymbolTable()
        {
            Scanner.ScanLine();
            while(true)
            {
                //Console.WriteLine(Scanner.CurrentString + " 去除了空格后行数:" + Scanner.innerLine + " 原本的行数:" + Scanner.Line);
                InsertVar(Scanner.CurrentString);
                Scanner.ScanLine();
                if (Scanner.CurrentString == null || Scanner.CurrentString.StartsWith(".text"))
                {
                    
                    break;
                }
            }
            
        }


        private void InsertVar(string currentString)
        {
            //awd:.word 12312
            //awd:.word 
            string[] varDecl = currentString.Split(":");
            string varName = varDecl[0];
            string[] initSentence = varDecl[1].Split(" ");
            bool isInit = initSentence.Length == 1 ? false : true;
            if (isInit)
            {
                Var var = new Var
                {
                    Name = varName,
                    InitVal = ConvertHelper.ConvertIntegerToHex(initSentence[1]),
                    Type = ConvertStringToType(initSentence[0]),
                };
                SymbolTable.Add(varName, var);
            }
            else
            {
                Var var = new Var
                {
                    Name = varName,
                    Type = ConvertStringToType(initSentence[0]),
                };
                SymbolTable.Add(varName, var);
            }
        }

        public void GetTable()
        {
            foreach (KeyValuePair<string, Var> var in SymbolTable)
            {
                Console.WriteLine("变量:{0}  .{1},初始值:{2},地址:{3}", var.Key, var.Value.Type.ToString(), var.Value.InitVal == "" ? "" : var.Value.InitVal, var.Value.Addr);
            }
            Console.WriteLine("---------------------------");
            foreach (KeyValuePair<string, Label> label in LabelTable)
            {
                Console.WriteLine("标号:{0} ,地址:{1}", label.Key, label.Value.Address);
            }
        }


        private BaseType ConvertStringToType(string s)
        {
            if ((s.ToLower()).Contains(".word"))
            {
                return BaseType.WORD;
            }
            else if((s.ToLower()).Contains(".byte"))
            {
                return BaseType.BYTE;
            }
            return BaseType.BYTE;
        }

        
        private string TranslateSentence(string opType, string[] opNums)
        {
            string hex = "";
            
            if (opType.ToLower() == (Instrcution.add).ToString())
            {
                string func = "100000";
                hex = BaseRTypeCodeTranslation(opNums,func);
            }
            else if(opType.ToLower() == (Instrcution.addu).ToString())
            {
                string func = "100001";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.sub).ToString())
            {
                string func = "100010";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.subu).ToString())
            {
                string func = "100011";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.and).ToString())
            {
                string func = "100100";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.or).ToString())
            {
                string func = "100101";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.xor).ToString())
            {
                string func = "100110";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.nor).ToString())
            {
                string func = "100111";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.slt).ToString())
            {
                string func = "101010";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.sltu).ToString())
            {
                string func = "101011";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.sll).ToString())
            {
                string rs = "00000";
                string op = "000000";
                string rt = TranslateRegisterToRegCode(opNums[1]);
                string rd = TranslateRegisterToRegCode(opNums[0]);
                string shamtHex = ConvertHelper.ConvertIntegerToHex( opNums[2]);
                string shamtBinary = "";
                string func = "000000";
                for(int i = shamtHex.Length - 1; i >= 0; i--)
                {
                    shamtBinary = shamtBinary.Insert(0, ConvertHelper.HexToBinary(shamtHex[i]));
                }
                hex = ConvertHelper.BinaryToHex(op + rs + rt + rd + shamtBinary.Substring(27) + func);
            }
            else if (opType.ToLower() == (Instrcution.srl).ToString())
            {
                string rs = "00000";
                string op = "000000";
                string rt = TranslateRegisterToRegCode(opNums[1]);
                string rd = TranslateRegisterToRegCode(opNums[0]);
                string shamtHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                string shamtBinary = "";
                string func = "000010";
                for (int i = shamtHex.Length - 1; i >= 0; i--)
                {
                    shamtBinary = shamtBinary.Insert(0, ConvertHelper.HexToBinary(shamtHex[i]));
                }
                hex = ConvertHelper.BinaryToHex(op + rs + rt + rd + shamtBinary.Substring(27) + func);
            }
            else if (opType.ToLower() == (Instrcution.sra).ToString())
            {
                string rs = "00000";
                string op = "000000";
                string rt = TranslateRegisterToRegCode(opNums[1]);
                string rd = TranslateRegisterToRegCode(opNums[0]);
                string shamtHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                string shamtBinary = "";
                string func = "000011";
                for (int i = shamtHex.Length - 1; i >= 0; i--)
                {
                    shamtBinary = shamtBinary.Insert(0, ConvertHelper.HexToBinary(shamtHex[i]));
                }
                hex = ConvertHelper.BinaryToHex(op + rs + rt + rd + shamtBinary.Substring(27) + func);
            }
            else if (opType.ToLower() == (Instrcution.sllv).ToString())
            {
                string func = "000100";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.srlv).ToString())
            {
                string func = "000110";
                hex = BaseRTypeCodeTranslation(opNums, func);

            }
            else if (opType.ToLower() == (Instrcution.srav).ToString())
            {
                string func = "000111";
                hex = BaseRTypeCodeTranslation(opNums, func);
            }
            else if (opType.ToLower() == (Instrcution.jr).ToString())
            {
                string func = "001000";
                string op = "000000";
                string rt = "00000";
                string rd = rt;
                string shamt = rt;
                string rs = TranslateReg(opNums[0]);
                hex = ConvertHelper.BinaryToHex(op + rs + rt + rd + shamt + func);
            }
            else if (opType.ToLower() == (Instrcution.addi).ToString())
            {
                string op = "001000";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.addiu).ToString())
            {
                string op = "001001";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.andi).ToString())
            {
                string op = "001100";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.ori).ToString())
            {
                string op = "001101";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.xori).ToString())
            {
                string op = "001101";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.sltiu).ToString())
            {
                string op = "001110";
                hex = BaseITypeCodeTranslation(opNums, op);
            }
            else if (opType.ToLower() == (Instrcution.lui).ToString())
            {
                string op = "001111";
                string rs = "00000";
                string rt = TranslateReg(opNums[0]);
                string immHex = ConvertHelper.ConvertIntegerToHex(opNums[1]);
                string immBinary = "";
                for (int i = immHex.Length - 1; i >= 0; i--)
                {
                    if (immBinary.Length == 16)
                    {
                        break;
                    }
                    else
                    {
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }
                }
                hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
            }
            else if (opType.ToLower() == (Instrcution.lw).ToString())
            {
                string op = "100011";
                string rt = TranslateReg(opNums[0]);
                string[] offsets = opNums[1].Split("(");
                for(int i = 0; i < offsets.Length; i++)
                {
                    offsets[i] = offsets[i].Trim();
                }

                string immHex = ConvertHelper.ConvertIntegerToHex(offsets[0]);
                string immBinary = "";
                for(int i  =  immHex.Length - 1; i >= 0; i--)
                {
                    if(immBinary.Length == 16)
                    {
                        break;
                    }
                    else
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                }

                string[] reg2 = offsets[1].Split(")");
                string rs = TranslateReg(reg2[0]);
                hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
            }
            else if (opType.ToLower() == (Instrcution.sw).ToString())
            {
                string op = "101011";
                string rt = TranslateReg(opNums[0]);
                string[] offsets = opNums[1].Split("(");
                for (int i = 0; i < offsets.Length; i++)
                {
                    offsets[i] = offsets[i].Trim();
                }

                string immHex = ConvertHelper.ConvertIntegerToHex(offsets[0]);
                string immBinary = "";
                for (int i = immHex.Length - 1; i >= 0; i--)
                {
                    if (immBinary.Length == 16)
                    {
                        break;
                    }
                    else
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                }

                string[] reg2 = offsets[1].Split(")");
                string rs = TranslateReg(reg2[0]);
                hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
            }
            else if (opType.ToLower() == (Instrcution.beq).ToString())
            {
                string op = "000100";
                string rs = TranslateReg(opNums[0]);
                string rt = TranslateReg(opNums[1]);
                if(!LabelTable.ContainsKey(opNums[2]))
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        if (immBinary.Length == 16)
                        {
                            break;
                        }
                        else
                        {
                            immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                        }
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
                }
                else
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(LabelTable[opNums[2]].Address);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }

                    //下一条指令
                    string nextAddrHex = ConvertHelper.ConvertIntegerToHex(((Scanner.innerLine) * 4 | 0x00400000 ).ToString());
                    string nextAddrBinary = "";
                    for(int i = nextAddrHex.Length - 1; i >= 0; i--)
                    {
                        nextAddrBinary = nextAddrBinary.Insert(0, ConvertHelper.HexToBinary(nextAddrHex[i]));
                    }

                    //immBinary - currentAddrBinary  
                    nextAddrBinary = ConvertHelper.ReverseBinary(nextAddrBinary);
                    long immByte = Convert.ToInt64(immBinary, 2);
                    long currentByte = Convert.ToInt64(nextAddrBinary, 2);
                    long actualAddr = (immByte + currentByte) / 4;

                    string actualAddrHex= ConvertHelper.ConvertIntegerToHex(actualAddr.ToString());
                    string actualAddrBinary = "";
                    for (int i = actualAddrHex.Length - 1; i >= 0; i--)
                    {
                        if(actualAddrBinary.Length == 16)
                        {
                            break;
                        }
                        else
                            actualAddrBinary = actualAddrBinary.Insert(0, ConvertHelper.HexToBinary(actualAddrHex[i]));
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + actualAddrBinary);
                }
               
            }
            else if (opType.ToLower() == (Instrcution.bne).ToString())
            {
                string op = "000101";
                string rs = TranslateReg(opNums[0]);
                string rt = TranslateReg(opNums[1]);
                if (!LabelTable.ContainsKey(opNums[2]))
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        if (immBinary.Length == 16)
                        {
                            break;
                        }
                        else
                        {
                            immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                        }
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
                }
                else
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(LabelTable[opNums[2]].Address);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }

                    string currentAddrHex = ConvertHelper.ConvertIntegerToHex((((Scanner.innerLine - 1) * 4) | 0x00400000).ToString());
                    string currentAddrBinary = "";
                    for (int i = currentAddrHex.Length - 1; i >= 0; i--)
                    {
                        currentAddrBinary = currentAddrBinary.Insert(0, ConvertHelper.HexToBinary(currentAddrHex[i]));
                    }

                    //currentAddrBinary - immBinary
                    immBinary = ConvertHelper.ReverseBinary(immBinary);
                    byte immByte = Convert.ToByte(immBinary, 2);
                    byte currentByte = Convert.ToByte(currentAddrBinary, 2);
                    int actualAddr = immByte + currentByte;

                    string actualAddrHex = ConvertHelper.ConvertIntegerToHex(actualAddr.ToString());
                    string actualAddrBinary = "";
                    for (int i = actualAddrHex.Length - 1; i >= 0; i--)
                    {
                        if (actualAddrBinary.Length == 16)
                        {
                            break;
                        }
                        else
                            actualAddrBinary = actualAddrBinary.Insert(0, ConvertHelper.HexToBinary(actualAddrHex[i]));
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + actualAddrBinary);

                }
            }
            else if (opType.ToLower() == (Instrcution.bgtz).ToString())
            {
                string op = "000111";
                string rs = TranslateReg(opNums[0]);
                string rt = "00000";
                if(!LabelTable.ContainsKey(opNums[1]))
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[1]);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        if (immBinary.Length == 16)
                        {
                            break;
                        }
                        else
                        {
                            immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                        }
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
                }
                else
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(LabelTable[opNums[1]].Address);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        immBinary =  immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }

                    string currentAddrHex = ConvertHelper.ConvertIntegerToHex((((Scanner.innerLine - 1) * 4) | 0x00400000).ToString());
                    string currentAddrBinary = "";
                    for (int i = currentAddrHex.Length - 1; i >= 0; i--)
                    {
                        currentAddrBinary =  currentAddrBinary.Insert(0, ConvertHelper.HexToBinary(currentAddrHex[i]));
                    }

                    //currentAddrBinary - immBinary
                    immBinary = ConvertHelper.ReverseBinary(immBinary);
                    byte immByte = Convert.ToByte(immBinary, 2);
                    byte currentByte = Convert.ToByte(currentAddrBinary, 2);
                    int actualAddr = immByte + currentByte;

                    string actualAddrHex = ConvertHelper.ConvertIntegerToHex(actualAddr.ToString());
                    string actualAddrBinary = "";
                    for (int i = actualAddrHex.Length - 1; i >= 0; i--)
                    {
                        if (actualAddrBinary.Length == 16)
                        {
                            break;
                        }
                        else
                            actualAddrBinary.Insert(0, ConvertHelper.HexToBinary(actualAddrHex[i]));
                    }
                    hex = ConvertHelper.BinaryToHex(op + rs + rt + actualAddrBinary);
                }
                
            }
            else if (opType.ToLower() == (Instrcution.j).ToString())
            {
                string op = "000010";
                if (!LabelTable.ContainsKey(opNums[0]))
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[0]);
                    string immBinary = "";

                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        if (immBinary.Length == 26)
                        {
                            break;
                        }
                        else
                        {
                            immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                        }
                    }
                    hex = ConvertHelper.BinaryToHex(op + immBinary);
                }
                else
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(LabelTable[opNums[0]].Address);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }
                    hex = ConvertHelper.BinaryToHex(op + immBinary.Substring(4,26));

                }
                    
            }
            else if (opType.ToLower() == (Instrcution.jal).ToString())
            {
                string op = "000011";
                if (!LabelTable.ContainsKey(opNums[0]))
                {

                    string immHex = ConvertHelper.ConvertIntegerToHex(opNums[0]);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        if (immBinary.Length == 26)
                        {
                            break;
                        }
                        else
                        {
                            immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                        }
                    }
                    hex = ConvertHelper.BinaryToHex(op + immBinary);
                }
                else
                {
                    string immHex = ConvertHelper.ConvertIntegerToHex(LabelTable[opNums[0]].Address);
                    string immBinary = "";
                    for (int i = immHex.Length - 1; i >= 0; i--)
                    {
                        immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                    }
                    hex = ConvertHelper.BinaryToHex(op + immBinary.Substring(4, 26));
                }
            }

            return hex;
        }

        private string BaseITypeCodeTranslation(string[] opNums, string op)
        {
            string hex = "";
            string rs = TranslateReg(opNums[1]);
            string rt = TranslateReg(opNums[0]);
            string immHex = ConvertHelper.ConvertIntegerToHex(opNums[2]);
            string immBinary = "";
            for(int i = immHex.Length - 1; i >= 0; i--)
            {
                if(immBinary.Length == 16)
                {
                    break;
                }
                else
                {
                    immBinary = immBinary.Insert(0, ConvertHelper.HexToBinary(immHex[i]));
                }
            }
            hex = ConvertHelper.BinaryToHex(op + rs + rt + immBinary);
            return hex;
        }

        private string BaseRTypeCodeTranslation(string[] opNums, string func)
        {
            string hex = "";
            string rs = TranslateReg(opNums[1]);
            string rt = TranslateReg(opNums[2]);
            string rd = TranslateReg(opNums[0]);
            string op = "000000";
            string shamt = "00000";
            hex = ConvertHelper.BinaryToHex(op + rs + rt + rd + shamt + func);
            return hex;
        }
        #region 翻译Reg
        private string TranslateReg(string reg)
        {
            string regCode = "";
            //$xn
            string register = reg.Substring(1);
            //xn
            regCode = TranslateRegisterToRegCode(register);
            return regCode;
        }

        private string TranslateRegisterToRegCode(string register)
        {
            string regCode = "";
            if (register.Contains(Register.zero.ToString()) || register == "0")
            {
                regCode = "00000";
            }
            else if (register.Contains(Register.at.ToString()) || register == "1")
            {
                regCode = "00001";
            }
            else if (register.Contains(Register.v0.ToString()) || register == "2")
            {
                regCode = "00010";
            }
            else if (register.Contains(Register.v1.ToString()) || register == "3")
            {
                regCode = "00011";
            }
            else if (register.Contains(Register.a0.ToString()) || register == "4")
            {
                regCode = "00100";
            }
            else if (register.Contains(Register.a1.ToString()) || register == "5")
            {
                regCode = "00101";
            }
            else if (register.Contains(Register.a2.ToString()) || register == "6")
            {
                regCode = "00110";
            }
            else if (register.Contains(Register.a3.ToString()) || register == "7")
            {
                regCode = "00111";
            }
            else if (register.Contains(Register.t0.ToString())|| register == "8")
            {
                regCode = "01000";
            }
            else if (register.Contains(Register.t1.ToString()) || register == "9")
            {
                regCode = "01001";
            }
            else if (register.Contains(Register.t2.ToString()) || register == "10")
            {
                regCode = "01010";
            }
            else if (register.Contains(Register.t3.ToString()) || register == "11")
            {
                regCode = "01011";
            }
            else if (register.Contains(Register.t4.ToString()) || register == "12")
            {
                regCode = "01100";
            }
            else if (register.Contains(Register.t5.ToString()) || register == "13")
            {
                regCode = "01101";
            }
            else if (register.Contains(Register.t6.ToString()) || register == "14")
            {
                regCode = "01110";
            }
            else if (register.Contains(Register.t7.ToString()) || register == "15")
            {
                regCode = "01111";
            }
            else if (register.Contains(Register.s0.ToString()) || register == "16")
            {
                regCode = "10000";
            }
            else if (register.Contains(Register.s1.ToString()) || register == "17")
            {
                regCode = "10001";
            }
            else if (register.Contains(Register.s2.ToString()) || register == "18")
            {
                regCode = "10010";
            }
            else if (register.Contains(Register.s3.ToString()) || register == "19")
            {
                regCode = "10011";
            }
            else if (register.Contains(Register.s4.ToString()) || register == "20")
            {
                regCode = "10100";
            }
            else if (register.Contains(Register.s5.ToString()) || register == "21")
            {
                regCode = "10101";
            }
            else if (register.Contains(Register.s6.ToString()) || register == "22")
            {
                regCode = "10110";
            }
            else if (register.Contains(Register.s7.ToString()) || register == "23")
            {
                regCode = "10111";
            }
            else if (register.Contains(Register.t8.ToString()) || register == "24")
            {
                regCode = "11000";
            }
            else if (register.Contains(Register.t9.ToString()) || register == "25")
            {
                regCode = "11001";
            }
            else if (register.Contains(Register.k0.ToString()) || register == "26")
            {
                regCode = "11010";
            }
            else if (register.Contains(Register.k1.ToString()) || register == "27")
            {
                regCode = "11011";
            }
            else if (register.Contains(Register.gp.ToString()) || register == "28")
            {
                regCode = "11100";
            }
            else if (register.Contains(Register.sp.ToString()) || register == "29")
            {
                regCode = "11101";
            }
            else if (register.Contains(Register.fp.ToString()) || register == "30")
            {
                regCode = "11110";
            }
            else if (register.Contains(Register.ra.ToString()) || register == "31")
            {
                regCode = "11111";
            }
            return regCode;
        }
        #endregion
    }
}

Program.cs

using System;
namespace AssembleHelper
{
    class Program
    {
        static void Main(string[] args)
        {
            InstructionTranslator instructionTranslator = new InstructionTranslator("G:\\ComputerHardWare\\AssembleHelper\\AssembleHelper\\source_code.txt");
            instructionTranslator.Translate();
            instructionTranslator.GetTable();
        }
    }
}

source_code.txt 测试

#版本2:新增时控函数,由变量timer决定每个灯泡亮的间隔
#版本3:增加处理函数,函数中调用其他函数需要保存$ra寄存器,为了方便,就不在函数中调用函数了
.data
	mode:.word 0x00000000#点灯模式,21~23位开关作为模式选择开关
	count:.word 0x00000834 #每个模式运行2100次,2100次过后可以切换为当前选定模式
	timer:.word 0x00000001 #实际赫兹为500hz,半秒对应于运行250次;事实上,并不准确,运行速度较慢,可以进一步改小timer;经实验,当timer=1时,效果最佳
	mode1:.word 0x00000020
	mode2:.word 0x00000040
	mode3:.word 0x00000080
	mode1_init_rstate:.word 0x00000FFF	#模式1,初始右灯状态
	mode1_init_lstate:.word 0xFFF00000	#模式1, 初始左灯状态
	mode2_init_light_state:.word 0xFF000000	#模式2,初始亮灯状态
	mode2_init_dark_state:.word 0x00FFFFFF	# 模式2,初始暗灯状态
	mode3_input_X:.word 0x00000000	#模式3,低16位输入的X,
	temp:.word 0x00000000
	t1:.word 0x00000000
	t2:.word 0x00000000
.text
lui   $1,0xFFFF           #0  let $28 = 0xFFFF0000 as the upper 16 bits of the port address
ori   $28,$1,0xF000      #4 $28 port is the upper 20 bits of the system's I/O address

main_loop:	
	lw   $1,0xC72($28)          #8 读高8位开关数据	t1=xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_sw23,sw22,sw21,x_xxxx
	andi  $t1, $1, 0x000000E0	 #c  屏蔽其他位	t1=0000_0000_0000_0000_0000_0000_sw23,sw22,sw21,0_0000
	sw $t1, mode			#14 保存选项			mode = t1
	
	lw $t2, mode1			#1c
	lw $t3, mode2			#24
	lw $t4, mode3			#2c
	
	beq $t1,$t2,mode_mode1	#30 if mode == mode1, go mode_mode1
	beq $t1,$t3,mode_mode2	#34 if mode == mode2, go mode_mode2
	beq $t1,$t4,mode_mode3	#38 if mode == mode3, go mode_mode3
	
	j main_loop				#3c else keep loop

#=================================mode1=============================	
mode_mode1:			
mode1_init:
	lw $s3, count	#40 初始化s3 为counter,2100次后结束mode1
	lw $s4, mode1_init_rstate #初始化s4右灯泡状态
	lw $s5, mode1_init_lstate  #初始化s5左灯泡状态
	addi $s6, $0, 0x00FFF000 # 初始化s6为右全亮状态
	addi $s7, $0, 0x000FFF00 # 初始化s7为左全亮状态
	
mode1_start_light:
	beq $s3,$0,mode1_end #2100次结束,if counter == 0, go mode1_end
	beq $s4, $s6, mode1_start_dark  #说明灯已全亮,该熄灭了
	
mode1_light:
	sll $s4,$s4,1	#右灯泡向左移,亮一个
	srl $s5,$s5,1	#左灯泡向右移,亮一个
	jal model1_processor	#call model1_processor,调用模式1处理函数
	jal start_timer #call timer,调用计时函数
	addi $s3,$s3,-1	#counter = counter  -1
	j mode1_start_light
	
	
mode1_start_dark:
	beq $s3,$0,mode1_end #2100次结束,if counter == 0, go mode1_end
	addi $t6, $0, 0x00000FFF
	beq $s4, $t6,  mode1_start_light # t4 = t6 = 0x00000FFF说明灯已全暗,该亮了
		
mode1_dark:
	srl $s4,$s4,1	#右灯泡向右移,灭一个
	sll $s5,$s5,1	#左灯泡向左移,灭一个
	jal model1_processor #call model1_processor,调用模式1处理函数
	jal start_timer #call timer,调用计时函数
	addi $s3,$s3,-1	#counter = counter  -1
	j mode1_start_dark
	
mode1_end:
	j main_loop

#mode1处理函数
model1_processor:
	and $t1,$s4, $s6 # t1=s4 & s6         00XXX000
	and $t2,$s5, $s7 # t2 = s5 & s7       000XXX00
	
	srl $t1,$t1, 12	#t1 = t1<<12 00000XXX
	sll $t2, $t2, 4 #t2 = t2>>4	00XXX000
	sw $t1, t1
	sw $t2, t2
	
	add $t3,$t1,$t2 #t3 = 00XXXXXX,为当前左右灯泡状态
	sw $t3, temp
	
	andi $t1, $t3,  0x0000FFFF	#t1为右LED状态
	sw $t1,0xC60($28) 	#亮右灯
	
	andi $t1, $t3,  0x00FF0000	#t1为左LED状态
	srl $t1,$t1,16				#t1 = 000000XX
	sw $t1, 0xC62($28)	#亮左灯
	
	jr $ra
#=================================mode2=============================

mode_mode2:
mode2_init:
	lw $s1, mode2_init_light_state #s1 = 0xFF000000,初始亮灯状态
	lw $s2, mode2_init_dark_state # s2 = 0x00FFFFFF,初始熄灯状态
	lw $s3, count	#初始化s3 为counter,2100次后结束mode2
	addi $s4,$0, 0xFFFFFFFF	#s4 = 0xFFFFFFFF,灯全亮状态
	addi $s5,$0, 0x00000000 	#s5 = 0x00000000,灯全灭状态

mode2_light:
	lw $s2, mode2_init_dark_state #重置熄灯状态
	beq $s3, $0, mode2_end #if counter = 0, go end
	beq $s1, $s4, mode2_dark # 如果全亮,则说明该熄灯了,go mode2_dark
	
	sra $s1,$s1,1	#0xFFXXXXXX
	andi $t1, $s1, 0x00FFFFFF #t1 = s1 &  0x00FFFFFF 	0x00XXXXXX
	
	jal mode2_processor	#call mode2_processor,调用模式2处理函数
	jal start_timer #call timer,调用计时函数
	addi $s3,$s3,-1	#counter = counter  -1
	j mode2_light
	
mode2_dark:
	lw $s1, mode2_init_light_state #重置灯亮状态
	beq $s3, $0, mode2_end #if counter = 0, go end
	beq $s2, $s5, mode2_light # 如果全灭,则说明该亮灯了,go mode2_light
	
	srl $s2,$s2,1	#0x00XXXXXX
	andi $t1, $s2, 0x00FFFFFF #t1 = s1 &  0x00FFFFFF 	0x00XXXXXX
	
	jal mode2_processor	#call ,调用模式2处理函数
	jal start_timer #call timer,调用计时函数
	addi $s3,$s3,-1	#counter = counter  -1
	j mode2_dark
	
mode2_end:
	j main_loop
	
mode2_processor:
	andi $t2, $t1, 0x0000FFFF
	sw $t2,0xC60($28) 	#亮右灯
	
	andi $t3, $t1,0x00FF0000	# t3 = 0x00XX0000
	srl $t3,$t3,16	# t3 = 0x000000XX
	sw $t3,0xC62($28)		# 亮左灯
	jr $ra
#=================================mode3=============================
mode_mode3:
mode3_init:
	lw  $t1,0xC70($28)          # 读低16位开关数据, t1 = 0x0000XXXX  
	sw $t1, mode3_input_X	#初始化X = $0000XXXX
	lw $s3, count	#初始化s3 为counter,2100次后结束mode3
	lw $s1, mode3_input_X # s1 = X
	
mode3_start:
	beq $s3, $0, mode3_end #if counter = 0, go end
	
	andi $t1, $s1, 0x0000FFFF
	sw $t1,0xC60($28) 	#亮右灯
	
	andi $t2, $s1,0x00FF0000	# t3 = 0x00XX0000
	srl $t2,$t2,16	# t3 = 0x000000XX
	sw $t2,0xC62($28)		# 亮左灯
	
	andi $t1, $s1, 0x00000001 #t1 = s1[0]
	sll $t1, $t1, 23	#t1 = b 0000_0000_s1[0]000_0000_0000_0000_0000_0000
	srl $s1, $s1, 1 #s1 = b 0000_0000_0xxx_xxxx_xxxx_xxxx_xxxx_xxxx
	add $s1, $s1, $t1# s1 = b 0000_0000_s1[0]xxx_xxxx_xxxx_xxxx_xxxx_xxxx
	sw $s1, temp
	
	jal start_timer #call timer,调用计时函数
	addi $s3,$s3,-1	#counter = counter - 1 
	j mode3_start
	
mode3_end:
	j main_loop

#计时器函数
start_timer:
timer_init:
	lw $t8, timer
timer_start:
	beq $t8, $0, timer_end
	addi $t8, $t8,-1
	j timer_start
timer_end:
	jr $ra

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值