Exemple #1
0
        /// <summary>
        /// Reads a line in a .text segment of a program, and adds any found symbols to the
        /// symbol table.
        /// </summary>
        /// <param name="asmLine">The line of assembly code to parse.</param>
        /// <param name="symbolList">The list of symbols that will be added to.</param>
        /// <param name="alignment">Unused. Alignment is always on word boundaries in the text segment.</param>
        public void ParseSymbolsInLine(LineData asmLine, SymbolTable symbolList, int alignment)
        {
            string[] tokens = asmLine.Text.Split(' ');
            // a label should end with a ':' character.
            // this is OK if there's trash and no real assembly at this point,
            // as the second pass code generator will flag it.
            // we're just here to get symbols and addresses.
            if (ParserCommon.ContainsLabel(tokens[0]))
            {
                string labelName = ParserCommon.ExtractLabel(tokens[0]);
                var    label     = new Symbol(labelName, SegmentType.Text, m_CurrTextAddress);
                label.Size = sizeof(int);
                symbolList.AddSymbol(label);

                // determine if there are any instructions on this line.
                string[] subTokens = tokens[0].Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

                // if we have more than one subtoken, then there is more than just a label on this line.
                // increment the number of words in the segment (since we're assuming whatever is on the right-hand side
                // is an instruction) by however many bytes the instruction is
                if (subTokens.Length > 1)
                {
                    ParseUnlabeledLine(asmLine);
                }
            }

            // if this doesn't have a label, and is not empty or a comment,
            // then this is an instruction. increment the counter.
            else
            {
                ParseUnlabeledLine(asmLine);
            }
        }
Exemple #2
0
        /// <summary>
        /// Reads a denoted .data segment line of an assembly program for symbols
        /// </summary>
        /// <param name="reader">The reader used to read the file.</param>
        /// <param name="symbolList">The list of symbols that will be added to.</param>
        /// <param name="startingLine">The line that the .data segment starts on. Will be incremented</param>
        public void ParseSymbolsInLine(LineData asmLine, SymbolTable symbolList, int alignment)
        {
            string[] tokens      = asmLine.Text.Split(' ', '\t');
            string[] fixedTokens = ParserCommon.GetTrimmedTokenArray(tokens).ToArray();

            // a label should end with a ':' character and should be the first token.
            if (ParserCommon.ContainsLabel(fixedTokens[0]))
            {
                ParseLabeledLine(symbolList, asmLine, fixedTokens, alignment);
            }

            // if this doesn't have a label, and is not empty or a comment,
            // then this is a data element.
            else
            {
                // try to make sure this isn't garbage.
                // this will return false if no data was parsed,
                if (!ParseUnlabeledLine(asmLine, fixedTokens, alignment))
                {
                    throw new AssemblyException(asmLine.LineNum, "Expected size declaration, received \"" + asmLine.Text + '\"');
                }
            }
        }
        /// <summary>
        /// Generates the byte representation of an instruction from a line of assembly code.
        /// </summary>
        /// <param name="asmLine">The line to parse.</param>
        /// <param name="objFile">The object file that will be written to.</param>
        /// <param name="currAlignment">The current specified alignment of the file.</param>
        public void GenerateCodeForSegment(string fileName, LineData asmLine, BasicObjectFile objFile, int currAlignment)
        {
            string[] tokens               = asmLine.Text.Split(' ', '\t');
            string[] fixedTokens          = ParserCommon.GetTrimmedTokenArray(tokens).ToArray();
            bool     foundDataDeclaration = false;
            int      dataDeclarationIdx   = 0;

            for (int i = 0; i < fixedTokens.Length && !foundDataDeclaration; ++i)
            {
                if (ParserCommon.IsDataDeclaration(fixedTokens[i]))
                {
                    foundDataDeclaration = true;
                    dataDeclarationIdx   = i;
                }
            }

            // we found a data declaration; make sure that there's at least one value following it.
            if (foundDataDeclaration)
            {
                if (dataDeclarationIdx + 1 < fixedTokens.Length)
                {
                    // if it is a trivial type, use our precomputed map to get the size.
                    if (ParserCommon.IsTrivialDataType(fixedTokens[dataDeclarationIdx]))
                    {
                        // determine before writing the next data element if we need to add padding.
                        int paddingSize = ParserCommon.GetNumPaddingBytes(m_NumBytesLaidOut, currAlignment);
                        int dataSize    = ParserCommon.DetermineTrivialDataSize(fixedTokens[dataDeclarationIdx]);
                        int numElements = ParserCommon.GetArraySize(asmLine.Text, fixedTokens[dataDeclarationIdx]);

                        if (dataSize > paddingSize)
                        {
                            // add as much padding as we need to reach the next alignment boundary.
                            for (int i = 0; i < paddingSize; ++i)
                            {
                                objFile.AddDataElement((byte)0);
                                m_NumBytesLaidOut += 1;
                            }
                        }

                        int totalReservedSize = dataSize * numElements;

                        m_NumBytesLaidOut += totalReservedSize;

                        AddTrivialDataElementsToFile(objFile, dataSize, asmLine.Text, fixedTokens[dataDeclarationIdx]);
                    }

                    // see if we can figure out the string length
                    else if (ParserCommon.IsStringDeclaration(fixedTokens[dataDeclarationIdx]))
                    {
                        int paddingSize = ParserCommon.GetNumPaddingBytes(m_NumBytesLaidOut, currAlignment);

                        // if this is a string declaration, then get the original string data
                        string dataStr  = ParserCommon.GetStringData(asmLine.Text);
                        int    dataSize = ParserCommon.DetermineNonTrivialDataLength(fixedTokens[dataDeclarationIdx], dataStr);

                        if (dataSize > paddingSize)
                        {
                            // add as much padding as we need to reach the next alignment boundary.
                            for (int i = 0; i < paddingSize; ++i)
                            {
                                objFile.AddDataElement((byte)0);
                                m_NumBytesLaidOut += 1;
                            }
                        }

                        // add the string data to the object file.
                        AddNonTrivialDataElementToObjectFile(objFile, fixedTokens[dataDeclarationIdx], dataStr);
                        m_NumBytesLaidOut += dataSize;
                    }

                    // otherwise, this must be a .space declaration. just get the size following it.
                    else
                    {
                        int dataSize    = ParserCommon.DetermineNonTrivialDataLength(fixedTokens[dataDeclarationIdx], fixedTokens[dataDeclarationIdx + 1]);
                        int paddingSize = ParserCommon.GetNumPaddingBytes(dataSize, currAlignment);

                        // fill the space and padding with zeroes.
                        for (int i = 0; i < dataSize + paddingSize; ++i)
                        {
                            objFile.AddDataElement((byte)0);
                        }

                        // we expect one token after this word.
                        // otherwise, it may be garbage that we should detect.
                        if (fixedTokens.Length > dataDeclarationIdx + 2)
                        {
                            throw new AssemblyException(asmLine.LineNum, "Unknown token \"" + fixedTokens[dataDeclarationIdx + 2] + "\" found.");
                        }
                    }
                }
                else
                {
                    throw new AssemblyException(asmLine.LineNum, "Expected data value after token " + fixedTokens[dataDeclarationIdx]);
                }
            }

            // check to see if this is just a label.
            // otherwise, it is probably garbage that we should throw.
            else if (!ParserCommon.ContainsLabel(asmLine.Text))
            {
                throw new AssemblyException(asmLine.LineNum, "Unable to ascertain data type from line " + asmLine.Text);
            }
        }