- PVSM.RU - https://www.pvsm.ru -
Привет, %username%!
Декодирование IA-32 кода — задача архисложная. Чтобы в этом убедиться, можете обратиться к Intel Software Development Manual [1] или к статьям, ранее написанным на хабре: Префиксы в системе команд IA-32 [2], Правильно ли работает ваш дизассемблер? [3]. Давайте посмотрим, как с этой задачей борется функционально точный полноплатформенный симулятор Wind River Simics [4], позволяющий создать высокопроизводительное виртуальное окружение, в котором любая электронная система, начиная с одной платы и заканчивая целыми многопроцессорными, многоядерными и даже многомашинными системами, может быть определена, разработана и запущена.
Большинство библиотек для декодирования IA-32 инструкций генерируют или используют таблицы соответствия между кодами операций и инструкциями. Пример использования данного подхода описан в статье Дизассемблер своими руками [5]. Однако декодирование префиксов и аргументов обычно написано руками: libopcodes [6], metasm [7], beaengine [8], distorm [9]. Данный подход обладает существенным недостатком — добавление поддержки новых наборов команд потребует большого количества ручной работы.
Существуют и другие способы создания декодеров, например с помощью языка GDSL [10]. Данный подход является универсальным и позволяет создавать декодеры для любых архитектур.
Simics же использует совершенно другой не менее универсальный подход для работы с IA-32 инструкциями, названный раздельным декодированием. Также Simics имеет возможность использования внешних декодеров, но об этом немного позже.
В реальном процессоре за задачу декодирования отвечает отдельный блок логических элементов микросхемы. В симуляторе же ему соответствует некоторая процедура, написанная на языке программирования. Рассмотрим, что подаётся на её вход и какие результаты следует от нее ожидать.
Очевидно, что на вход декодера подаётся массив байт известной длины, полученный на фазе выборки команд (англ. fetch). Кроме того, ему должен быть известен текущий режим процессора (см. Префиксы в системе команд IA-32 [2]).
В результате работы декодер должен вернуть код ошибки и результаты анализа последовательности в виде списка полей результата. При этом возможны следующие значения для кода ошибки:
На рисунке ниже приведён пример алгоритма, сочетающего в себе итерации фаз Fetch и Decode и позволяющего провести декодирование для инструкций с переменной длиной.
Основной идеей данного подхода является разделение фазы декодирования на две стадии:
Само собой разумеется, что вторая фаза зависит от результата, так как в системе команд IA-32 существует такое понятие, как обязательные префиксы, которые фактически являются частью кода операции (см. Префиксы в системе команд IA-32 [2]).
Simics позволяет подключать дополнительные декодеры с помощью внешних интерфейсов, описанных в Model Builder User's Guide, который поставляется вместе с симулятором. Таким образом, можно подключить множество внешних декодеров и вызывать их по очереди до тех пор, пока какой-нибудь декодер не даст положительного результата или список декодеров не кончится. В этом случае можно будет сделать вывод, что в данной модели данный код операции считается недопустимым.
Для обеспечения гибкости внешние декодеры в Simics делятся на два типа:
Разница между предложенными типами декодеров заключается в том, что пользовательские декодеры запускаются первыми — еще до вызова встроенного, что позволяет переопределять результаты декодирования, зашитые в исходную модель. Расширяющие запускаются только в том случае, когда ни пользовательские, ни встроенный декодеры не смогли распознать инструкцию.
То есть пользователь, занимаясь разработкой какого-либо ISA, может просто подсунуть свой декодер и посмотреть что изменится, не меняя исходной модели процессора.
Кроме того, данный подход позволяется переиспользовать уже существующие декодеры вместо написания их с нуля, что значительно сокращает время разработки модели.
Автор: yulyugin
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/x86/57255
Ссылки в тексте:
[1] Intel Software Development Manual: http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf
[2] Префиксы в системе команд IA-32: http://habrahabr.ru/company/intel/blog/200598/
[3] Правильно ли работает ваш дизассемблер?: http://habrahabr.ru/company/intel/blog/200658/
[4] Wind River Simics: http://www.windriver.com/products/simics
[5] Дизассемблер своими руками: http://habrahabr.ru/post/128042/
[6] libopcodes: http://packages.debian.org/testing
[7] metasm: http://metasm.cr0.org/
[8] beaengine: http://www.beaengine.org
[9] distorm: http://www.ragestorm.net/distorm/
[10] GDSL: http://www2.in.tum.de/bib/files/sepp12gdsl.pdf
[11] SimGen: https://www.pvsm.ruftp://ftp.sics.se/pub/SICS-reports/Reports/SICS-R--97-03--SE.ps.Z
[12] Источник: http://habrahabr.ru/post/215687/
Нажмите здесь для печати.