/// <summary> /// Checks to see if the junk alignment directive is compatible with the actual /// address. This is used to screen out alignment values that no longer match up /// with the actual addresses. /// </summary> /// <param name="offset">File offset of directive.</param> /// <param name="dfd">Format descriptor.</param> /// <param name="addrMap">Offset to address map.</param> /// <returns>True if the .junk alignment directive is correct, false if it's /// incorrect or not an alignment sub-type (e.g. None).</returns> public static bool CheckJunkAlign(int offset, FormatDescriptor dfd, CommonUtil.AddressMap addrMap) { Debug.Assert(dfd.FormatType == FormatDescriptor.Type.Junk); if (dfd.FormatSubType == FormatDescriptor.SubType.None) { return(false); } Debug.Assert(dfd.IsAlignedJunk); // Just check the address. Shouldn't need to check the length. int lastOffset = offset + dfd.Length - 1; int alignToAddr = addrMap.OffsetToAddress(lastOffset) + 1; int alignPwr = FormatDescriptor.AlignmentToPower(dfd.FormatSubType); int alignMask = (1 << alignPwr) - 1; bool result = (alignToAddr & alignMask) == 0; //Debug.WriteLine(dfd.FormatSubType + " at +" + offset.ToString("x6") + // "(" + alignToAddr.ToString("x4") + "): " + result); return(result); }
// 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 = mLocalizer.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, mLocalizer.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, mLocalizer.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.Junk: int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length); if (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) { // 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); } }