Обнаружение инструкции Thumb-2 и местоположение смещения P C - PullRequest
0 голосов
/ 10 марта 2020

Я новичок в ARM, и я пытаюсь понять, как инструкции интерпретируются / выполняются:

Насколько я знаю, в ARM довольно просто, поскольку каждая инструкция занимает 4 байта и все выровнены также на 4 байта.

Проблема возникает с Thumb-2, где их инструкции могут быть 16/32-битными. Я прочитал это, чтобы определить, является ли текущая инструкция длиной 16/32 бита, процессор читает слово (32 бита) и вычисляет первое полуслово для определенных битов [15:11]. Если эти биты равны 0b11101 / 0b11110 / 0b11111, то это половинное слово является первым полусловом 32-битной инструкции, иначе это 16-битная инструкция (я не совсем понимаю, почему эти конкретные c байты определяют это). Таким образом, пример должен быть:

0x4000 16-bit
0x4002 32-bit
0x4006 16-bit
0x4008 16-bit
0x400a 32-bit

Затем процессор должен перехватить значение от 0x4000 до 0x4004, вычислить первое полуслово (от 0x4000 до 0x4002), и если инструкция является 16-битной, то она просто переходит к следующей половина слова и повторяет процесс, но если половина слова указывает на 32-битный адрес, тогда он пропускает следующее полуслово и выполняет эту 32-битную инструкцию?

Кроме того, я запутался в том, где P C указать на большой палец-2, это еще две инструкции дальше?

1 Ответ

2 голосов
/ 10 марта 2020

Большинство из нас не знает / не знает точно, как это реализовано в логи c (и есть разные ядра, поэтому каждое из них может быть различным). Но то, что раньше было неопределенными инструкциями, превратилось в расширения thumb-2 на пару десятков в armv6-m, а затем в 150 новых в armv7-m.

Подумайте о процессоре, извлекающем 16-битные инструкции, и иногда он перебирает Переменная длина один. Как и другие процессоры переменной длины, x86 будет смотреть на однобайтовую инструкцию, основываясь на том, что ему может понадобиться или не потребоваться просмотр следующего байта и так далее, пока он не разрешит всю инструкцию. То же самое здесь, он смотрит на то, как полуслово определяет, есть ли у него все, что ему нужно, если нет, то захватывает следующее полуслово для остальной информации.

0x4000 16-bit
0x4002 32-bit
0x4006 16-bit
0x4008 16-bit
0x400a 32-bit

процессор захватывает 0x4000 и видит, что он имеет то, что ему нужно, выполняется. Процессор захватывает 0x4002, видит, что ему нужно другое полуслово, захватывает 0x4004, выполняет. Процессор захватывает 0x4006 и выполняет то, что ему нужно. захватывает 0x4008 имеет то, что ему нужно, выполняет. захватывает 0x400A и видит, что ему нужно другое полуслово, захватывает 0x400 C, выполняет.

Эти битовые комбинации ранее были неопределенными инструкциями, теперь они являются частью определения инструкции переменной длины. Так же, как инструкции, начинающиеся с 0b010000, являются инструкциями по обработке данных, и чтобы определить, является ли это добавлением или xor, вам нужно взглянуть на другие биты. Эти битовые комбинации определяют расширения thumb-2, а другие биты в этих двух полусловах определяют, что такое полная инструкция.

Почему эти битовые комбинации? Вы можете думать, что это произвольно, если хотите, все наборы команд, которые кто-то (/ группа) сел и решил, какие битовые комбинации будут означать, что, ничем не отличаются здесь. В пространстве набора команд было место с определенными шаблонами, поэтому они использовались. Вполне обычно добавлять инструкции позже в жизни семейства процессоров, например, x86. Плюс ко многим другим, для 8-битного типа x86 или 6502 или чего-либо еще, вы можете использовать 8-битную инструкцию / код операции в качестве вашей следующей новой инструкции или взять этот ранее неиспользуемый байт / код операции и расширить его до многих других, например, вы берете байт / opcode, который не использовался и этот байт теперь означает просмотр следующего байта, этот следующий байт может содержать до 256 новых инструкций или он может просто дополнять первый байт, определяющий регистры или операции, и т. д. c. Ничего не изменилось, в дальнейшем мы расширили набор команд большого пальца, некоторый процент инструкции расходуется, указывая на то, что это инструкция переменной длины, но из этих 32 битов все еще остается довольно много битов, чтобы учесть более крупную инструкцию с большим количеством опций , (но при потере отношения «один к одному» между командами большого пальца и руки все инструкции большого пальца (не расширения большого пальца) отображаются непосредственно в инструкцию полного размера руки).

Каждое ядро ​​отличается, они не все выбирают слово в то же время расширения thumb-2 не обязательно должны быть выровнены, поэтому целая инструкция thumb-2 не обязательно помещается в выровненную выборку слов для процессоров, выполняющих выборку слов. Думайте о (предварительном) сборщике и декодере как о двух отдельных вещах, так как они функционально, декодер берет 16 бит за раз в режиме большого пальца, как это конкретно реализовано? Не знаю Они ждут, пока две половины слова будут готовы, прежде чем расшифровать первую? Не знаю Все ли реализации одинаковы? Не знаю, не ожидал бы. Что касается извлечения, они не такие, как вы можете видеть в документации ARM, и я думаю, что по крайней мере один, если не больше, поставщик чипов может выбрать во время компиляции.

Если вы, например, взяли учебник на основе MIPS и пытаетесь понять другие процессоры, это может сбить с толку, понять, что эти учебники и термины предназначены для понимания и словарного запаса, конвейеры не настолько глубоки в общем и вы вообще не получаете целые инструкции за один раз (x86 не выбирает один байт за раз, он получает много инструкций за один раз). В ris c -v проблема еще хуже, чем в режиме arm и mips, поскольку вы можете иметь 16-битные сжатые инструкции, 32-битные инструкции и 64-битные инструкции, 32-битные инструкции не обязательно должны быть выровнены по ris c -v (ни 64-битный), так что выборка 32 за раз не дает вам целую инструкцию, сборщик отделяется от декодера, как только там достаточно, то декодер может завершиться.

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

Disassembly of section .text:

00000000 <hello-0xe>:
   0:   e005        b.n e <hello>
   2:   bf00        nop
   4:   bf00        nop
   6:   f000 b802   b.w e <hello>
   a:   bf00        nop
   c:   bf00        nop

0000000e <hello>:
   e:   bf00        nop

Да, так что два полусложных слова впереди (pc + 4) в обоих случаях , Было бы значительно сложнее, если бы было две инструкции впереди, как это было раньше, чтобы было легко запомнить. Если бы впереди было две инструкции, то иногда pc + 4, иногда pc + 6, а иногда pc + 8, logi c должен был бы декодировать две инструкции, чтобы узнать, как смещение p c было смещено для первой из два, так что придерживаться pc + 4, как это всегда было для режима большого пальца, - разумный способ сделать это.

...