예제 #1
0
        // IGenerator
        public void OutputDataOp(int offset)
        {
            Formatter formatter = SourceFormatter;

            byte[]   data = Project.FileData;
            Anattrib attr = Project.GetAnattrib(offset);

            string labelStr = string.Empty;

            if (attr.Symbol != null)
            {
                labelStr = Localizer.ConvLabel(attr.Symbol.Label);
            }

            string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]);
            string opcodeStr, operandStr;

            FormatDescriptor dfd = attr.DataDescriptor;

            Debug.Assert(dfd != null);
            int length = dfd.Length;

            Debug.Assert(length > 0);

            bool multiLine = false;

            switch (dfd.FormatType)
            {
            case FormatDescriptor.Type.Default:
                if (length != 1)
                {
                    Debug.Assert(false);
                    length = 1;
                }
                opcodeStr = sDataOpNames.DefineData1;
                int operand = RawData.GetWord(data, offset, length, false);
                operandStr = formatter.FormatHexValue(operand, length * 2);
                break;

            case FormatDescriptor.Type.NumericLE:
                opcodeStr = sDataOpNames.GetDefineData(length);
                operand   = RawData.GetWord(data, offset, length, false);
                UpdateCharacterEncoding(dfd);
                operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
                                                           Localizer.LabelMap, dfd, operand, length,
                                                           PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                break;

            case FormatDescriptor.Type.NumericBE:
                opcodeStr = sDataOpNames.GetDefineBigData(length);
                if ((string.IsNullOrEmpty(opcodeStr)))
                {
                    // Nothing defined, output as comma-separated single-byte values.
                    GenerateShortSequence(offset, length, out opcodeStr, out operandStr);
                }
                else
                {
                    UpdateCharacterEncoding(dfd);
                    operand    = RawData.GetWord(data, offset, length, true);
                    operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
                                                               Localizer.LabelMap, dfd, operand, length,
                                                               PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                }
                break;

            case FormatDescriptor.Type.Fill:
                opcodeStr  = sDataOpNames.Fill;
                operandStr = length + "," + formatter.FormatHexValue(data[offset], 2);
                break;

            case FormatDescriptor.Type.Dense:
                multiLine = true;
                opcodeStr = operandStr = null;
                OutputDenseHex(offset, length, labelStr, commentStr);
                break;

            case FormatDescriptor.Type.Uninit:
            // TODO: use the special syntax for uninit byte/word/dword if possible.
            case FormatDescriptor.Type.Junk:
                bool canAlign = (dfd.FormatType == FormatDescriptor.Type.Junk);
                int  fillVal  = Helper.CheckRangeHoldsSingleValue(data, offset, length);
                if (canAlign && fillVal >= 0 &&
                    GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap))
                {
                    // .align <expression>[, <fill>]
                    opcodeStr = sDataOpNames.Align;
                    int alignVal = 1 << FormatDescriptor.AlignmentToPower(dfd.FormatSubType);
                    operandStr = alignVal.ToString() +
                                 "," + formatter.FormatHexValue(fillVal, 2);
                }
                else if (fillVal >= 0 && (length > 1 || fillVal == 0x00))
                {
                    // If multi-byte, or single byte and zero, treat same as Fill.
                    opcodeStr  = sDataOpNames.Fill;
                    operandStr = length + "," + formatter.FormatHexValue(fillVal, 2);
                }
                else
                {
                    // treat same as Dense
                    multiLine = true;
                    opcodeStr = operandStr = null;
                    OutputDenseHex(offset, length, labelStr, commentStr);
                }
                break;

            case FormatDescriptor.Type.StringGeneric:
            case FormatDescriptor.Type.StringReverse:
            case FormatDescriptor.Type.StringNullTerm:
            case FormatDescriptor.Type.StringL8:
            case FormatDescriptor.Type.StringL16:
            case FormatDescriptor.Type.StringDci:
                multiLine = true;
                opcodeStr = operandStr = null;
                OutputString(offset, labelStr, commentStr);
                break;

            default:
                opcodeStr  = "???";
                operandStr = "***";
                break;
            }

            if (!multiLine)
            {
                opcodeStr = formatter.FormatPseudoOp(opcodeStr);
                OutputLine(labelStr, opcodeStr, operandStr, commentStr);
            }
        }