Вопрос по assembly, visual-c++ – Как просмотреть сборку за кодом с помощью Visual C ++?

100

Я читал еще один вопрос, касающийся эффективности двух строк кода, и ОП сказал, что он посмотрел на сборку за кодом, и обе строки были идентичны в сборке. Отступление в сторону, как я могу просмотреть ассемблерный код, созданный при компиляции программы.

Я использую Microsoft Visual C ++, но мне также хотелось бы знать, возможно ли просмотреть сборку за кодом, написанным на Visual Basic.

Итак, как мне посмотреть ассемблерный код программы, написанной на языках более высокого уровня, таких как C ++ и Visual Basic?

Он называется листингом сборки в msvc, как уже упоминали другие. Я создал простой плагин, добавляющий записи в контекстное меню редактора для автоматизации этих утомительных шагов:marketplace.visualstudio.com/items?itemName=Trass3r.DevUtils Trass3r

Ваш Ответ

8   ответов
20

ючателя интегрируется только код сборки или высокоуровневый код и код сборки. Имя файла получает расширение .asm. Вот поддерживаемые значения:

/FA Assembly code; .asm /FAc Machine and assembly code; .cod /FAs Source and assembly code; .asm /FAcs Machine, source, and assembly code; .cod
9

disassembly window.

4

link.exe / dump / linenumbers / disasm /out:foo.dis foo.dll

foo.pdb должен быть доступен для получения символов

1

.NET Reflector от Red Gate это довольно удивительный инструмент, который помог мне несколько раз. Плюсом этой утилиты, помимо простого показа MSIL, является то, что вы можете анализировать множество сторонних DLL и заставить Reflector позаботиться о преобразовании MSIL в C # и VB.

Я не обещаю, что код будет таким же понятным, как и исходный код, но у вас не должно возникнуть особых проблем с его выполнением.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
6

основном избыточна, посколькуhttp://gcc.godbolt.org/ обеспечиваетCL 19 RC для ARM, x86 и x86-64 (нацелены на соглашение о вызовах Windows, в отличие от gcc, clang и icc на этом сайте).

Проводник компилятора Godbolt предназначен для удобного форматирования вывода asm компилятора, удаляя "шум". директив, поэтому я настоятельно рекомендую использовать его, чтобы найти в asm простые функции, которые принимают аргументы и возвращают значение (поэтому они не будут оптимизированы).

Некоторое время CL был доступен наhttp://gcc.beta.godbolt.org/ но не основной сайт, но теперь он на обоих сайтах.

Чтобы получить MSVC ASM выход изhttp://rextester.com/l/cpp_online_compiler_visual онлайн компилятор: Добавить/FAs к параметрам командной строки. Пусть ваша программа найдет свой собственный путь и определит путь к.asm и брось это. Или запустить дизассемблер на.exe.

напримерhttp://rextester.com/OKI40941

#include <string>
#include <boost/filesystem.hpp>
#include <Windows.h>

using namespace std;

static string my_exe(void){
    char buf[MAX_PATH];
    DWORD tmp = GetModuleFileNameA( NULL, // self
                                  buf, MAX_PATH);
    return buf;
}

int main() {
    string dircmd = "dir ";
    boost::filesystem::path p( my_exe() );
    //boost::filesystem::path dir = p.parent_path();

    // transform c:\foo\bar\1234\a.exe 
    // into      c:\foo\bar\1234\1234.asm
    p.remove_filename();
    system ( (dircmd + p.string()).c_str() );

    auto subdir = p.end();      // pointing at one-past the end
    subdir--;                   // pointing at the last directory name
    p /= *subdir;               // append the last dir name as a filename
    p.replace_extension(".asm");
    system ( (string("type ") + p.string()).c_str() );
//    std::cout << "Hello, world!\n";
}

... code of functions you want to see the asm for goes here ...

type версия для DOScat, Я не хотел включать больше кода, который усложнил бы поиск функций, для которых я хотел бы увидеть asm. (Хотя использование std :: string и boost работает против этих целей! Некоторые манипуляции со строками в стиле C, которые делают больше предположений о строке, которую она обрабатывает (и игнорируют максимальную длину / распределение при использовании большого буфера) для результата изGetModuleFileNameA будет гораздо меньше общего машинного кода.)

ИДК почему, ноcout << p.string() << endl показывает только базовое имя (то есть имя файла без каталогов), даже если печать его длины показывает, что оно не просто голое имя. (Chromium48 на Ubuntu 15.10). Возможно, в какой-то моментcoutили между стандартным выводом программы и веб-браузером.

Error: User Rate Limit Exceededsubdir--Error: User Rate Limit Exceededp /= *subdirError: User Rate Limit ExceededsubdirError: User Rate Limit Exceededp.end()
Error: User Rate Limit ExceededisError: User Rate Limit Exceeded.c_str()Error: User Rate Limit Exceededstd::stringError: User Rate Limit Exceeded#if 0Error: User Rate Limit ExceededcoutError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded\\rError: User Rate Limit Exceeded\rError: User Rate Limit Exceededp.generic_string()Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededGetModuleFileNameAError: User Rate Limit Exceededa.exeError: User Rate Limit ExceededprintError: User Rate Limit Exceeded
Error: User Rate Limit Exceededsubdir--; p /= *subdir;Error: User Rate Limit ExceededpError: User Rate Limit Exceeded
4

как мне кажется, имеют возможность вывода списка ASM с исходным кодом. Таким образом, вы увидите исходный код C / C ++ и полученный ASM в одном файле.

134

You can normally see assembly code while debugging C++ in visual studio (and eclipse too). For this in Visual Studio put a breakpoint on code in question and when debugger hits it rigth click and find "Go To Assembly" ( or press CTRL+ALT+D )

Second approach is to generate assembly listings while compiling. For this go to project settings -> C/C++ -> Output Files -> ASM List Location and fill in file name. Also select "Assembly Output" to "Assembly With Source Code".

Compile the program and use any third-party debugger. You can use OllyDbg or WinDbg for this. Also you can use IDA (interactive disassembler). But this is hardcore way of doing it.

Обратите внимание, что подход № 2 не работает при компиляции статической библиотеки с включенной оптимизацией всей программы (по крайней мере, в VS2010). Что имеет смысл - компилятор еще не сгенерировал окончательный код.
Это называется "Перейти к разборке" в Visual Studio 2017
С подходом № 2, как я могу увидеть сборку?
27

есть большая разница между выходом Debug на ассемблере и первым выпуском. Первый хорошо узнать, как компилятор производит ассемблерный код из C ++. Второе полезно узнать, как компилятор оптимизирует различные конструкции C ++. В этом случае некоторые преобразования C ++ - asm не очевидны.

Это абсолютно верно. Но это не отвечает на вопрос вообще.
Я заметил, что при разборке исполняемого файла Debug кажется, что он распаковывает код во время его работы, этого не происходит в версии Release. Также при открытии обоих с PEiD только версия отладки показывает «Microsoft Visual C ++ 8.0 [Debug]».

Похожие вопросы