/// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += "flw ";
            if (inst.Parameters.Count() != 3)
            {
                throw new ArgumentException("Floating point I instruction expected 3 arguments, received " + inst.Parameters.Count());
            }

            string rd  = ReverseRegisterMap.GetStringifiedFloatingPtRegisterValue(inst.Parameters.ElementAt(0));
            string rs1 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(1));

            int offset = inst.Parameters.ElementAt(2);

            retStr += rd + ", " + offset + "(" + rs1 + ")";

            return(retStr);
        }
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name + ' ';

            if (inst.Parameters.Count() != 2)
            {
                throw new ArgumentException("U-type instruction expected 2 arguments, received " + inst.Parameters.Count());
            }

            string rd        = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(0));
            int    immediate = inst.Parameters.ElementAt(1);

            retStr += rd + ", 0x" + immediate.ToString("X2");

            return(retStr);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name + ' ';
            if (inst.Parameters.Count() != 3)
            {
                throw new ArgumentException("sb instruction expected 3 arguments, received " + inst.Parameters.Count());
            }

            string rs1 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(0));
            string rs2 = ReverseRegisterMap.GetStringifiedRegisterValue(inst.Parameters.ElementAt(1));

            retStr += rs1 + ", " + rs2 + ", ";

            int offset = inst.Parameters.ElementAt(2);

            int address = currPgrmCtr + offset;

            // see if there's a symbol mapped to it.
            if (symTable.ContainsSymbol(address))
            {
                Symbol sym = symTable.GetSymbol(address);
                retStr += sym.LabelName;
            }
            else
            {
                retStr += "0x" + address.ToString("X2");
            }

            return(retStr);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Formats and stringifies an instruction as well as its parameters.
        /// </summary>
        /// <param name="currPgrmCtr">The value that the program counter would theoretically be at
        /// upon encountering this instruction.</param>
        /// <param name="inst">The disassembled instruction to stringify.</param>
        /// <param name="symTable">A reverse symbol table used to map addresses back to label names.</param>
        /// <returns>A string representing the instruction and its parameters that can be written to a text file.</returns>
        public string GetFormattedInstruction(int currPgrmCtr, DisassembledInstruction inst, ReverseSymbolTable symTable)
        {
            string retStr = string.Empty;

            // first, see if the program counter has a symbol mapped to it.
            if (symTable.ContainsSymbol(currPgrmCtr))
            {
                Symbol sym = symTable.GetSymbol(currPgrmCtr);
                retStr += sym.LabelName + ":\t\t";
            }
            else
            {
                retStr += "\t\t\t";
            }

            retStr += m_Name;
            return(retStr);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Writes out the .data segment of the file.
        /// </summary>
        /// <param name="writer">The StreamWriter to use while writing the file.</param>
        /// <param name="symTable">The reverse lookup symbol table to use for symbol mapping.</param>
        /// <param name="dataSegment">The accessor to the file's data segment.</param>
        private void GenerateDataSegment(StreamWriter writer, ReverseSymbolTable symTable, DataSegmentAccessor dataSegment)
        {
            int currAlignment = CommonConstants.DEFAULT_ALIGNMENT;

            writer.WriteLine(".data");
            int processedByteCount = 0;
            int currAddress        = dataSegment.BaseRuntimeDataAddress;

            foreach (MetadataElement elem in m_File.Metadata)
            {
                // don't do any processing if we're looking at padding bytes.
                if (processedByteCount % currAlignment == 0)
                {
                    // first, see if there's a label associated with the data element.
                    if (symTable.ContainsSymbol(currAddress))
                    {
                        // if so, write it out.
                        Symbol sym = symTable.GetSymbol(currAddress);
                        writer.Write(sym.LabelName);
                        writer.Write(":\t\t");
                    }
                    else
                    {
                        writer.Write("\t\t\t");
                    }

                    // determine what to write out.
                    switch (elem.TypeCode)
                    {
                    case ObjectTypeCode.Byte:
                    {
                        writer.Write(".byte ");
                        byte value = dataSegment.ReadUnsignedByte(currAddress);
                        writer.WriteLine(value);
                        processedByteCount += sizeof(byte);
                        break;
                    }

                    case ObjectTypeCode.Half:
                    {
                        writer.Write(".half ");
                        short value = dataSegment.ReadShort(currAddress);
                        writer.WriteLine(value);
                        processedByteCount += sizeof(short);
                        break;
                    }

                    case ObjectTypeCode.Word:
                    {
                        writer.Write(".word ");
                        int value = dataSegment.ReadWord(currAddress);
                        writer.WriteLine(value);
                        processedByteCount += sizeof(int);
                        break;
                    }

                    case ObjectTypeCode.Dword:
                    {
                        writer.Write(".dword ");
                        long value = dataSegment.ReadLong(currAddress);
                        writer.WriteLine(value);
                        processedByteCount += sizeof(long);
                        break;
                    }

                    case ObjectTypeCode.String:
                    {
                        writer.Write(".asciiz ");
                        string value          = dataSegment.ReadString(currAddress);
                        string processedValue = ProcessString(value);
                        writer.WriteLine(processedValue);
                        processedByteCount += value.Length;

                        // account for a null terminating byte here.
                        ++processedByteCount;
                        break;
                    }

                    case ObjectTypeCode.AlignmentChange:
                    {
                        currAlignment = elem.Alignment;
                        break;
                    }
                    }
                }
                else
                {
                    // otherwise, assume we're at a padding byte and don't print it.
                    ++processedByteCount;
                }

                currAddress += elem.Size;
            }
        }
        /// <summary>
        /// Writes out the .data segment of the file.
        /// </summary>
        /// <param name="writer">The StreamWriter to use while writing the file.</param>
        /// <param name="symTable">The reverse lookup symbol table to use for symbol mapping.</param>
        /// <param name="dataSegment">The accessor to the file's data segment.</param>
        private void GenerateDataSegment(StreamWriter writer, ReverseSymbolTable symTable, DataSegmentAccessor dataSegment)
        {
            int currAddress = dataSegment.BaseRuntimeDataAddress;

            writer.WriteLine(".data");

            int endAddress = currAddress + dataSegment.SegmentSize;

            // get the address of each symbol in the .data segment, and sort
            // them in ascending order.
            var symbolAddresses = symTable.AllSymbols
                                  .SelectIf(sym => sym.Address,
                                            sym => dataSegment.BaseRuntimeDataAddress <= sym.Address && sym.Address < endAddress)
                                  .OrderBy(num => num);

            while (currAddress < endAddress)
            {
                // are there any addresses in our symbol table that fall between our current
                // address and the next address we'll examine?
                if (symbolAddresses.Any(address => currAddress <= address && address < (currAddress + sizeof(int))))
                {
                    // okay, slightly narrow our screen
                    if (symbolAddresses.Any(address => currAddress <= address && address < (currAddress + sizeof(short))))
                    {
                        if (symTable.ContainsSymbol(currAddress))
                        {
                            Symbol sym = symTable.GetSymbol(currAddress);
                            writer.Write(sym.LabelName);
                            writer.Write(":\t\t");
                            switch (sym.Size)
                            {
                            case sizeof(byte):
                            {
                                writer.Write(".byte ");
                                sbyte value = dataSegment.ReadSignedByte(currAddress);
                                writer.WriteLine(value.ToString(StringifyAsHexadecimal(value, 2)));
                                currAddress += sizeof(byte);
                                break;
                            }

                            case sizeof(short):
                            {
                                writer.Write(".half ");
                                short value = dataSegment.ReadShort(currAddress);
                                writer.WriteLine(StringifyAsHexadecimal(value, 4));
                                currAddress += sizeof(short);
                                break;
                            }

                            case sizeof(int):
                            {
                                writer.Write(".word ");
                                int value = dataSegment.ReadWord(currAddress);
                                writer.WriteLine(StringifyAsHexadecimal(value, 8));
                                currAddress += sizeof(int);
                                break;
                            }

                            case sizeof(long):
                            {
                                writer.Write(".dword ");
                                long value = dataSegment.ReadLong(currAddress);
                                writer.WriteLine(StringifyAsHexadecimal(value, 16));
                                currAddress += sizeof(int);
                                break;
                            }

                            default:
                            {
                                // just be cheap for now and write out numeric values
                                // (even though this could be an ascii string, in theory).
                                // maybe at some point the assembler will be nice enough
                                // to force strings into .strtable section for smarter
                                // heuristics, but we don't want to force that upon the user
                                // unless the user specifically directs us so.
                                // (or maybe we do?). if someone thinks of a better
                                // algorithm that can be done in the disassembler, I'm
                                // al ears.
                                int numWordsInSize = sym.Size / sizeof(int);
                                int numLeftover    = sym.Size % sizeof(int);

                                int numHalfWordsInRemainingBytes = numLeftover / sizeof(int);
                                int numRemainingBytes            = numLeftover % sizeof(int);


                                for (int i = 0; i < numWordsInSize; ++i)
                                {
                                    writer.Write(".word ");
                                    int value = dataSegment.ReadWord(currAddress);
                                    writer.WriteLine(StringifyAsHexadecimal(value, 8));
                                    currAddress += sizeof(int);
                                }

                                for (int i = 0; i < numHalfWordsInRemainingBytes; ++i)
                                {
                                    writer.Write(".half ");
                                    short value = dataSegment.ReadShort(currAddress);
                                    writer.WriteLine(StringifyAsHexadecimal(value, 4));
                                    currAddress += sizeof(short);
                                }

                                for (int i = 0; i < numRemainingBytes; ++i)
                                {
                                    writer.Write(".byte ");
                                    sbyte value = dataSegment.ReadSignedByte(currAddress);
                                    writer.WriteLine(StringifyAsHexadecimal(value, 2));
                                    currAddress += sizeof(byte);
                                }

                                break;
                            }

                                // todo: determine if we need to perform alignment
                                // detection (as in theory at this point we could judge
                                // if the new byte offset is on a word boundary).
                            }
                        }
                        else
                        {
                            writer.Write(".byte ");
                            sbyte value = dataSegment.ReadSignedByte(currAddress);
                            writer.WriteLine(value.ToString(StringifyAsHexadecimal(value, 2)));
                            currAddress += sizeof(byte);
                            break;
                        }
                    }
                    else
                    {
                        writer.Write(".half ");
                        short value = dataSegment.ReadShort(currAddress);
                        writer.WriteLine(StringifyAsHexadecimal(value, 4));
                        currAddress += sizeof(short);
                    }
                }
                else
                {
                    writer.Write(".word ");
                    int value = dataSegment.ReadWord(currAddress);
                    writer.WriteLine(StringifyAsHexadecimal(value, 8));
                    currAddress += sizeof(int);
                }
            }
        }