博客
关于我
用C#实现一个简易的Mips汇编器
阅读量:453 次
发布时间:2019-03-05

本文共 47485 字,大约阅读时间需要 158 分钟。

用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    {           ///         /// 把十进制、八进制、十六进制数转化为length位的16进制数        ///         /// 字符型整数        /// Hex位数        /// 
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
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; } ///
/// 32位binary2Hex /// ///
///
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
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
SymbolTable = new Dictionary
(); Dictionary
LabelTable = new Dictionary
(); 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
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
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
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
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.textlui   $1,0xFFFF           #0  let $28 = 0xFFFF0000 as the upper 16 bits of the port addressori   $28,$1,0xF000      #4 $28 port is the upper 20 bits of the system's I/O addressmain_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, timertimer_start:	beq $t8, $0, timer_end	addi $t8, $t8,-1	j timer_starttimer_end:	jr $ra
你可能感兴趣的文章
myeclipse的新建severlet不见解决方法
查看>>
MyEclipse设置当前行背景颜色、选中单词前景色、背景色
查看>>
Mtab书签导航程序 LinkStore/getIcon SQL注入漏洞复现
查看>>
myeclipse配置springmvc教程
查看>>
MyEclipse配置SVN
查看>>
MTCNN 人脸检测
查看>>
MyEcplise中SpringBoot怎样定制启动banner?
查看>>
MyPython
查看>>
MTD技术介绍
查看>>
MySQL
查看>>
MySQL
查看>>
mysql
查看>>
MTK Android 如何获取系统权限
查看>>
MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况、SQL 优化
查看>>
MySQL - ERROR 1406
查看>>
mysql - 视图
查看>>
MySQL - 解读MySQL事务与锁机制
查看>>
MTTR、MTBF、MTTF的大白话理解
查看>>
mt_rand
查看>>
mysql -存储过程
查看>>