Поделиться через


DisassemblyData

Описывает инструкцию дизассембли, которую интегрированная среда разработки (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);
                }
            }
        }
    }
}

См. также