
Я понимаю, что мы можем выгрузить эквивалентную ассемблерную часть из кода C++, используя множество отладчиков и т. п.
А как насчет двоичного кода? Форматирование битов в каждом байте(ах), которые составляют фактические машинные инструкции, которые (могут) составлять микропрограммы (если микроархитектура таковая имеет).
Если каждая строка кода C++ ДОЛЖНА быть преобразована в машинный код каким-то образом и в какой-то момент программы (например, float может быть определен в C++, но не использоваться до тех пор, пока не будет помещен в стек, поэтому он может не преобразоваться 1:1 во весь машинный код, строка за строкой, но будет использоваться в любом случае), каждый оператор и т. д. можно отследить. Но отладчики не выводят формирование битов, занимающих каждую отдельную инструкцию(ы).
Если каждая программа становится отформатированной инструкцией по байтам/битам для ЦП, то (я предполагаю) должно быть возможно отследить весь написанный вами код до фактических битов на уровне схемы.
Но для максимально возможной уверенности,Является ли это возможнымсделать это в той степени, в которой я описываю здесь? Современные отладчики/программное обеспечение не предлагают эту функцию, и даже те, которые предлагают, похоже, не предоставляют разработчику полное двоичное представление каждой инструкции.
PS: Конечно, это предполагает, что скомпилированный код легко исполняется с инструкциями для предполагаемой архитектуры (а не является каким-то интерпретируемым языком или байт-кодом, для дальнейшего перевода которого требуется другая программа).
решение1
Вы можете использовать дизассемблер для преобразования скомпилированного двоичного кода обратно в язык ассемблера. Это позволит вам «читать» (с трудом) программное обеспечение, распространяемое только в двоичном виде.
Что касается другой части вашего вопроса, то вы, похоже, хотите какой-то аппаратный декомпилятор, который дает более подробную информацию о том, как процессор выполняет определенную двоичную инструкцию. Я не знаю ни одного инструмента, который мог бы это сделать. Вероятно, вам придется прочитать руководства по оборудованию и провести такой анализ в уме.
решение2
Нет.
Ну, может быть, но нет никакой гарантии, потому что код, который попадает в компилятор, редко совпадает с кодом, который выходит, по двум причинам: люди ужасно плохо пишут эффективный код, и люди не думают о коде так, как его должен обрабатывать процессор. Из-за этого компиляторы оптимизируют исходный код перед его преобразованием в ассемблер/двоичный код. Это может привести коператоры переупорядочиваются, бесполезные операторы удаляются, а целые функции встраиваются.
Например, рассмотрим следующий псевдокод:
int x = 3;
x = 3*3;
x = 4;
function mult4(number) { return number * 4; }
x = mult4(x);
может быть полностью сведена к
int x = 16;
хорошим оптимизирующим компилятором, который вообще не соответствует исходному коду. Вот почему при отладке часто приходится отключать оптимизации компилятора. При отключении всех оптимизаций компилятор попытается вывести сборку, которая соответствует исходному коду 1 к 1.