Подтвердить что ты не робот

Преобразование очень простых команд 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 в двоичный/шестнадцатеричный/машинный код, в который он собирается.

Заранее благодарим за помощь.

4b9b3361

Ответ 1

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

ARM data processing instructions

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

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

Итак, mov r0, r0 должен выглядеть следующим образом:

1110 00 0 0 1101 0000 0000 00000000

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

Ответ 2

Во-первых, вам нужно ARM Architectural Reference Manual (ARM ARM) на infocenter.arm.com, справочные руководства, получить самый старый (armv5 или что-то еще). набор команд хорошо определен там.

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

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

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

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 нажмите в набор команд руки, затем в алфавитном списке команд руки, затем найдите cmp. Он начинается с cond 00I10101 rn sbz shifter

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

бит с 19 по 16 выше: 0b001, который равен rn, так что rn = 1 (r1) для операнда shifter в 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 есть я, теперь мы знаем, что мы хотим, чтобы там был нуль, поэтому

между страницей 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

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

на этот раз мы делаем 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.

Ответ 3

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

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

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

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

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

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