描述要显示的集成开发环境(IDE)的一个反汇编指令。
Syntax
public struct DisassemblyData {
public uint dwFields;
public string bstrAddress;
public string bstrAddressOffset;
public string bstrCodeBytes;
public string bstrOpcode;
public string bstrOperands;
public string bstrSymbol;
public ulong uCodeLocationId;
public TEXT_POSITION posBeg;
public TEXT_POSITION posEnd;
public string bstrDocumentUrl;
public uint dwByteOffset;
public uint dwFlags;
};
Members
dwFields
指定哪些字段被填写的常量DISASSEMBLY_STREAM_FIELDS。
bstrAddress
地址作为一些起点的偏移量(通常是关联函数的开头)。
bstrCodeBytes
此指令的代码字节。
bstrOpcode
此指令的操作码。
bstrOperands
此指令的操作数。
bstrSymbol
与地址(公共符号、标签等)关联的符号名称(如果有)。
uCodeLocationId
此反汇编行的代码位置标识符。 如果一行的代码上下文地址大于另一行的代码上下文地址,则第一行的反汇编代码位置标识符也将大于第二行的代码位置标识符。
posBeg
TEXT_POSITION 对应于文档中反汇编数据开始的位置。
posEnd
文档中反汇编数据结束位置对应的 TEXT_POSITION。
bstrDocumentUrl
对于可以用文件名表示的文本文档,bstrDocumentUrl 字段将以 file://file name 格式填写源所在的文件名。
对于不能表示为文件名的文本文档, bstrDocumentUrl 是文档的唯一标识符,并且调试引擎必须实现 GetDocument 方法。
此字段还可以包含有关校验和的其他信息。 有关详细信息,请参阅“备注”。
dwByteOffset
指令的字节数来自代码行的开头。
dwFlags
DISASSEMBLY_FLAGS 常量指定了哪些标志处于活动状态。
Remarks
每个 DisassemblyData 结构描述一条反汇编指令。 从 Read 方法返回这些结构的数组。
TEXT_POSITION结构仅用于基于文本的文档。 此指令的源代码范围仅在从语句或代码行生成的第一个指令时填写,例如在 dwByteOffset == 0 这种情况下。
对于非文本的文档,可以从代码获取文档上下文,字段 bstrDocumentUrl 应为 null 值。 如果bstrDocumentUrl字段与前一个bstrDocumentUrl数组元素中的DisassemblyData字段相同,则将bstrDocumentUrl字段设置为null值。
如果dwFlags字段设置了DF_DOCUMENT_CHECKSUM标志,则额外的校验和信息将紧跟在由bstrDocumentUrl字段指向的字符串之后。 具体而言,在空字符串终止符之后,是一个用于标识校验和算法的 GUID,其后是一个 4 字节的值,指示校验和中的字节数,然后是校验和的字节。 请参阅本主题中的示例,了解如何在 Visual C# 中对此字段进行编码和解码。
Example
如果bstrDocumentUrl设置了标志,该DF_DOCUMENT_CHECKSUM字段可以包含字符串以外的其他信息。 创建和读取此编码字符串的过程在 Visual C++中非常简单。 但是,在 Visual C# 中,这是另一回事。 对于那些好奇的人,以下示例显示了从 Visual C# 创建编码字符串的一种方法,以及解码 Visual C# 中编码字符串的一种方法。
using System;
using System.Runtime.InteropServices;
namespace MyNamespace
{
class MyClass
{
string EncodeData(string documentString,
Guid checksumGuid,
byte[] checksumData)
{
string returnString = documentString;
if (checksumGuid == null || checksumData == null)
{
// Nothing more to do. Just return the string.
return returnString;
}
returnString += '\0'; // separating null value
// Add checksum GUID to string.
byte[] guidDataArray = checksumGuid.ToByteArray();
int guidDataLength = guidDataArray.Length;
IntPtr pBuffer = Marshal.AllocCoTaskMem(guidDataLength);
for (int i = 0; i < guidDataLength; i++)
{
Marshal.WriteByte(pBuffer, i, guidDataArray[i]);
}
// Copy guid data bytes to string as wide characters.
// Assumption: sizeof(char) == 2.
for (int i = 0; i < guidDataLength / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
// Add checksum count (a 32-bit value).
Int32 checksumCount = checksumData.Length;
Marshal.StructureToPtr(checksumCount, pBuffer, true);
for (int i = 0; i < sizeof(Int32) / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
// Add checksum data.
pBuffer = Marshal.AllocCoTaskMem(checksumCount);
for (int i = 0; i < checksumCount; i++)
{
Marshal.WriteByte(pBuffer, i, checksumData[i]);
}
for (int i = 0; i < checksumCount / sizeof(char); i++)
{
returnString += (char)Marshal.ReadInt16(pBuffer, i * sizeof(char));
}
Marshal.FreeCoTaskMem(pBuffer);
return returnString;
}
void DecodeData( string encodedString,
out string documentString,
out Guid checksumGuid,
out byte[] checksumData)
{
documentString = String.Empty;
checksumGuid = Guid.Empty;
checksumData = null;
IntPtr pBuffer = Marshal.StringToBSTR(encodedString);
if (null != pBuffer)
{
int bufferOffset = 0;
// Parse string out. String is assumed to be Unicode.
documentString = Marshal.PtrToStringUni(pBuffer);
bufferOffset += (documentString.Length + 1) * sizeof(char);
// Parse Guid out.
// Read guid bytes from buffer and store in temporary
// buffer that contains only the guid bytes. Then the
// Marshal.PtrToStructure() can work properly.
byte[] guidDataArray = checksumGuid.ToByteArray();
int guidDataLength = guidDataArray.Length;
IntPtr pGuidBuffer = Marshal.AllocCoTaskMem(guidDataLength);
for (int i = 0; i < guidDataLength; i++)
{
Marshal.WriteByte(pGuidBuffer, i,
Marshal.ReadByte(pBuffer, bufferOffset + i));
}
bufferOffset += guidDataLength;
checksumGuid = (Guid)Marshal.PtrToStructure(pGuidBuffer, typeof(Guid));
Marshal.FreeCoTaskMem(pGuidBuffer);
// Parse out the number of checksum data bytes (always 32-bit value).
int dataCount = Marshal.ReadInt32(pBuffer, bufferOffset);
bufferOffset += sizeof(Int32);
// Parse out the checksum data.
checksumData = new byte[dataCount];
for (int i = 0; i < dataCount; i++)
{
checksumData[i] = Marshal.ReadByte(pBuffer, bufferOffset + i);
}
}
}
}
}