MyTetra Share
Делитесь знаниями!
Краткая документация по командам ассемблера ARM для процесора Cortex M4
Время создания: 02.04.2024 10:31
Текстовые метки: arm, документация, синтаксис, ассемблер, инструкции, список, перечень, процессор, микропроцессор, контроллер, микроконтроллер, cortex, M4
Раздел: Компьютер - Аппаратное обеспечение - Микроконтроллеры ARM
Запись: xintrea/mytetra_syncro/master/base/17120431198ilvpw0xnr/text.html на raw.github.com

На сайте developer.arm.com имеется документ Cortex-M4 Technical Reference Manual r0p0 с номером DDI 0439 (копия PDF-файла прикреплена к этой записи). Страница с командами Ассемблера расположена по адресу:



https://developer.arm.com/documentation/ddi0439/b/CHDDIGAC



Нумерация r0p0 означает, что релизный номер документа (release) является 0, и номер изменений (path) тоже 0. То есть, это первая версия такста документа, без изменений и дополнений.


В самом документе нижеуказанные сведения находятся в разделе 3.3 на страницах 3-4 - 3-8.


Здесь приведен частичный перевод страницы с командами Ассемблера.



Важно: в данном документе нет полных описаний того, что выполняет та или иная инструкция. Полное описание инструкций доступно в документе ARM Architecture Reference Manual Thumb-2 Supplement под номером DDI 0308D.



* * *


Справочное руководство Cortex-M4 r0p0


Список инструкций микропроцессора Cortex-M4



В данном процессоре реализован набор инструкций по стандарту ARMv7-M Thumb. Таблица 3.1 содержит инструкции Cortex-M4 и количество циклов, затрачиваемых на их выполнение. Количество циклов основано на системе с нулевыми состояниями ожидания.


В синтаксисе ассемблера, в зависимости от операции, поле <op2> может быть заменено на один из следующих вариантов:



  • простой спецификатор регистра, например Rm
  • непосредственно сдвиговый регистр, например Rm, LSL #4
  • регистр сдвигового регистра, например Rm, LSL Rs
  • непосредственно значение, например xE000E000



Примечание: здесь, для краткости, приведены не все режимы адресации при загрузке и сохранении. Дополнительную информацию смотрите в справочном руководстве по архитектуре ARMv7-M (ARMv7-M Architecture Reference Manual).



В таблице 3.1 в столбце "Циклы" используются следующие значения:



P - количество циклов, необходимых для полной загрузки конвейера. Эначение лежит в диапазоне от 1 до 3 в зависимости от ширины целевой инструкции, от того как она выровнена, а также от того, удастся ли процессору заранее вычислить адрес.


B - Количество циклов, необходимых для выполнения барьерной операции. Для DSB и DMB минимальное количество циклов равно нулю. Для ISB минимальное количество циклов эквивалентно количеству, необходимого для полной загрузки конвейера.


N - Количество регистров в списке регистров, подлежащих загрузке или сохранению (включая PC или LR)


W - Количество циклов, затраченных на ожидание соответствующего события.



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


  • Rd - регистр назначения (destination)
  • Rm - регистр, откуда происходит перемещение (move), но не всегда
  • Rn - регистр, содержащий какое-то число (number), обычно источник данных
  • Суффикс W - работа со словом (Word, 16 бит)



Таблица 3.1. Краткое описание набора инструкций Cortex-M4



Operation

Description

Assembler

Cycles

Move

(загрузка значения

в регистр)

Register

MOV Rd, <op2>

1

16-bit immediate

MOVW Rd, #<imm>

1

Immediate into top

MOVT Rd, #<imm>

1

To PC

MOV PC, Rm

1 + P

Add

(сложение)

Add

ADD Rd, Rn, <op2>

1

Add to PC

ADD PC, PC, Rm

1 + P

Add with carry

ADC Rd, Rn, <op2>

1

Form address

ADR Rd, <label>

1

Subtract

(вычитание)

Subtract

SUB Rd, Rn, <op2>

1

Subtract with borrow

SBC Rd, Rn, <op2>

1

Reverse

RSB Rd, Rn, <op2>

1

Multiply

(умножение)

Multiply

MUL Rd, Rn, Rm

1

Multiply accumulate

MLA Rd, Rn, Rm

2

Multiply subtract

MLS Rd, Rn, Rm

2

Long signed

SMULL RdLo, RdHi, Rn, Rm

1

Long unsigned

UMULL RdLo, RdHi, Rn, Rm

1

Long signed accumulate

SMLAL RdLo, RdHi, Rn, Rm

1

Long unsigned accumulate

UMLAL RdLo, RdHi, Rn, Rm

1

Divide

(деление)

Signed

SDIV Rd, Rn, Rm

2 to 12[a]

Unsigned

UDIV Rd, Rn, Rm

2 to 12[a]

Saturate

(ограничение значения

до заданного)

Signed

SSAT Rd, #<imm>, <op2>

1

Unsigned

USAT Rd, #<imm>, <op2>

1

Compare

(сравнение)

Compare

CMP Rn, <op2>

1

Negative

CMN Rn, <op2>

1

Logical

(операции бинарной

логики)

AND

AND Rd, Rn, <op2>

1

Exclusive OR

EOR Rd, Rn, <op2>

1

OR

ORR Rd, Rn, <op2>

1

OR NOT

ORN Rd, Rn, <op2>

1

Bit clear

BIC Rd, Rn, <op2>

1

Move NOT

MVN Rd, <op2>

1

AND test

TST Rn, <op2>

1

Exclusive OR test

TEQ Rn, <op1>

Shift

(сдвиг)

Logical shift left

LSL Rd, Rn, #<imm>

1

Logical shift left

LSL Rd, Rn, Rs

1

Logical shift right

LSR Rd, Rn, #<imm>

1

Logical shift right

LSR Rd, Rn, Rs

1

Arithmetic shift right

ASR Rd, Rn, #<imm>

1

Arithmetic shift right

ASR Rd, Rn, Rs

1

Rotate

(кольцевой сдвиг)

Rotate right

ROR Rd, Rn, #<imm>

1

Rotate right

ROR Rd, Rn, Rs

1

With extension

RRX Rd, Rn

1

Count

(подсчет количества)

Leading zeroes

CLZ Rd, Rn

1

Load

(загрузка из памяти)

Word

LDR Rd, [Rn, <op2>]

2[b]

To PC

LDR PC, [Rn, <op2>]

2[b] + P

Halfword

LDRH Rd, [Rn, <op2>]

2[b]

Byte

LDRB Rd, [Rn, <op2>]

2[b]

Signed halfword

LDRSH Rd, [Rn, <op2>]

2[b]

Signed byte

LDRSB Rd, [Rn, <op2>]

2[b]

User word

LDRT Rd, [Rn, #<imm>]

2[b]

User halfword

LDRHT Rd, [Rn, #<imm>]

2[b]

User byte

LDRBT Rd, [Rn, #<imm>]

2[b]

User signed halfword

LDRSHT Rd, [Rn, #<imm>]

2[b]

User signed byte

LDRSBT Rd, [Rn, #<imm>]

2[b]

PC relative

LDR Rd,[PC, #<imm>]

2[b]

Doubleword

LDRD Rd, Rd, [Rn, #<imm>]

1 + N

Multiple

LDM Rn, {<reglist>}

1 + N

Multiple including PC

LDM Rn, {<reglist>, PC}

1 + N + P

Store

(запись в память)

Word

STR Rd, [Rn, <op2>]

2[b]

Halfword

STRH Rd, [Rn, <op2>]

2[b]

Byte

STRB Rd, [Rn, <op2>]

2[b]

Signed halfword

STRSH Rd, [Rn, <op2>]

2[b]

Signed byte

STRSB Rd, [Rn, <op2>]

2[b]

User word

STRT Rd, [Rn, #<imm>]

2[b]

User halfword

STRHT Rd, [Rn, #<imm>]

2[b]

User byte

STRBT Rd, [Rn, #<imm>]

2[b]

User signed halfword

STRSHT Rd, [Rn, #<imm>]

2[b]

User signed byte

STRSBT Rd, [Rn, #<imm>]

2b

Doubleword

STRD Rd, Rd, [Rn, #<imm>]

1 + N

Multiple

STM Rn, {<reglist>}

1 + N

Push

(укладка значения в стек)

Push

PUSH {<reglist>}

1 + N

Push with link register

PUSH {<reglist>, LR}

1 + N

Pop

(вытаскивание значения

из стека)

Pop

POP {<reglist>}

1 + N

Pop and return

POP {<reglist>, PC}

1 + N + P

Semaphore

(семафор эксклюзивного доступа

для многозадачных

систем)

Load exclusive

LDREX Rd, [Rn, #<imm>]

2

Load exclusive half

LDREXH Rd, [Rn]

2

Load exclusive byte

LDREXB Rd, [Rn]

2

Store exclusive

STREX Rd, Rt, [Rn, #<imm>]

2

Store exclusive half

STREXH Rd, Rt, [Rn]

2

Store exclusive byte

STREXB Rd, Rt, [Rn]

2

Clear exclusive monitor

CLREX

1

Branch

(переход

на заданный адрес,

в других ассемблерах

обычно обозначается

как jump)

Conditional

B<cc> <label>

1 or 1 + P[c]

Unconditional

B <label>

1 + P

With link

BL <label>

1 + P

With exchange

BX Rm

1 + P

With link and exchange

BLX Rm

1 + P

Branch if zero

CBZ Rn, <label>

1 or 1 + P[c]

Branch if non-zero

CBNZ Rn, <label>

1 or 1 + P[c]

Byte table branch

TBB [Rn, Rm]

2 + P

Halfword table branch

TBH [Rn, Rm, LSL#1]

2 + P

State change

(команды изменения

состояния процессора)

Supervisor call

SVC #<imm>

-

If-then-else

IT... <cond>

1[d]

Disable interrupts

CPSID <flags>

1 or 2

Enable interrupts

CPSIE <flags>

1 or 2

Read special register

MRS Rd, <specreg>

1 or 2

Write special register

MSR <specreg>, Rn

1 or 2

Breakpoint

BKPT #<imm>

-

Extend

(расширение числовых

значений до более

широких размеров)

Signed halfword to word

SXTH Rd, <op2>

1

Signed byte to word

SXTB Rd, <op2>

1

Unsigned halfword

UXTH Rd, <op2>

1

Unsigned byte

UXTB Rd, <op2>

1

Bit field

(работа с битовыми

полями)

Extract unsigned

UBFX Rd, Rn, #<imm>, #<imm>

1

Extract signed

SBFX Rd, Rn, #<imm>, #<imm>

1

Clear

BFC Rd, Rn, #<imm>, #<imm>

1

Insert

BFI Rd, Rn, #<imm>, #<imm>

1

Reverse

(получение обратного

порядка байт/бит)

Bytes in word

REV Rd, Rm

1

Bytes in both halfwords

REV16 Rd, Rm

1

Signed bottom halfword

REVSH Rd, Rm

1

Bits in word

RBIT Rd, Rm

1

Hint

(дополнительные

инструкции)

Send event

SEV

1

Wait for event

WFE

1 + W

Wait for interrupt

WFI

1 + W

No operation

NOP

1

Barriers

(синхронизация

через барьеры)

Instruction synchronization

ISB

1 + B

Data memory

DMB

1 + B

Data synchronization

DSB <flags>

1 + B

[a] Операции деления используют раннее завершение, чтобы свести к минимуму количество требуемых циклов, основанных на количестве начальных единиц и нулей во входных операндах.

[b] Рядом расположенные единичные инструкции чтения и записи из памяти могут использовать различные стадии конвейера для размещения адресов и данных. Это позволяет выполнять такие команды за один цикл выполнения.

[c] Условная ветвь выполнения завершается за один цикл, если ветвь не используется.

[d] Инструкция IT может быть объединена с предыдущей 16-разрядной Thumb-командой, что позволяет выполнять ее в нулевых циклах.



Подробное описание команд


Команда MOV



MOV Rd, <op2>



Команда MOV передает значение в регистр.



Примечание: Через MOV нельзя читать из памяти. Нельзя написать MOV R0, [R1] — вместо этого надо использовать инструкцию LDR.



Передача значения из 32-х битного регистра:



MOV R0, R1 ; Передача значения регистра R1 в R0



В качестве принимающего регистра может быть регистр общего назначения, и даже регистр PC:



MOV PC, R0



Передача непосредственного значения, закодированного в машинной инструкции:



MOV R0, #42 ; Передача непосредственного значения в R0



В режиме ARM (32-битные инструкции) можно загрузить 8-битные значения, сдвинутые на чётное число бит (0, 2, 4, ..., 30) влево. Т. е. immediate-значение кодируется в 12 битах: 8 бит - само значение, 4 бита - количество сдвигов (16 возможных значений), причем количество сдвигов умножается на 2.



Примеры допустимых:


0xFF (0xFF << 0)

0x3F00 (0x3F << 8)

0xC0000000 (0xC0 << 24)

0x3FC00000 (0xFF << 22)


Недопустимые:


0x1234 (нельзя представить как 8-битное + четное кол-во сдвигов).



В режиме Thumb (16-битные инструкции) можно передать значение размером 8 бит, команда работает только с R0–R7.


В режиме Thumb-2 (расширеннык 32-битные инструкции) можно загружать 16-битные значения.


Видно, что ни в одном режиме невозможно загрузить 32-х битное значение. Для загрузки 32-х битных значений используются две инструкции: MOVW / MOVT (см. далее).



Передача регистра со сдвигом:



MOV R0, R1, LSL #2 ; R0 = R1 << 2



Поддерживаемые сдвиги:


  • LSL — логический сдвиг влево
  • LSR — логический сдвиг вправо
  • ASR — арифметический сдвиг вправо
  • ROR — циклический сдвиг вправо


Встает вопрос: а что, а ARM-процессорах нет специальных инструкций сдвига регистров? Конечно, есть. Следующие команды будут давать один и тот же результат:



MOV R0, R1, LSL #2

LSL R0, R1, 2



Использование специализированной инструкции вместо MOV может дать в некоторых режимах более компактный машинный код.


Команды MOVW / MOVT


Команда MOVW - расшифровывается как Move Wide, т. е. перемещение значения регистра с расширением до 32-х бит, и в качестве ресширения используются нули. Эта команда загружает непосредственное 16-бит значение в младшие два байта регистра Rd, а старшие два байта обнуляются:



MOVW Rd, #<imm>



Команда MOVT (Move to Top) загружает непосредственное 16-бит значение в старшие два байта регистра Rd. Младшие 2 байта не меняются.



MOVT Rd, #<imm>



Таким образом, эти две команды позволяют за две инструкции загрузить в регистр 32-х битное значение:



MOVW R0, #0x5678 ; младшие 16 бит, регистр R0 станет равен 0x00005678

MOVT R0, #0x1234 ; старшие 16 бит, регистр R0 станет равен 0x12345678



Команда ADD


Простое сложение:



Простое сложение - это сложение без установкии и без учета флага переноса.



ADD Rd, Rn, <op2>



Например:



ADD R0, R1, R2 ; это R0 = R1 + R2

ADD R0, R1, #5 ; это R0 = R1 + 5



Ограничения на непосредственный операнд такие же как и в команде MOV.


С помощью ADD можно увеличивать регистр PC на значение из другого регистра:



ADD PC, PC, Rm



Сложение со сдвигом:



ADD R0, R1, R2, LSL #2 ; это R0 = R1+ (R2 << 2)


Варианты сдвига (LSL, LSR, ASR, ROR) - такие же как у MOV.



Зачем нужна команда сложения со сдвигом? Например для быстрого вычисления адреса пикселя на стандартных экранах через два-три сдвига и пару сложений. Если в процессоре существуют операции "сложение со сдвигом", то можно уместиться в две-три машинные команды, причем не используя умножение. А команды сдвига и сложения в ARM исполняются за один такт. Таким образом за 2 такта можно высчитать адрес, даже если в процессоре нет блока умножения.


К примеру, R1 - это X, R2 - это Y. Если один пиксель занимает 1 байт (да, это 256 цветов на пиксель с использованием палитры), то чтобы получить адрес пикселя, надо Y умножить на ширину экрана (получится адрес начала линии с номером Y), и прибавить X.


Стандартные ширины экранов устроены таким образом, что умножать на ширину можно просто одним-тремя сдвигами. Что имеется в виду? Вот какие ширины бывают:



320 pix (это 256 + 64)

640 pix (это 512 + 128)

800 pix (это 512 + 256 + 32)

1024 pix (это 1024)

1280 pix (это 1024 + 256)

и т.д.



Если ширина 1280, то чтобы получить адрес начала линии с номером Y, надо сделать два сдвига Y и одно сложение:



Адрес начала линии = Y * 1280

= Y * (1024 + 256)

= Y * 1024 + Y * 256

= Y * 2^10 + Y * 2^8

= (Y << 10) + (Y << 8)



А чтобы получить адрес пикселя надо еще прибавить X:



Адрес пикселя = (Y << 10) + (Y << 8) + X



Эти вычисления на ARM укладываются в две команды:



ADD R3, R2, R1, LSL #8 ; R3 = (Y << 8) + X

ADD R0, R3, R1, LSL #10 ; R0 = (Y << 10) + R3



В результате в R0 лежит адрес пикселя.



Команда ADC


Это сложение с учетом бита переноса (Add with carry):



ADC Rd, Rn, <op2>



В качестве второго операнда используются регистр, сдвинутый регистр (см. MOV с LSL) или непосредстванное значение.



... Дописать ...



Прикрепленные файлы:
Так же в этом разделе:
 
MyTetra Share v.0.67
Яндекс индекс цитирования