Описание ARM

ИЮЛ | МАР | апр
| 13 |
2012 | 2013 | 2014

33 captures 18 янв 07 - 13 мар 13 |

Close Help

Описание ARM

# Оглавление

- Введение
- 1 Краткая история ARM
- 2 Архитектура ARM
- 3 Регистры ARM
- 4 Hабор команд

  4.1 Команды обработки данных

  4.2 Команды загрузки и сохранения

  4.3 Команды переходов

- 5 Общие операции

  5.1 Засылка в регистр большого значения

  5.2 Повторение нескольких команд

- 6 Порядок взаимодействия с ОС WindowsCE

  6.1 Регистры

  6.2 Строение стека задачи

  6.3 Указатель окна FP и указатель стека SP

  6.4 Пролог

  6.5 Эпилог

- 7 Справочник по командам

  7.1 Принятые обозначения

  7.2 Команды

  - 7.2.1 Арифметические команды
  - 7.2.2 Команды пересылок и логические команды
  - 7.2.3 Команды для работы с памятью
  - 7.2.4 Команды переходов

  7.3 Гибкое 2-е данное (Г2Д)

  7.4 Адресация памяти

  - 7.4.1 Адресация слов и беззнаковых байт (АСББ)
  - 7.4.2 Адресация полуслов и знаковых байт (АПЗБ)
  - 7.4.3 Изменение регистра основы (ИРО)

  7.5 Коды условий (КУ)

# Введение

В данном руководстве приводятся сведения по ARM-процессорам, необходимые для понимания работы Малого Преобразователя Глагола, который производит ARM код, работающий под управлением PocketPC. В конце руководства приводится справочник по всем используемым командам.

# 1 Краткая история ARM

Первый ARM-процессор (ARM – сокращение от Advanced RISC Machine) был спроектирован и изготовлен Acorn Computer Group в середине 80-х. В 1990 Acorn вместе с Apple Computer создали новую компанию под названием Advaced RISC Machines Ltd. В наши дни ARM Ltd не производит процессоров, а только проектирует их и продаёт разрешения на изготовление процессоров третьим производителям. XScale процессоры от Intel тоже разработаны на основе ARM. На текущий момент существует несколько версий архитектуры ARM-процессоров, которые, в основном, отличаются наборами команд в части плавающей и векторной арифметики. В данном руководстве рассматривается архитектура 4-го издания, набор команд которой поддерживается всеми современными ARM-процессорами. Плавающая и векторная арифметика в данном руководстве не рассматривается.

# 2 Архитектура ARM

ARM – это 32-х разрядный процессор с RISC-архитектурой. RISC - сокращение от Reduced Instruction Set Computer – машина с сокращённым набором команд, ориентированная на быстрое выполнение относительно небольшого набора встроенных команд. ARM имеет архитектуру вида "загрузить/сохранить", где команды, обрабатывающие данные, могут работать только с регистрами, а не с памятью напрямую. Поддерживаются команды многократной загрузки и сохранения, а также условное выполнение всех команд. Каждая команда имеет одну и ту же длину – 32 разряда.

# 3 Регистры ARM

У ARM есть 16 видимых 32-х разрядных регистров: с R0 по R15. Для упрощения можно считать, что есть 13 регистров общего назначения – с R0 по R11, и четыре регистра, которым отведена особая роль в Глагол-приложениях:

R12 или FP – указатель окна

R13 или SP – указатель стека

R14 или LR – адрес возврата

R15 или PC – счётчик команд

Перед выполнением каждой команды R15 увеличивается на 4 (размер команды в байтах). Когда вызывается задача по команде BL (см. далее), то в R14 помещается адрес следующей за BL команды. Возврат из задачи осуществляется занесением данного значения обратно в программный счетчик R15.

При заполнении стека указатель SP обычно уменьшается и указывает на последнее, записанное в него слово. Например, после занесения последовательно в стек чисел 1, 2 и 3 память будет выглядеть следующим образом:

| адрес | значение
SP -> | n-8 | 3
| n-4 | 2
| n | 1

Учтите, что для указателя окна FP в PocketPC (см. далее) обычно выделяется R11, а не R12.

# 4 Hабор команд

Как было написано выше, в ARM, как и в большинстве других RISC, длина двоичного кода команды постоянная. Старшие четыре разряда команды всегда используются для задания кода условия КУ, при котором данная команда будет выполняться.

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

Для лучшего понимания возможностей команд будем также рассматривать и их двоичный код.

## 4.1 Команды обработки данных

Команды обработки данных в общем случае имеют следующий вид:

    <команда>  <регистр назначения>, <1-е данное>, <2-е данное>

<регистр назначения> – регистр (R0-R15), в который записывается результат выполненной команды, <1-е данное> также может быть одним из 15 регистров, а <2-е данное> может быть регистром, смещенным регистром или непосредственным значением. Таким способом задаются команды сложения, вычитания, пересылки и логические команды.

Примеры:

сложение | ADD R1,R1,#10 | R1:=R1+10
вычитание | SUB R1,R1,#0 x10 | R1:=R1-16
логическое И | AND R0,R1,R2 | R0:=R1 AND R2
логическое искл. ИЛИ | EOR R0,R1,#10 | R0:=R1 XOR 10
логическое ИЛИ | ORR R0,R1,R2 | R0:=R1 OR R2
пересылка | MOV R2,R0 | R2:=R0

Заметьте, что в записи команд перед числами всегда ставится "#", а шестнадцатеричные числа начинаются с "0x".

В двоичном коде команд присутствуют: код условия выполнения команды КУ, код производимого действия КД, регистр назначения Rd, регистр первого данного Rn и регистр Rm или постоянная для второго данного. Необычная, но полезная особенность – разряды второго данного перед выполнением заданного действия могут быть передвинуты на любое место 32-х разрядного слова.

РРРР | РРР | РРРРР | РРРР | РРРР | РРРРР | РР | Р | РРРР
4 | 3 | 5 | 4 | 4 | 5 | 2 | 1 | 4
КУ | 000 | КД | Rn | Rd | k | сс | 0 | Rm

    ADD  Rd, Rn, Rm, LSL k          ; Rd:=Rn+(Rm LSL k)

РРРР | РРР | РРРРР | РРРР | РРРР | РРРР | Р | РР | Р | РРРР
4 | 3 | 5 | 4 | 4 | 4 | 1 | 2 | 1 | 4
КУ | 000 | КД | Rn | Rd | Rs | 0 | сс | 1 | Rm

    SUB  Rd, Rn, Rm, LSR Rs         ; Rd:=Rn-(Rm LSR Rs)

При этом способ сдвига разрядов (сс) может быть задан как:

LSL – логический сдвиг влево

ASL – арифметический сдвиг влево

LSR – логический сдвиг вправо

ASR – арифметический сдвиг вправо

ROR – вращение вправо

RRX – однократное вращение вправо с флагом переноса.

Одной из причуд ARM является то, что для непосредственного числового значения выделяется область только из 8 разрядов. Это очень неприятное ограничение, и досадно, что при этом в каждой команде тратится 4 разряда на код условия КУ выполнения команды, хотя эта возможность обычно используется только в командах условного перехода. И для сдвига этого 8-ми разрядного числа можно использовать только правое вращение на чётное число разрядов.

РРРР | РРР | РРРРР | РРРР | РРРР | РРРР | РРРРРРРР
4 | 3 | 5 | 4 | 4 | 4 | 8
КУ | 000 | КД | Rm | Rd | k | число8пв

    ORR  Rd, Rm, число8пв ROR 2*k   ; Rd:= Rm OR (число8пв ROR (2* k))
    MOV  Rd, число8пв ROR 2*k       ; Rd:=число8пв ROR (2*k)

## 4.2 Команды загрузки и сохранения

Загрузить в регистр Rd значение из памяти:

    LDR Rd, <адрес>

Пример: LDR R0,[R1] загружает в R0 32-х разрядное слово из памяти с адресом, хранящимся в R1. Также существуют команды, ответственные за загрузку 8 и 16 разрядных данных и соответствующие команды, сохраняющие содержимое регистров в памяти.

Сохранить значение регистра Rd в памяти:

    STR   Rd, <адрес>

Сохранить младшие 8 разрядов регистра Rd в памяти:

    STRB  Rd, <адрес>

ARM также поддерживает сохранение/загрузку нескольких регистров – команда STM (сохранить несколько регистров в памяти):

    STM<ИРО>  Rd{!}, <список регистров>

Где ИРО – изменение регистра основы, см. последующие примеры. Регистр основы Rd содержит начальный адрес памяти, куда будет производиться запись значений регистров, перечисленных в списке команды. Регистр основы может быть любым регистром, но обычно используется указатель стека SP. Например:

    STMDB SP!, {R0-R3,R6}

сохраняет последовательно регистры R6, R3, R2, R1 и R0 в стеке, уменьшая перед каждой пересылкой регистр основы SP на 4 байта (<ИРО> = DB – сокращение от Decrement Befor e). Очевидно, что после выполнения данной команды регистр основы (указатель стека) будет указывать туда, где сохранён регистр R0. Знак "!" после SP обозначает то, что регистр основы будет обновляться после каждого переноса данных. Если бы этого знака не было, то после выполнения команды оказалось бы, что SP остался прежним, а все регистры последовательно сохранялись бы в одну и ту же ячейку по адресу SP-4.

Команда LDM служит для одновременной загрузки нескольких регистров из памяти. Пример:

    LDMIA SP!, {R0-R3,R6}

восстанавливает последовательно регистры R0, R1, R2, R3 и R6 из стека, увеличивая после каждой пересылки регистр основы SP на 4 байта (<ИРО> = IA – сокращение от Increment After).

Есть некоторые неудобства в командах загрузки и сохранения в память. Адрес в этих командах вычисляется или как сумма значений двух регистров (значение одного из этих регистров предварительно может быть сдвинуто), или как сумма регистра и смещения. А для области смещения отведено всего лишь 12 разрядов. Было бы гораздо лучше для этих целей иметь 16 разрядов. Вместо этого существует богатое разнообразие способов вычисления и сохранения адресов доступа:

РРРР | РРР | РРРРР | РРРР | РРРР | РРРРРРРРРРРР
4 | 3 | 5 | 4 | 4 | 12
КУ | 01 0 | КД | Rn | Rd | смещение12

    LDR  Rd, [Rn,#-смещение12]    ; Rd:=[Rn-смещение12]
    LDR  Rd, [Rn,#+смещение12]!   ; адр:=Rn+смещение12, Rd:=[адр], Rn:=адр
    LDR  Rd, [Rn],#-смещение12    ; Rd:=[Rn], Rn:=[Rn-смещение12]

РРРР | РРР | РРРРР | РРРР | РРРР | РРРРР | РР | Р | РРРР
4 | 3 | 5 | 4 | 4 | 5 | 2 | 1 | 4
КУ | 011 | КД | Rn | Rd | k | сс | 0 | Rm

    LDR  Rd, [Rn,-Rm,LSL k]       ; Rd:=[Rn+((-Rm) LSL k)]
    STR  Rd, [Rn,Rm,LSR k]        ; [Rn+(Rm LSR k)]:=Rd
    STR  Rd, [Rn,-Rm,ROR k]!      ; адр:=Rn+((-Rm) ROR k), [адр]:=Rd, Rn:=адр
    STR  Rd, [Rn],Rm,ASR k        ; [Rn]:=Rd, Rn:=Rn+(Rm ASR k)

РРРР | РРР | РРРРР | РРРР | РРРРРРРРРРРРРРРР
4 | 3 | 5 | 4 | 16
КУ | 011 | КД | Rn | {регистры}

    LDMDB  Rn,  {регистры}        ; Повторять: Ri:=[ Rn-4]
    LDMDA  Rn!, {регистры}        ; Повторять: Ri:=[ Rn], Rn:=Rn-4
    STMIB  Rn,  {регистры}        ; Повторять: [Rn+4]:= Ri
    STMIA  Rn!, {регистры}        ; Повторять: [Rn+4]:= Ri, Rn:=Rn+4
    STMDB  Rn!, {регистры}        ; Повторять: Rn:= Rn-4, [Rn]:=Ri

## 4.3 Команды переходов

Есть две такие команды:

переход:

    B   <адрес>

и переход с возвратом:

    BL  <адрес>

После выполнения этих команд значение счётчика команд PC увеличится на <адрес>- PC байт. И, как было упомянуто выше, после выполнения перехода с возвратом дополнительно в LR будет занесён адрес следующей команды.

Командам переходов предоставлена область для смещения (слов) в 24 разряда, что позволяет совершать относительные переходы на +-32Мб.

РРРР | РРР | Р | РРРРРРРРРРРРРРРРРРРРРРРР
4 | 3 | 1 | 24
КУ | 101 | L | смещение24

    B    смещение24*4               ; R15:=R15+смещение24*4
    BL   смещение24*4               ; R14:=R15, R15:=R15+смещение24*4

# 5 Общие операции

## 5.1 Засылка в регистр большого значения

Так как все команды на ARM занимают всего лишь 32 бита, включая код действия, код условия выполнения и код данных, то нет никакого способа за одну команду непосредственно заслать в регистр большое значение. Эту трудность можно преодолеть с помощью сдвигов.

Например, чтобы заслать в R0 шестнадцатеричное число 0x2008, нам нужно выполнить следующие команды:

             MOV   R0, #8             ; R0:=8
             ADD   R0, R0, R0,LSL #10 ; R0:=8+(0x8 LSL 10)

Эту же засылку можно сделать, используя неявный сдвиг:

             MOV   R0, #0x2000        ; R0:=0x2 ROR (10*2)
             ADD   R0, R0, #8         ; R0:=0x2000+8

В крайнем случае, можно загрузить постоянную и из памяти:

             LDR   R0, |пост|         ; R0:=[пост]
             B     |пост|+4           ; Переход через слово данных
    |пост|   DCD   0 x2008            ; пост=0x2008

Или то же самое без метки |пост|:

             LDR   R0, [PC]
             B     .+8
             DCD   0x2008

В последнем примере "." обозначает (для преобразователя кода) адрес текущей команды, а DCD ( Define constant data) - заполнение памяти (4 байта) данным числом.

## 5.2 Повторение нескольких команд

Предположим, что нам нужно сконструировать код, который будет повторяться 3 раза подряд. Обычно это делается так:

             MOV   R0, #3     ; счётчик повторов
    |кольцо| ...
             SUB   R0, R0, #1 ; R0:=R0-1
             CMP   R0, #0     ; проверяем, R0=0
             BNE   |кольцо|   ; если Z-флаг!=1, то переход к метке кольцо

Этот код можно улучшить, используя команду SUB с суффиксом S, при использовании которого выставляются все флаги, в т.ч. и Z-флаг.

             MOV   R0, #3
    |кольцо| ...
             SUBS  R0, R0, #1
             BNE   |кольцо|

# 6 Порядок взаимодействия с ОС WindowsCE

## 6.1 Регистры

Следующая таблица показывает роль регистров при вызове задач ОС:

Регистр | Синоним | Назначение | Использование
R0-R3 |  | 1-4 слово приёмников | временный
R4-R10 |  |  | охраняемый
R11 | FP | указатель окна | охраняемый
R12 | IP | начальный SP | временный
R13 | SP | указатель стека | охраняемый
R14 | LR | адрес возврата | охраняемый
R15 | PC | счётчик команд |

Ответ задачи возвращается через R0.

Регистры R0-R3 содержат первые 4 слова приёмников задачи. Оставшиеся слова при необходимости размещаются в стеке. Охраняемые регистры задача должна оставить неизменными после окончания своей работы.

## 6.2 Строение стека задачи

Стек задачи создаётся в прологе, а оканчивает работу в эпилоге. Он строится из области сохранённых регистров – ОСР, и собственной области задачи – СОЗ. ОСР содержит значения тех охраняемых регистров, которые задача может затереть при своей работе. А СОЗ - это память для собственных переменных задачи. Для ссылки на ОСР и СОЗ обычно используется указатель окна FP.

Если задаче требуются регистры R0-R4, или если ей требуется адрес приёмника, который хранится в R0-R4, то в прологе задача может сохранить данные регистры в ОСР.

## 6.3 Указатель окна FP и указатель стека SP

Если задача не сохраняет охраняемые регистры, не выделяет память для своих переменных и память под источники вызываемых задач, то ей не нужен указатель окна FP.

Если задача использует указатель окна FP, то она не имеет права его изменять между прологом и эпилогом. А задачи без указателя окна FP не имеют права изменять указатель стека SP.

Значение указателя стека SP никогда не должно превышать адреса ОСР. Это предохраняет сохранённые значения от затирания при внешних прерываниях, которые могут произойти при работе пролога или эпилога.

Указатель окна FP и указатель стека SP всегда необходимо выравнивать по границе слова.

## 6.4 Пролог

Пролог состоит из трёх неразрывных частей:

1. Копирование указателя стека SP в R12. Далее R12 будет использоваться для вычисления указателя окна FP.

2. При необходимости сохранение в СОЗ приёмников из R0-R4 и охраняемых регистров с одновременной настройкой указателя стека SP на новую вершину.

3. Захват памяти для собственных переменных задачи посредством вычитания из SP размера переменных (выровненного на границу слова). Если размер не помещается в одну инструкцию, то для его временного хранения используется регистр FP.

Пример пролога с окном.

    MOV    R12, SP            ; 1 часть
    STMDB  SP!, {R0-R3}       ; 2 часть
    STMDB  SP!, {R4-R12, LR}  ; 2 часть
    SUB    FP,  R12, #16      ; 3 часть: 16 байт для переменных задачи

Пример пролога без окна.

    MOV    R12, SP            ; 1 часть
    STMDB  SP!, {R0-R3}       ; 2 часть
    STMDB  SP!, {R4-R12, LR}  ; 2 часть

Пример пролога без окна и использования R12.

    STMDB  SP!, {...,LR}      ; 1 и 2 часть

## 6.5 Эпилог

Эпилог предназначен для восстановления охраняемых регистров.

Если использовалось окно, то в качестве регистра основы при восстановлении всех регистров (включая PC и SP) необходимо использовать указатель окна FP, а не указатель стека SP.

Пример эпилога с окном:

    LDMIA  FP!, {R4-FP, SP, PC}

Пример эпилога без окна:

    LDMIA  SP!, {R4-FP, SP, PC}

# 7 Справочник по командам

## 7.1 Принятые обозначения

Rd | регистр назначения
Rn | регистр основания, регистр 1-го данного
Rm | регистр данного
Rs | регистр сдвигов, регистр множителя
{КУ} | если присутствует, то команда будет выполняться только при состоянии процессора, которое соответствует заданному условию, см. Коды условий
{S} | если присутствует, то флаги условий будут обновлены в соответствии с ответом
{!} | если присутствует, то регистр основы Rn будет обновлён после переноса данных
<Г2Д> | см. Гибкое 2-е данное
<реги> | список разделённых запятыми регистров, заключённый в фигурные скобки
<число N> | N разрядное число
<АСББ> | см. Адресация слов и беззнаковых байт
<АПЗБ> | см. Адресация полуслов и знаковых байт
<ИРО> | см. Изменение регистра основы
+/- | + или - (+ может быть опущен)

## 7.2 Команды

### 7.2.1 Арифметические команды

Действие | Код | Флаги c S | Поведение
Сложение | ADD{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Rn+Г2Д
с переносом | ADC{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Rn+Г2Д+Перенос
Вычитание | SUB{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Rn-Г2Д
с переносом | SBC{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Rn-Г2Д-NOT(Перенос)
обратное | RSB{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Г2Д-Rn
обратное с переносом | RSC{КУ}{S} Rd,Rn,<Г2Д> | N Z C V | Rd:=Г2Д-Rn-NOT(Перенос)
Умножение | MUL{КУ}{S} Rd,Rm,Rs | N Z | Rd:=(Rm*Rs)[31:0]
с накоплением | MLA{КУ}{S} Rd,Rm,Rs,Rn | N Z | Rd:=((Rm*Rs)+Rn)[31:0]
широкое | SMULL{КУ}{S} RdМл,RdСт,Rm,Rs | N Z | RdСт,RdМл:=Rm*Rs
широкое с накоплением | SMLAL{КУ}{S} RdМл,RdСт,Rm,Rs | N Z | RdСт,RdМл:=RdСт,RdМл+Rm*Rs
широкое беззнаковое | UMULL{КУ}{S} RdМл,RdСт,Rm,Rs | N Z | RdСт,RdМл:=БезЗн(Rm*Rs)
широкое беззнаковое с накоплением | UMLAL{КУ}{S} RdМл,RdСт,Rm,Rs | N Z | RdСт,RdМл:=БезЗн(RdСт,RdМл+Rm*Rs)

### 7.2.2 Команды пересылок и логические команды

Действие | Код | Флаги c S | Поведение
Пересылка | MOV{КУ}{S} Rd,<Г2Д> | N Z C | Rd:=Г2Д
отрицательная | MVN{КУ}{S} Rd,<Г2Д> | N Z C | Rd:=0 FFFFFFFFH EOR Г2Д
И | AND{КУ}{S} Rd,Rn,<Г2Д> | N Z C | Rd:=Rn AND Г2Д
Искл. ИЛИ | EOR{КУ}{S} Rd,Rn,<Г2Д> | N Z C | Rd:=Rn EOR Г2Д
ИЛИ | ORR{КУ}{S} Rd,Rn,<Г2Д> | N Z C | Rd:=Rn OR Г2Д
Проба | TST{КУ} Rn,<Г2Д> | N Z C | Обновить флаги для (Rn AND Г2Д)
Проба на равенство | TEQ{КУ} Rn,<Г2Д> | N Z C | Обновить флаги для (Rn EOR Г2Д)
Сравнение | CMP{КУ}{S} Rn,<Г2Д> | N Z C V | Обновить флаги для (Rn-Г2Д)
отрицательное | CMN{КУ}{S} Rn,<Г2Д> | N Z C V | Обновить флаги для (Rn+Г2Д)
Очистка разрядов | BIC{КУ}{S} Rd,Rn,<Г2Д> | N Z C | Rd:=Rn AND NOT Г2Д

### 7.2.3 Команды для работы с памятью

Действие | Код | Поведение | Примечание
Загрузка слова | LDR{КУ} Rd,<АСББ> | Rd:=[адрес] | Rd не м.б. R15
Загрузка PC | LDR{КУ} R15,<АСББ> | R15:=[адрес][31:1] |
Загрузка байта | LDR{КУ}B Rd,<АСББ> | Rd:=РасшНулём [адрес] [7:0] | Rd не м.б. R15
знаковая | LDR{КУ}SB Rd,<АПЗБ> | Rd:=РасшЗнаком [адрес] [7:0] | Rd не м.б. R15
Загрузка полслова | LDR{КУ}H Rd,<АПЗБ> | Rd:=РасшНулём [адрес] [15:0] | Rd не м.б. R15
знаковая | LDR{КУ}SH Rd,<АПЗБ> | Rd:=РасшЗнаком [адрес] [15:0] | Rd не м.б. R15
Загрузка составная | LDM{КУ}<ИРО> Rn{!},<реги> | Загрузить в регистры значения из [Rn] | в R15 только [31:1]
Сохранение слова | STR{КУ} Rd,<АСББ> | [адрес]:=Rd |
Сохранение байта | STR{КУ}B Rd,<АСББ> | [адрес ][7:0]:=Rd[7:0] |
Сохранение полслова | STR{КУ}H Rd,<АПЗБ> | [адрес ][15:0]:=Rd[15:0] |
Сохранение составное | STM{КУ}<ИРО> Rn{!},<реги> | Сохранить значения регистров в [Rn] |
Обмен словами | SWP{КУ} Rd,Rm,[Rn] | вр:=[Rn], [Rn]:=Rm, Rd:=вр |
Обмен байтами | SWP{КУ}B Rd,Rm,[Rn] | вр:=РасшНулём[Rn][7:0], [Rn][7:0]:=Rm[7:0], Rd:=вр |

### 7.2.4 Команды переходов

Действие | Код | Поведение | Примечание
Переход | B{КУ} метка | R15 :=метка | Метка в пределах +-32Мб от тек. команды
с возвратом | BL{КУ} метка | R15:=метка, R14:=адрес след. команды | Метка в пределах +-32Мб от тек. команды

## 7.3 Гибкое 2-е данное (Г2Д)

Код | Значение | Примечание
#<число8пв> | 32-разрядное число, полученное вращением 8-разрядного числа на чётное число разрядов вправо | Пример: #0x10000000, т.к. 0 x10000000=0x10 ROR (4*2)
Rm, LSL #<сдвиг> | непосредственный логический сдвиг Rm влево | Разрешен сдвиг на 0-31 разрядов
Rm, LSR #<сдвиг> | непосредственный логический сдвиг Rm вправо | Разрешен сдвиг на 1-32 разрядов
Rm, ASR #<сдвиг> | непосредственный арифметический сдвиг Rm вправо | Разрешен сдвиг на 1-32 разрядов
Rm, ROR #<сдвиг> | непосредственное вращение Rm вправо | Разрешен сдвиг на 1-31 разрядов
Rm | Rm |
Rm, RRX | однократное вращение вправо Rm с флагом переноса |
Rm, LSL Rs | логический сдвиг Rm влево на Rs разрядов |
Rm, LSR Rs | логический сдвиг Rm вправо на Rs разрядов |
Rm, ASR Rs | арифметический сдвиг Rm вправо на Rs разрядов |
Rm, ROR Rs | вращение Rm вправо на Rs разрядов |

## 7.4 Адресация памяти

### 7.4.1 Адресация слов и беззнаковых байт (АСББ)

Вычисления адреса | Смещение | Код | Примечание
До доступа | Непосредственное | [Rn, #+/-<число12>]{!} |
Без смещения | [Rn] | Равнозначно [Rn,#0]
Регистровое | [Rn, +/-Rm]{!} |
Взвеш. регистровое | [Rn, +/-Rm, LSL #<сдвиг>]{!} | Разрешен сдвиг на 0-31 разрядов
[Rn, +/-Rm, LSR #<сдвиг>]{!} | Разрешен сдвиг на 1-32 разрядов
[Rn, +/-Rm, ASR #<сдвиг>]{!} | Разрешен сдвиг на 1-32 разрядов
[Rn, +/-Rm, ROR #<сдвиг>]{!} | Разрешен сдвиг на 1-31 разрядов
[Rn, +/-Rm, RRX]{!} |
После доступа | Непосредственное | [Rn], #+/-<число12> |
Регистровое | [Rn], +/-Rm |
Взвеш. регистровое | [Rn], +/-Rm, LSL #<сдвиг> | Разрешен сдвиг на 0-31 разрядов
[Rn], +/-Rm, LSR #<сдвиг> | Разрешен сдвиг на 1-32 разрядов
[Rn], +/-Rm, ASR #<сдвиг> | Разрешен сдвиг на 1-32 разрядов
[Rn], +/-Rm, ROR #<сдвиг> | Разрешен сдвиг на 1-31 разрядов
[Rn], +/-Rm, RRX |

### 7.4.2 Адресация полуслов и знаковых байт (АПЗБ)

Вычисления адреса | Смещение | Код | Примечание
До доступа | Непосредственное | [Rn, #+/-<число8>]{!} |
Без смещения | [Rn] | Равнозначно [Rn,#0]
Регистровое | [Rn, +/-Rm]{!} |
После доступа | Непосредственное | [Rn], #+/-<число8> |
Регистровое | [Rn], +/-Rm |

### 7.4.3 Изменение регистра основы (ИРО)

Код | Сокращение от | Регистр основы
IA | Increment After | увеличивать после
IB | Increment Befor | увеличивать до
DA | Decrement After | уменьшать после
DB | Decrement Befor | уменьшать до

## 7.5 Коды условий (КУ)

Код | Сокращение от | Условие
EQ | Equal | равно
NE | Not equal | не равно
CS/HS | Carry Set / Unsigned higher or same | есть перенос / старше или такое же
CC/LO | Carry Clear / Unsigned lower | нет переноса / младше
MI | Minus | отрицательно
PL | Plus | положительно или 0
VS | Overflow | переполнено
VC | No overflow | не переполнено
HI | Unsigned higher | старше
LS | Unsigned lower or same | младше или такое же
GE | Signed greater than or equal | больше или равно
LT | Signed less than | меньше
GT | Signed greater than | больше
LE | Signed less than or equal | меньше или равно
AL | Always | всегда (обычно опускается)

Сделано в России