- Просмотр кода дизассемблирования в отладчике Visual Studio (C#, C++, Visual Basic, F#) View disassembly code in the Visual Studio debugger (C#, C++, Visual Basic, F#)
- Использование окна дизассемблирования Use the Disassembly window
- How to: View assembly contents
- Example
- Assemblies in .NET
- Assemblies in the common language runtime
- Create an assembly
- Assembly manifest
- Add a reference to an assembly
Просмотр кода дизассемблирования в отладчике Visual Studio (C#, C++, Visual Basic, F#) View disassembly code in the Visual Studio debugger (C#, C++, Visual Basic, F#)
В окне Дизассемблированный код отображается код сборки, соответствующий инструкциям, созданным компилятором. The Disassembly window shows assembly code corresponding to the instructions created by the compiler. При отладке управляемого кода эти инструкции ассемблера соответствуют присущему данному объекту коду, созданному компилятором JIT, а не промежуточному языку (MSIL), созданному компилятором Visual Studio. If you’re debugging managed code, these assembly instructions correspond to the native code created by the Just-in-Time (JIT) compiler, not the Microsoft intermediate language (MSIL) created by the Visual Studio compiler.
Чтобы воспользоваться всеми возможностями окна Дизассемблированный код, изучите основы программирования на языке ассемблера. To take full advantage of the Disassembly window, understand or learn the basics of assembly-language programming.
Эта возможность доступна, только если включена отладка на уровне адреса. This feature is only available if address-level debugging is enabled. Она недоступна для отладки скриптов и SQL. It isn’t available for script or SQL debugging.
В дополнение к инструкциям ассемблера в окне Дизассемблированный код могут отображаться следующие сведения: In addition to assembly instructions, the Disassembly window can show the following optional information:
Адреса в памяти, где располагается каждая из инструкций. Memory address where each instruction is located. Для собственных приложений это фактические адреса в памяти. For native applications, it is the actual memory address. Для кода на Visual Basic или C# это смещение относительно начала функции. For Visual Basic or C#, it’s an offset from the beginning of the function.
Исходный код, из которого получается код сборки. Source code from which the assembly code derives.
Байты кода, то есть байтовое представление реальных инструкций компьютера или языка MSIL. Code bytes, that is, the byte representations of the actual machine or MSIL instructions.
Символьные имена для адресов памяти. Symbol names for the memory addresses.
Номера строк, соответствующие исходному коду. Line numbers corresponding to the source code.
Инструкции на языке ассемблера состоят из мнемоник, представляющих собой сокращения имен инструкций, и символов, которые обозначают переменные, регистры и константы. Assembly-language instructions consist of mnemonics, which are abbreviations for instruction names, and symbols for variables, registers, and constants. Каждую инструкцию машинного кода представляет одна мнемоника ассемблера, за которой следует один или несколько необязательных символов. Each machine-language instruction is represented by one assembly-language mnemonic optionally followed by one or more symbols.
Код на ассемблере активно использует регистры процессора, а при использовании управляемого кода — регистры среды выполнения. Assembly code relies heavily on processor registers or, for managed code, common language runtime registers. Вы можете использовать окно Дизассемблированный код в сочетании с окном Регистры, которое позволяет изучить содержимое регистров. You can use the Disassembly window along with the Registers window, which allows you to examine register contents.
Чтобы просмотреть инструкции машинного кода в необработанной числовой форме, а не на языке ассемблера, используйте окно Память или выберите Байты кода в контекстном меню в окне Дизассемблированный код. To view machine-code instructions in their raw numeric form, rather than as assembly language, use the Memory window or select Code Bytes from the shortcut menu in the Disassembly window.
Использование окна дизассемблирования Use the Disassembly window
Чтобы включить окно Дизассемблированный код, выберите в разделе Сервис > Параметры > Отладка параметр Включить отладку на уровне адреса. To enable the Disassembly window, under Tools > Options > Debugging, select Enable address-level debugging.
Чтобы открыть окно Дизассемблированный код во время отладки, выберите Windows > Дизассемблированный код или нажмите сочетание клавиш ALT+8. To open the Disassembly window during debugging, select Windows > Disassembly or press Alt+8.
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих параметров или выпуска. The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings or edition. Чтобы изменить параметры, выберите в меню Сервис пункт Импорт и экспорт параметров . To change your settings, choose Import and Export Settings on the Tools menu. Дополнительные сведения см. в разделе Сброс параметров. For more information, see Reset settings.
Чтобы включить или отключить вывод дополнительных сведений, щелкните правой кнопкой в окне Дизассемблированный код и установите или снимите в контекстном меню соответствующие флажки. To turn optional information on or off, right-click in the Disassembly window, and set or clear the desired options in the shortcut menu.
Желтая стрелка, расположенная в левом поле, отмечает текущую точку выполнения. A yellow arrow in the left margin marks the current execution point. Для собственного кода точка выполнения соответствует счетчику команд ЦП. For native code, the execution point corresponds to the CPU’s program counter. В этом расположении отображается следующая инструкция, которая будет выполнена в программе. This location shows the next instruction that will be executed in your program.
How to: View assembly contents
You can use the Ildasm.exe (IL Disassembler) to view Microsoft intermediate language (MSIL) information in a file. If the file being examined is an assembly, this information can include the assembly’s attributes and references to other modules and assemblies. This information can be helpful in determining whether a file is an assembly or part of an assembly and whether the file has references to other modules or assemblies.
To display the contents of an assembly using Ildasm.exe, enter ildasm at a command prompt. For example, the following command disassembles the Hello.exe assembly.
To view assembly manifest information, double-click the Manifest icon in the MSIL Disassembler window.
Example
The following example starts with a basic «Hello World» program. After compiling the program, use Ildasm.exe to disassemble the Hello.exe assembly and view the assembly manifest.
Running the command ildasm.exe on the Hello.exe assembly and double-clicking the Manifest icon in the MSIL Disassembler window produces the following output:
The following table describes each directive in the assembly manifest of the Hello.exe assembly used in the example:
Directive | Description |
---|---|
.assembly extern | Specifies another assembly that contains items referenced by the current module (in this example, mscorlib ). |
.publickeytoken | Specifies the token of the actual key of the referenced assembly. |
.ver | Specifies the version number of the referenced assembly. |
.assembly | Specifies the assembly name. |
.hash algorithm | Specifies the hash algorithm used. |
.ver | Specifies the version number of the assembly. |
.module | Specifies the name of the modules that make up the assembly. In this example, the assembly consists of only one file. |
.subsystem | Specifies the application environment required for the program. In this example, the value 3 indicates that this executable is run from a console. |
.corflags | Currently a reserved field in the metadata. |
An assembly manifest can contain a number of different directives, depending on the contents of the assembly. For an extensive list of the directives in the assembly manifest, see the Ecma documentation, especially «Partition II: Metadata Definition and Semantics» and «Partition III: CIL Instruction Set»:
Assemblies in .NET
Assemblies form the fundamental units of deployment, version control, reuse, activation scoping, and security permissions for .NET-based applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. Assemblies take the form of executable (.exe) or dynamic link library (.dll) files, and are the building blocks of .NET applications. They provide the common language runtime with the information it needs to be aware of type implementations.
In .NET Core and .NET Framework, you can build an assembly from one or more source code files. In .NET Framework, assemblies can contain one or more modules. This allows larger projects to be planned so that several developers can work on separate source code files or modules, which are combined to create a single assembly. For more information about modules, see How to: Build a multifile assembly.
Assemblies have the following properties:
Assemblies are implemented as .exe or .dll files.
For libraries that target the .NET Framework, you can share assemblies between applications by putting them in the global assembly cache (GAC). You must strong-name assemblies before you can include them in the GAC. For more information, see Strong-named assemblies.
Assemblies are only loaded into memory if they are required. If they aren’t used, they aren’t loaded. This means that assemblies can be an efficient way to manage resources in larger projects.
You can programmatically obtain information about an assembly by using reflection. For more information, see Reflection (C#) or Reflection (Visual Basic).
You can load an assembly just to inspect it by using the MetadataLoadContext class in .NET Core and the Assembly.ReflectionOnlyLoad or Assembly.ReflectionOnlyLoadFrom methods in .NET Core and .NET Framework.
Assemblies in the common language runtime
Assemblies provide the common language runtime with the information it needs to be aware of type implementations. To the runtime, a type does not exist outside the context of an assembly.
An assembly defines the following information:
Code that the common language runtime executes. Note that each assembly can have only one entry point: DllMain , WinMain , or Main .
Security boundary. An assembly is the unit at which permissions are requested and granted. For more information about security boundaries in assemblies, see Assembly security considerations.
Type boundary. Every type’s identity includes the name of the assembly in which it resides. A type called MyType that is loaded in the scope of one assembly is not the same as a type called MyType that is loaded in the scope of another assembly.
Reference scope boundary. The assembly manifest has metadata that is used for resolving types and satisfying resource requests. The manifest specifies the types and resources to expose outside the assembly, and enumerates other assemblies on which it depends. Microsoft intermediate language (MSIL) code in a portable executable (PE) file won’t be executed unless it has an associated assembly manifest.
Version boundary. The assembly is the smallest versionable unit in the common language runtime. All types and resources in the same assembly are versioned as a unit. The assembly manifest describes the version dependencies you specify for any dependent assemblies. For more information about versioning, see Assembly versioning.
Deployment unit. When an application starts, only the assemblies that the application initially calls must be present. Other assemblies, such as assemblies containing localization resources or utility classes, can be retrieved on demand. This allows apps to be simple and thin when first downloaded. For more information about deploying assemblies, see Deploy applications.
Side-by-side execution unit. For more information about running multiple versions of an assembly, see Assemblies and side-by-side execution.
Create an assembly
Assemblies can be static or dynamic. Static assemblies are stored on disk in portable executable (PE) files. Static assemblies can include interfaces, classes, and resources like bitmaps, JPEG files, and other resource files. You can also create dynamic assemblies, which are run directly from memory and aren’t saved to disk before execution. You can save dynamic assemblies to disk after they have executed.
There are several ways to create assemblies. You can use development tools, such as Visual Studio, that can create .dll or .exe files. You can use tools in the Windows SDK to create assemblies with modules from other development environments. You can also use common language runtime APIs, such as System.Reflection.Emit, to create dynamic assemblies.
Compile assemblies by building them in Visual Studio, building them with .NET Core command-line interface tools, or building .NET Framework assemblies with a command-line compiler. For more information about building assemblies using .NET Core CLI, see .NET Core CLI overview.
To build an assembly in Visual Studio, on the Build menu, select Build.
Assembly manifest
Every assembly has an assembly manifest file. Similar to a table of contents, the assembly manifest contains:
The assembly’s identity (its name and version).
A file table describing all the other files that make up the assembly, such as other assemblies you created that your .exe or .dll file relies on, bitmap files, or Readme files.
An assembly reference list, which is a list of all external dependencies, such as .dlls or other files. Assembly references contain references to both global and private objects. Global objects are available to all other applications. In .NET Core, global objects are coupled with a particular .NET Core runtime. In .NET Framework, global objects reside in the global assembly cache (GAC). System.IO.dll is an example of an assembly in the GAC. Private objects must be in a directory level at or below the directory in which your app is installed.
Because assemblies contain information about content, versioning, and dependencies, the applications that use them needn’t rely on external sources, such as the registry on Windows systems, to function properly. Assemblies reduce .dll conflicts and make your applications more reliable and easier to deploy. In many cases, you can install a .NET-based application simply by copying its files to the target computer. For more information, see Assembly manifest.
Add a reference to an assembly
To use an assembly in an application, you must add a reference to it. Once an assembly is referenced, all the accessible types, properties, methods, and other members of its namespaces are available to your application as if their code were part of your source file.
Most assemblies from the .NET Class Library are referenced automatically. If a system assembly isn’t automatically referenced, for .NET Core, you can add a reference to the NuGet package that contains the assembly. Either use the NuGet Package Manager in Visual Studio, or add a
element for the assembly to the .csproj or .vbproj project. In .NET Framework, you can add a reference to the assembly by using the Add Reference dialog in Visual Studio, or by using the -reference command line option for the C# or Visual Basic compilers.
In C#, you can use two versions of the same assembly in a single application. For more information, see extern alias.