Почему несколько кодировок для одной инструкции в ARMv7

В настоящее время я пытаюсь реализовать дизассемблер для ARM cortex A9, который реализует набор инструкций ARMv7.

Для этого я использую руководство "DDI0406C_b_arm_architecture_reference_manual.pdf", которое можно скачать здесь (после регистрации на веб-сайте arm):

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.architecture/index.html

В этом руководстве, в части A8.8 с подробностями инструкций, я не могу понять, почему существует несколько кодировок для одной инструкции (например, A1, A2, ...), которые, кажется, все реализованы с помощью ARMv7.

Кроме того, поскольку в ARM cortex A9 используется thumb-2, он также реализует кодировки A1/A2/... или только T1/T2...?

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

3 ответа

Разное кодирование инструкции делает функционально разные вещи.

Одним из примеров использования различных кодировок является A8.9.12 ADR

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

Если инструкция закодирована как A1 тогда смещение должно интерпретироваться как ноль или положительное значение, если оно закодировано как A2 тогда смещение отрицательно.

Другой пример A8.8.132 POP

Если список содержит более одного регистра, инструкция собирается в кодировку A1. Если список содержит ровно один регистр, инструкция собирается в кодировку A2.

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

Что касается второй части вашего вопроса, Cortex-A9 - это процессор архитектуры ARMv7-A, и он поддерживает все инструкции, указанные в указанном вами руководстве. Возможно, вам также следует прочитать Техническое справочное руководство Cortex™-A9.

Кодировки Ax являются ручными, когда процессор находится в режиме охраны, он будет декодировать найденные биты, используя эти кодировки. если имеется более одного A1, A2, должно быть очевидно, что есть другая особенность или причина для этого. эти две инструкции можно считать отдельными (посмотрите на чрезмерное использование инструкции mov в x86, например, она имеет много кодировок). Обрабатывайте каждую кодировку как отдельную "инструкцию".

Тогда есть варианты Tx, это расширения thumb и thumb2. Большой палец - все 16 бит (bl может быть декодирован как две отдельные 16-битные инструкции), а описания под ними указывают "все варианты большого пальца" или "armv4t to present" или какой-либо другой такой язык. Все расширения thumb2 являются 32-битными, первые 16 бит являются неопределенной инструкцией в мире большого пальца. У них больше ограничений на то, какие архитектуры их поддерживают.

Вы не сможете полностью создать дизассемблер для одного из этих процессоров, по той же причине, по которой вы не можете сделать один для x86 или многих других процессоров (все?). Если вы предполагаете, что все инструкции являются одним режимом (arm или thumb или thumb+thumb2), но без смешивания режимов (arm + thumb), то вы можете сделать это, потому что все имеют фиксированную длину инструкции, и вы можете просто разобрать все данные и код, и вы не будете запускать в любые проблемы. Чтобы разобрать смешанный режим, вы должны в основном эмулировать / выполнять инструкции и следовать потоку инструкций (точно так же, как дизассемблер набора команд переменной длины слова), чтобы попытаться найти переходы, проблема здесь, конечно, состоит в том, что переходы состоят из нескольких команд при минимальной нагрузке. регистр, затем регистр bx, иногда в вычислении команд участвует математика, и нет никакой гарантии, что вычисление адреса или загрузка произойдут в команде перед bx. Таким образом, вы могли бы сделать это и пройти долгий путь, разбирая программу.

Если thumb2 поддерживается / разрешен на используемом процессоре, тогда у вас есть проблема с переменной длиной инструкции для времен, когда вы обнаруживаете точки входа в код большого пальца. И если вы уже не делаете этого, вы должны следить за выполнением кода, чтобы определить, где начинаются инструкции (элемент разборки элементарной переменной длины инструкции).

Комбинация технического справочного руководства и архитектурного справочного руководства покажет вам, допускает ли архитектура и реализация этой архитектуры (trm) режимы "рука" и "большой палец". Я предположил бы, что A9 поддерживает руку thumb и thumb2, все три.

Семейство cortex-m пока является единственным, которое ограничено не поддерживающей рукой, и их thumb2 широко варьируется, так как cortex-m0 (и m1) - armv6m, а m3 и m4 - armv7m (несколько десятков (armv6m) инструкций) много десятков расширений thumb2 в armv7m). Существуют отдельные руководства по архитектуре, специально для вариантов -m, например, armv7-m и armv7-ar.

Нет никакого способа действительно различать ARM и Thumb в потоке команд. Вы можете принять решение только в зависимости от способа вызова функции (если младший бит установлен в 1, то это большой палец, в противном случае - постановка на охрану).

ARM-кодирование довольно "стабильно", вы найдете только несколько кодировок A1, BLX - это пример, где дается кодировка A2, но это главным образом потому, что новый ARM-ARM структурирован по-другому, чем старые. BL и BLX были двумя разными инструкциями, BLX был добавлен в дополнительное пространство инструкций (старшие 4 бита, которые обычно используются для условий, установлены в 1111, что в ARM до v5 означало "никогда не выполнять").

Для кодировок большого пальца все по-другому, их много, потому что они должны были быть помещены в более сжатое пространство инструкций, на странице A6-220 есть информация о том, как решить, какая инструкция большого пальца состоит из двух или только одного полуслова,

Другие вопросы по тегам