ФЭНДОМ


Адресное пространство Править

Архитектура ARM использует плоское адресное пространство размером 4 Гбайта. Адресами памяти являются беззнаковые целые числа длиной 32 бита. Физически на эти адреса отображается как собственно память (оперативная и постоянная), так и устройства ввода-вывода.

При вычислении адресов операндов, находящихся в памяти, используется 32-разрядная арифметика, а выход за пределы разрядной сетки игнорируется. Таким образом, при последовательном увеличении адресов после адреса FFFF_FFFF следует адрес 0000_0000, а при последовательном уменьшении — наоборот. Однако код программы не должен пересекать границу памяти: если при последовательном продвижении регистра PC произойдёт «свёртка» адреса, результат будет непредсказуем. Непредсказуемым окажется и результат выполнения инструкций чтения и записи данных, если используемая ими область данных пересекает границу адресов между FFFF_FFFF и 0000_0000.

Порядок следования байтов в многобайтовых величинах Править

Архитектуры до версии ARMv6 предусматривают два порядка следования байтов в полусловах и словах: «младший-старший» (little-endian, LE) и «старший-младший» с постоянным положением слов (big-endian word invariant, BE-32; подробнее эти порядки будут описаны в последующих подразделах). Производители процессоров были вольны сами выбирать, какой из возможных порядков следования байтов поддерживать. Допускалась и поддержка обоих порядков; в этом случае производитель определял, каким образом будет устанавливаться порядок, активный сразу после сброса процессора, и поддерживается ли возможность его программной смены. Теоретически могла возникнуть ситуация, когда процессор после сброса начинал работать с порядком «младший-старший», но был подключен к памяти, поддерживающей порядок «старший-младший»; в таком случае одним из первых действий программы было переключение процессора в режим «старший-младший» (это необходимо было сделать раньше, чем произойдёт первое обращение к байту или полуслову данных или же начнёт выполняться код Thumb).

В версии ARMv6 появилась поддержка смешанного порядка следования байтов (mixed endian), называемого также порядком «старший-младший» с постоянным положением байтов (big-endian byte invariant, BE-8). В отличие от BE-32, порядок BE-8 распространяется только на доступы к данным; при выборке команд при установленном режиме BE-8 используется порядок LE. Все процессоры ARMv6 обязаны поддерживать порядки LE и BE-8; поддержка порядка BE-32 является необязательной.

Порядок LE Править

При порядке LE младший байт полуслова, выровненного по границе полуслова и расположенного по адресу A (он будет кратен 2), находится по адресу A, а старший байт — по адресу A+1. Младший байт слова, выровненного на границу слова и расположенного по адресу A (он будет кратен 4), находится по адресу A, следующий за ним байт — по адресу A+1, третий байт — по адресу A+2 и четвёртый, самый старший байт — по адресу A+3.

Если осуществляется доступ к нескольким словам подряд (например, выполняется считывание двойного слова), то адрес младшего слова будет равен A, следующего за ним — A+4 и так далее.

Возможность доступа по невыровненным адресам определяется версией архитектуры процессора и несколькими управляющими битами. Подробнее об этом будет сказано ниже в соответствующем подразделе.

Порядок BE-32 Править

При порядке BE-32 старший байт полуслова, выровненного по границе полуслова и расположенного по адресу A (он будет кратен 2), находится по адресу A, а младший байт — по адресу A+1. Старший байт слова, выровненного на границу слова и расположенного по адресу A (он будет кратен 4), находится по адресу A, следующий за ним байт — по адресу A+1, третий байт — по адресу A+2 и четвёртый, самый младший байт — по адресу A+3.

Если осуществляется доступ к нескольким словам подряд (например, выполняется считывание двойного слова), то адрес младшего слова будет равен A, следующего за ним — A+4 и так далее, т.е. слова идут в порядке «младший-старший», как и при порядке LE, хотя байты в них расположены в порядке «старший-младший». Именно это обстоятельство подчёркивается в названии данного порядка следования байтов: «старший-младший» с постоянным положением слов.

Возможность доступа по невыровненным адресам определяется версией архитектуры процессора и несколькими управляющими битами. Подробнее об этом будет сказано ниже в соответствующем подразделе.

Порядок BE-8 Править

Как уже указывалось, порядок BE-8 появился в версии ARMv6 и распространяется только на доступы к данным; когда он активен, выборка инструкций производится в соответствии с порядком LE.

В отличие от порядка BE-32, порядок BE-8 не влияет на адреса байтов в памяти: они остаются одинаковыми в порядках LE и BE-8 (именно это подчёркивается названием: порядок «старший-младший» с постоянным положением байтов). Вместо этого при включении режима BE-8 информация, передаваемая между памятью и регистрами процессора, переворачивается «с ног на голову», что и создаёт эффект доступа с порядком следования байтов «старший-младший». Таким образом, младший байт полуслова, расположенного по адресу A, физически находится по адресу A, а старший байт — по адресу A+1, однако в регистре они будут расположены в разрядах 15:8 и 7:0 соответственно. Аналогичным образом, младший байт слова, расположенного по адресу A, физически находится по адресу A, следующий за ним байт — по адресу A+1, третий байт — по адресу A+2 и четвёртый, самый старший байт — по адресу A+3, однако в регистре они займут разряды соответственно 31:24, 23:16, 15:8 и 7:0.

Многословные доступы осуществляются как последовательность обращений к отдельным словам с последовательным увеличением адресов слов. Таким образом, положение слов при порядках BE-8 и LE тоже будет одинаковым.

Возможность доступов по невыровненным адресам зависит от режима работы процессора; подробнее это описывается в одном из следующих подразделов.

Доступы по невыровненным адресам Править

Архитектура ARM традиционно рассчитана на осуществление доступов к памяти по правильно выровненным адресам: это проще в реализации, а также обеспечивает наивысшую производительность. Тем не менее, в определённых ситуациях она позволяет осуществлять обращения к данным по невыровненным адресам. Инструкции всегда должны быть выровнены на правильную границу: команды набора ARM располагаются по границе слова, а команды набора Thumb — по границе полуслова.

Архитектуры, предшествующие ARMv6 Править

Инструкции чтения и записи двойного слова (LDRD и STRD) при обращении по невыровненному адресу дают непредсказуемый результат.

Невыровненные доступы к словам и полусловам подчиняются следующим правилам:

  • если CP15 отсутствует или если бит A равен нулю, обращения к словам и полусловам выполняются по принудительно выровненным адресам: для доступа к слову два младших бита считаются равными нулю, а для доступа к полуслову — один бит;
  • в дополнение к предыдущему, если выполняется операция загрузки слова (команды LDR и LDRT набора ARM и LDR набора Thumb), после выборки из памяти по выровненному адресу осуществляется циклический сдвиг («вращение») считанного значения вправо на число байтов, равное значению двух младших битов адреса.

Архитектура ARMv6 Править

Процессоры архитектуры ARMv6 всегда имеют в своём составе сопроцессор CP15, поэтому позволяют включать или отключать контроль выравнивания (бит A) по мере надобности. Кроме того, у них появился ещё один управляющий бит, U, который позволяет разрешить невыровненные доступы к словам и полусловам в командах LDRH, LDRSH, LDR, LDRT, STRH, STR и STRT набора ARM и их аналогов набора Thumb, а также ослабить контроль выравнивания для команд доступа к двойным словам LDRD и STRD (при установленном бите U задаваемый в них адрес должен быть кратен слову, а при сброшенном – двойному слову). Доступы к памяти в других инструкциях всегда должны быть выровненными независимо от состояния бита U.

Подробнее о выполнении различных видов доступов к памяти будет сказано в одном из следующих подразделов.

Управление порядком следования байтов и невыровненными доступами Править

Для переключения моделей следования байтов и управления невыровненными доступами используется пять битов:

В процессорах версий, предшествовавших ARMv6, может поддерживаться любая из моделей LE и BE-32 или обе вместе — это зависит от конкретной реализации процессора. В последнем случае переключение между ними осуществляется с помощью бита B регистра 1 сопроцессора управления системой CP15: когда он равен нулю, активна модель LE, а когда равен единице — модель BE-32. Обе эти модели распространяются на доступы и к коду, и к данным. В том случае, если необходимо использовать не ту модель, которая устанавливается автоматически после сброса, необходимо изменить значение бита B как можно раньше, до того, как будет выполнен первый доступ к полуслову или слову либо до переключения на выполнение кода Thumb или Jazelle. Другие средства управления порядком байтов и невыровненными доступами в версиях до ARMv6 отсутствуют, хотя из документации можно сделать вывод, что бит A в некоторых процессорах мог присутствовать и ранее.

Процессоры версии ARMv6 всегда поддерживают модели LE и BE-8; модель BE-32 является необязательной. Модель BE-8 распространяется только на данные; когда она активна, для доступа к коду используется модель LE. Бит B реализован только в тех процессорах ARMv6, которые поддерживают все три модели, и используется в целях обеспечения совместимости с предыдущими версиями архитектуры. Остальные четыре бита присутствуют во всех процессорах ARMv6.

При сбросе бит A всегда сбрасывается, что отключает контроль за невыровненными доступами. Остальные четыре бита устанавливаются в зависимости от состояния конфигурационных линий CFGEND[1:0], как показано в следующей таблице.

CFGEND[1:0] EE U B E Описание
00 0 0 0 0 Модель LE для кода и данных без невыровненных доступов
01 0 0 1 0 Модель BE-32 для кода и данных
10 0 1 0 0 Модель LE для кода и данных, поддержка невыровненных доступов
11 1 1 0 1 Модель LE для кода и BE-8 для данных, поддержка невыровненных доступов

Комбинация линий CFGEND[1:0], равная 01, трактуется как 00, если процессор не поддерживает модель BE-32. В тех процессорах, где линии CFGEND[1:0] отсутствуют, устанавливается режим, соответствующий нулевым значениям на этих линиях. В процессорах, предшествовавших ARMv6 и поддерживающих две модели следования байтов, для выбора модели по умолчанию использовалась конфигурационная линия BigEndinit.

Комбинации битов U и A позволяют выбрать следующие варианты работы с невыровненными доступами:

U A Описание
0 0 Унаследованный режим для совместимости с версиями до ARMv6, модели LE и BE-32
0 1 Контроль выравнивания двойных слов на границу 8 байтов, все три модели
1 0 Поддержка невыровненного доступа, модели LE и BE-8
1 1 Контроль выравнивания двойных слов на границу 4 байтов, все три модели

Первый вариант (U и A равны нулю) полностью соответствует работе процессоров до ARMv6. Используемая в нём модель следования байтов определяется битом B. В трёх других вариантах для управления моделью следования байтов используются биты B и E.

Используемая модель следования байтов и реакция на невыровненные доступы в зависимости от состояния битов U, A, B и E приведены в следующей таблице. В ней указаны только допустимые комбинации указанных битов; все остальные варианты являются зарезервированными. Результат выполнения инструкций, устанавливающих зарезервированную комбинацию битов, будет непредсказуемым.

U A B E Модель для инструкций Модель для данных Невыровненные доступы Описание
0 0 0 0 LE LE вращение при загрузке слова унаследованный порядок байтов данных «младший-старший»
0 0 1 0 BE-32 BE-32 вращение при загрузке слова унаследованный порядок байтов данных «старший-младший»
0 1 0 0 LE LE отказ данных контроль выравнивания двойных слов по границе 8 байтов; порядок данных «младший-старший»
0 1 0 1 LE BE-8 отказ данных контроль выравнивания двойных слов по границе 8 байтов; порядок данных «старший-младший»
0 1 1 0 BE-32 BE-32 отказ данных контроль выравнивания двойных слов по границе 8 байтов; унаследованный порядок данных «старший-младший»
1 0 0 0 LE LE нормальный доступ разрешён невыровненный доступ, порядок данных «старший-младший»
1 0 0 1 LE BE-8 нормальный доступ разрешён невыровненный доступ; порядок данных «старший-младший»
1 1 0 0 LE LE отказ данных контроль выравнивания двойных слов по границе 4 байтов; порядок данных «младший-старший»
1 1 0 1 LE BE-8 отказ данных контроль выравнивания двойных слов по границе 4 байтов; порядок данных «старший-младший»
1 1 1 0 BE-32 BE-32 отказ данных контроль выравнивания двойных слов по границе 4 байтов; унаследованный порядок данных «старший-младший»

Выполнение доступов к памяти при разном выравнивании Править

Список видов доступа к памяти и вызывающих эти доступы инструкций приведён в следующей таблице.

Вид доступа Инструкции набора ARM Инструкции набора Thumb
Byte LDRB, LDRBT, LDRSB, STRB, STRBT, SWPB LDRB, LDRSB, STRB
Halfword LDRH, LDRSH, STRH LDRH, LDRSH, STRH
WLoad LDR, LDRT, SWP (только загрузка при U=0) LDR
WStore STR, STRT, SWP (только запись при U=0) STR
WSync SWP (загрузка и запись при U=1)
Two-word LDRD, STRD
Multi-word LDC, LDM, RFE, STC, STM LDMIA, POP, PUSH, STMIA

Как выполняются эти виды доступов при различном выравнивании, показано в следующей таблице. Запись Align(Addr) в этой таблице означает, что используется значение адреса, принудительно выровненное на границу слова, т.е. со сброшенными двумя младшими битами. Обнаружение ошибки выравнивания приводит к возникновению отказа данных.

U A Addr[2:0] Вид доступа Поведение Обращение к памяти Примечания
0 0 Унаследованный режим, без контроля выравнивания
0 0 xxx Byte обычное Byte[Addr]
0 0 xx0 Halfword обычное Halfword[Addr]
0 0 xx1 Halfword непредсказуемое
0 0 xxx WLoad обычное Word[Aling(Addr)] Вращение загруженных данных вправо на число байтов, равное Addr[1:0]
0 0 xxx WStore обычное Word[Aling(Addr)] Операция не зависит от значения Addr[1:0]
0 0 x00 WSync обычное Word[Addr]
0 0 не x00 WSync непредсказуемое
0 0 000 Two-word обычное Word[Addr]
0 0 не 000 Two-word непредсказуемое
0 0 xxx Multi-word обычное Word[Align(Addr)] Операция от значения разрядов Addr[1:0] не зависит
1 0 Доступ без выравнивания, ARMv6
1 0 xxx Byte обычное Byte[Addr]
1 0 xxx Halfword обычное Halfword[Addr]
1 0 xxx WLoad, WStore обычное Word[Addr]
1 0 x00 WSync, Two-word, Multi-word обычное Word[Addr]
1 0 не x00 WSync, Two-word, Multi-word ошибка выравнивания
x 1 Доступ с контролем выравнивания, ARMv6
x 1 xxx Byte нормальное Byte[Addr]
x 1 xx0 Halfword нормальное Halfword[Addr]
x 1 xx1 Halfword ошибка выравнивания
x 1 x00 WLoad, WStore, WSync, Multi-word обычное Word[Addr]
x 1 не x00 WLoad, WStore, WSync, Multi-word ошибка выравнивания
x 1 000 Two-word обычное Word[Addr]
0 1 100 Two-word ошибка выравнивания
1 1 100 Two-word обычное Word[Addr]
x 1 xx1, x1x Two-word ошибка выравнивания

Из описанных выше правил существует несколько исключений, приводящих к непредсказуемым последствиям вместо обычного выполнения (но не вместо отказа данных) соответствующих команд:

  • попытка загрузки в счётчик команд с помощью команды LDR значения по адресу, не кратному 4;
  • попытка загрузки в счётчик команд нового значения с помощью любой инструкции, кроме LDR, LDM, RFE и POP, независимо от выровненности адреса;
  • попытка выполнения любой инструкции, выполняющей доступ к слову, двойному слову или группе слов, если её операндом является память с атрибутом «строго упорядоченная» или «память устройства», а адрес не кратен 4;
  • попытка выполнения любой инструкции, выполняющей доступ к послуслову, если её операндом является память с атрибутом «строго упорядоченная» или «память устройства», а адрес не является чётным.

Невыровненные доступы не обязательно являются атомарными и могут производить к заметному падению производительности.

Инструкции для изменения порядка байтов Править

В процессорах версии ARMv6 предусмотрена инструкция SETEND, имеющаяся в наборах команд ARM и Thumb. Она устанавливает или сбрасывает бит E текущего регистра состояния программы.

Для программного изменения порядка следования байтов в регистрах общего назначения процессоры ARMv6 имеют команды REV, REVSH и REV16, также присутствующие в системах команд ARM и Thumb.