Преобразование очень простых инструкций ARM в двоичный / шестнадцатеричный

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

Основной NOP:

       what goes here?          what goes here?
             _↓_                  _____↓____
            |   |                |          |
mov r0, r0 ; ????00?1101?????????????????????
                         |__||__|
                          ↑    ↑
                 how do I express registers?

Тот же основной вопрос для других.

Сравнивая два регистра:

cmp r1, r0

Добавление немедленного к значению регистра:

add r0, #0x1a

Все эти учебные пособия онлайн превосходно описывают, как использовать подобные инструкции, но ни один из них мне не удалось найти, как на самом деле разобраться, как преобразовать инструкцию ARM в двоичный / шестнадцатеричный / машинный код, в который она собирается.

Заранее спасибо за помощь.

3 ответа

Решение

Вот как кодируются инструкции по обработке данных:

Инструкция по обработке данных ARM

У вас есть таблица кодов условий на вашей странице. Регистры закодированы 0000 через 1111,

Все ваши примеры попадают в одну категорию. Изображение извлечено из какого-то документа на моем жестком диске, но мне также удалось найти его в Google. Кодирование этих инструкций - утомительная работа.

Так, mov r0, r0 должно идти так:

1110 00 0 0 1101 0000 0000 00000000

Я поставил Rn на 0, потому что это на самом деле не относится к MOV, В случае CMP, Я верю, S всегда 1.

Прежде всего, вам нужно ARM Архитектурное справочное руководство (ARM ARM) на infocenter.arm.com, справочные руководства, получите самое старое (armv5 или что-то еще). набор инструкций там четко определен.

Во-вторых, почему бы вам просто не собрать некоторые инструкции и посмотреть, что произойдет?

;@test.s
cmp r1, r0
add r0, #0x1a

какой бы у вас ни был кросс-ассемблер (см. http://github.com/dwelch67/raspberrypi в каталоге сборок gcc для скрипта, просто запустите через этот скрипт binutils)

arm-none-linux-gnueabi-as test.s  -o test.o
arm-none-linux-gnueabi-objdump -D test.o

arm-none-linux-gnueabi vs arm-none-elf vs arm-elf и т. д. Не имеет значения для этого, все делают то же самое

Disassembly of section .text:

00000000 <.text>:
   0:   e1510000    cmp r1, r0
   4:   e280001a    add r0, r0, #26

Верхние четыре бита полной инструкции 32-разрядного плеча (не большого пальца) - это код условия, см. Раздел поля условий в ARM ARM. 0xE означает всегда, всегда выполняйте эту инструкцию. 0b0000 - это eq, только если установлен флаг z, 0b0001 ne, только если z очищен и т. Д.

В ARM ARM нажмите на набор инструкций arm, затем алфавитный список инструкций arm, затем найдите cmp. Он начинается с cond 00I10101 rn sbz shift

Из приведенной выше инструкции cmp мы видим 1110 000101010001 ... поэтому я - нулевые биты 15:12 - нулевые биты, 27:26 - ноль, а 24:21 - 1010, так что это инструкция cmp

биты с 19 по 16 выше равны 0b001, то есть rn, так что rn = 1 (r1) для операнда сдвига в ARM ARM он говорит вам посмотреть на операнды Обработки данных режима адресации 1 и имеет ссылку в pdf на страницу

мы знаем, что мы хотим, чтобы второй операнд был просто регистром, который называется операндом обработки данных - регистр и номер страницы. Перейдите на эту страницу на этой странице. 15:12 это rd 11:4 - нули, а 3:0 - rm., мы знаем из инструкции cmp, что это говорит о том, что 15:12 должно быть нулем, интересно, если это волнует, cmp не сохраняет результат в регистр, поэтому rd не используется. rm используется, и в этом случае мы хотим r0, поэтому 0b0000 идет в 3:0, также обратите внимание, что биты 27:25 показаны как нули, в инструкции cmp 25 есть I, теперь мы знаем, что мы хотим получить ноль, так что

между страницей CMP и этой обработкой данных - страница регистрации у нас есть вся картина

1110 condition
000 
1010 opcode
1 S (store flags, that is a 1 for a cmp to be useful)
0001 rn
0000 rd/dont care/sbz
00000
000
0000 rm

cmp rn,rm
cmp r1,r0

add аналогичен, но использует немедленное, так что перейдите к инструкции add в альфа-списке инструкций. теперь мы знаем из cmp, что 24:21 для этого класса инструкций является кодом операции, мы можем в значительной степени перейти прямо к вещам с операндами сдвига, чтобы продолжить оттуда

на этот раз мы делаем add rd,rn,# немедленный

так что ищите страницу для #immediate

и кодировка

1110 condition, always
001 (note the immediate bit is set)
0100 (opcode for add for this type of instruction)
0 (S not saving the flags, it would be adds r0,r0,#26 for that)
0000 (rn = r0)
0000 (rd = r0)

Теперь начинается интересная часть, мы можем кодировать 26 различных способов. биты 7:0 являются непосредственными, а биты 11:8 позволяют вращать эти немедленные, 26 - это 0x1A, мы могли бы просто поместить 0x1A в младшие 8 битов и установить вращение в 0, и это то, что сделал ассемблер gnu. вероятно, можно поместить 0x68 в младшие 8 битов и 1 в поле rotate_imm. 1101000 повернутых вправо 1*2 битов составляет 11010 = 0x1A = 26.

Вы должны получить копию ARM ARM, которая описывает кодировку для всех инструкций.

Большинство инструкций ARM используют 4 старших бита для условного кода. Если вы не хотите выполнять инструкцию условно, просто используйте псевдо-условие AL (1110).

Первый регистр (Rn) в кодировании не используется для инструкции MOV, и он должен быть установлен в 0000, как определено ARM ARM.

Второй регистр - это пункт назначения, здесь вы просто кодируете номер регистра, так что в вашем случае это также будет 0000, потому что вы используете r0 в качестве адресата, для r 4 это будет 0100.

Остальная часть - это так называемый операнд сдвига, который очень гибкий. Это может быть простой регистр, как в вашем случае (r0), тогда это просто 0000 0000 0000, где последние 4 бита снова кодируют регистр. Он также может кодировать различные типы сдвигов и вращений с помощью регистра или непосредственных значений для обработки данных.

Но это также может быть момент, когда 8 бит закодированы в нижних битах, а первые 4 бита определяют поворот вправо с шагом в 2 бита. В этом случае бит25 также будет равен 1, во всех остальных случаях - 0.

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