DisassemblyData
Applies to: Visual Studio Visual Studio for Mac
Note
This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
Describes one disassembly instruction for the integrated development environment (IDE) to display.
typedef struct tagDisassemblyData {
DISASSEMBLY_STREAM_FIELDS dwFields;
BSTR bstrAddress;
BSTR bstrAddressOffset;
BSTR bstrCodeBytes;
BSTR bstrOpcode;
BSTR bstrOperands;
BSTR bstrSymbol;
UINT64 uCodeLocationId;
TEXT_POSITION posBeg;
TEXT_POSITION posEnd;
BSTR bstrDocumentUrl;
DWORD dwByteOffset;
DISASSEMBLY_FLAGS dwFlags;
} DisassemblyData;
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;
};
dwFields
The DISASSEMBLY_STREAM_FIELDS constant that specifies which fields are filled out.
bstrAddress
The address as an offset from some starting point (usually the beginning of the associated function).
bstrCodeBytes
The code bytes for this instruction.
bstrOpcode
The opcode for this instruction.
bstrOperands
The operands for this instruction.
bstrSymbol
The symbol name, if any, associated with the address (public symbol, label, and so on).
uCodeLocationId
The code location identifier for this disassembled line. If the code context address of one line is greater than the code context address of another, then the disassembled code location identifier of the first will also be greater than the code location identifier of the second.
posBeg
The TEXT_POSITION that corresponds to the position in a document where the disassembly data begins.
posEnd
The TEXT_POSITION that corresponds to the position in a document where the disassembly data ends.
bstrDocumentUrl
For text documents that can be represented as file names, the bstrDocumentUrl
field is filled in with the file name where the source can be found, using the format file://file name
.
For text documents that cannot be represented as file names, bstrDocumentUrl
is a unique identifier for the document, and the debug engine must implement the GetDocument method.
This field can also contain additional information about checksums. See Remarks for details.
dwByteOffset
The number of bytes the instruction is from the beginning of the code line.
dwFlags
The DISASSEMBLY_FLAGS constant that specifies which flags are active.
Each DisassemblyData
structure describes one instruction of disassembly. An array of these structures is returned from the Read method.
The TEXT_POSITION structure is used for text-based documents only. The source code range for this instruction is filled out only for the first instruction generated from a statement or line, for example, when dwByteOffset == 0
.
For documents that are non-textual, a document context can be obtained from the code, and the bstrDocumentUrl
field should be a null value. If the bstrDocumentUrl
field is the same as the bstrDocumentUrl
field in the previous DisassemblyData
array element, then set the bstrDocumentUrl
to a null value.
If the dwFlags
field has the DF_DOCUMENT_CHECKSUM
flag set, then additional checksum information follows the string pointed to by the bstrDocumentUrl
field. Specifically, after the null string terminator, there follows a GUID identifying the checksum algorithm that is in turn followed by a 4 byte value indicating the number of bytes in the checksum and that in turn is followed by the checksum bytes. See the Example in this topic on how to encode and decode this field in Visual C#.
The bstrDocumentUrl
field can contain additional information other than a string if the DF_DOCUMENT_CHECKSUM
flag is set. The process of creating and reading this encoded string is straightforward in Visual C++. However, in Visual C#, it is another matter. For those who are curious, the following example shows one way to create the encoded string from Visual C# and one way to decode the encoded string in 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);
}
}
}
}
}