Однократная передача данных (LDR, STR)
Эти команды будут выполнены, если условие истинно. Все различные условия их выполнения перечислены в таблице 6. Машинный код обеих команд приведен на рис.23.
Команды однократной передачи данных используются для чтения из памяти и записи в память данных в виде нескольких байт или слов. Адрес ячейки памяти, используемой в этих командах передачи, вычисляется посредством сложения или вычитания с некоторым смещением относительно указанного базового регистра. Если требуется применение автоиндексации, то результат этого вычисления может быть записан обратно в этот же базовый регистр.
Рис. 23. Команды однократной передачи данных (LDR и STR)
Смещения и автоиндексирование
Смещение относительно базового регистра может быть задано либо в виде 12-битной константы, указанной в коде команды, или в виде второго регистра-операнда (при выполнении команды его содержимое может быть подвергнуто логическому сдвигу), а само смещение может быть либо добавлено (U=1), либо вычтено (U=0) из базового регистра Rn. Такие модификации смещения могут быть выполнены либо до выполнения пересылки (пред-индексация, P=1) или после нее (постиндексация, P=0).
Бит W позволяет выбрать режим адресации: инкремент или декремент. Модифицированное значение базового адреса либо записывается обратно в него же (W=1), либо остается без изменений (W=0). В случае постиндексной адресации бит W теряет смысл и поэтому обнуляется, в этом случае можно сохранить прежнее значение базового адреса посредством установки смещения, равным нулю. Передача данных с постиндексированием всегда модифицируют содержимое базового адреса.
Только в привилегированном режиме допустимо использование бита W вместе пост-индексной передачей данных. В этом случае при установке бита W происходит принудительное выполнение команды передачи в непривилегированном режиме, тем самым позволяя операционной системе вычислить адрес задачи пользователя (процесса, потока и т.п.) для последующей передаче ей управления в тех системах, в которых наиболее оправдано применение аппаратных средств управления памятью.
Операции сдвига регистра, определяющего смещение
Восемь бит, управляющих операцией сдвига, подробно разъяснены в описании команд обработки данных (см. выше). Однако команды однократной передачи данных не поддерживают возможности указания числа операций сдвига с помощью регистра общего назначения (см. описание операций сдвига).
Байты и слова
Команды этого класса могут быть использованы для передачи данных между регистрами ARM7TDMI и ячейками памяти либо по одному байту (B=1), либо словарно (B=0). Результаты выполнения команд LDR(B) и STR(B) зависят от состояния сигнала BIGEND, вариации которого описаны ниже.
Режим Little-Endian
Команда чтения байта (LDRB) считывает данные с шины данных D[7:0], если адрес байта находится на границе слова, с D[15:8] - если адрес на единицу больше и т.д. После чего прочитанный байт размещается в младших 8-ми битах регистра-получателя, а остальные байты этого регистра заполняются нулями (см. рис. 5).
Команда записи байта (STRB) вычитывает из регистра-источника младшие 8 бит (младший байт), копируя его четырежды по всей ширине шины данных: D[31:24], D[23:16], D[15:8] и D[7:0]. Система управления внешней памятью (если используется), должна активизировать работу соответствующего узла для возможности чтения/записи одного байта.
Рис. 24. Адресация со смещением в режиме Little-Endian
Команда чтения слова (LDR) будет выполняться обычным способом, т.к. адрес слова изначально находится на границе слова. Однако если есть некоторое смещение адреса относительно границы слова, то данные будут циклически сдвинуты внутри регистра таким образом, чтобы адресованный байт был размещен в битах [7:0]. Это означает, например, что половина слова (16 бит) со смещением 0 или 2 относительно границы целого слова будет корректно загружена в биты [15:0] регистра. Еще две команды сдвига требуются для очистки или заполнения старших 16-ти бит (см. рис. 24).
Команда записи слова (STR) выполняется только для адреса, выровненного относительно границы слова. В противном случае, то это слово не будет размещено на шине данных. Другими словами, например, бит 31 сохраняемого регистра всегда будет размещен в соответствующем бите 31 на шине данных.
Режим Big-Endian
Команда чтения байта (LDRB) считывает данные с шины данных D[31:24], если адрес байта находится на границе слова, с D[23:16] - если адрес на единицу больше и т.д. После чего прочитанный байт размещается в младших 8-ми битах регистра-получателя, а остальные байты этого регистра заполняются нулями (см. рис. 4).
Команда записи байта (STRB) вычитывает из регистра-источника младшие 8 бит (младший байт), копируя его четырежды по всей ширине шины данных: D[31:24], D[23:16], D[15:8] и D[7:0]. Система управления внешней памятью (если используется), должна активизировать работу соответствующего узла для возможности чтения/записи одного байта.
Команда чтения слова (LDR) во время своего выполнения сформирует адрес, выровненный относительно границы слова. Адрес со смещением 0 или 2 (в байтах) относительно границы слова вызовет выполнение циклического сдвига внутри регистра таким образом, чтобы адресованный байт был размещен в битах [31:24]. Это означает, что доступное полуслово (16 бит) по этим смещениям будет корректно загружено в биты [31:16] регистра. Адрес со смещением 1 или 3 относительно границы слова вызовет выполнение циклического сдвига внутри регистра таким образом, чтобы адресованный байт был размещен в битах [15:8].
Команда записи слова (STR) выполняется только для адреса, выровненного относительно границы слова. В противном случае, то это слово не будет размещено на шине данных. Другими словами, например, бит 31 сохраняемого регистра всегда будет размещен в соответствующем бите 31 на шине данных.
Использование регистра R15
Недопустимо использование регистра R15 в качестве базового регистра (Rn), если в команде передаче данных бит перезаписи W=1 (write-back). Если W=0 и R15 используется в качестве базового регистра, то необходимо помнить, что этот регистр хранит адрес текущей команды.
Недопустимо использование R15 в качестве регистра, определяющего смещение (Rm). Если в команде записи регистра в память (STR) регистр R15 используется вместо регистра-источника (Rd), то сохраненное этой командой значение будет равно адресу команды плюс 12 байт.
Ограничения при использовании базового регистра
Если в программе используется обработка исключительных ситуаций (abort), то следующий пример будет сложен в реализации, поскольку содержимое базового регистра Rn будет изменено, перед тем, как будет вызван и запущен обработчик исключительной ситуации. В некоторых случаях после возврата из этого обработчика уже невозможно вычислить первичное значение регистра (в данном примере - R1).
Пример: LDRR0,[R1],R1
Поэтому, в командах LDR или STR с постиндексацией нежелательно использование регистра Rm в качестве регистра Rn.
Прерывания во время передачи данных (data aborts)
Чтение или запись по существующему адресу может вызвать проблемы для систем управления памятью. Например, в системах с применением виртуальной памяти запрашиваемые данные могут отсутствовать в физической памяти. Диспетчер памяти может сообщить об этом процессору, вызвав исключительную ситуацию ABORT. В результате чего системное приложение должно решить эту проблему и перезапустить ту команду, выполнение которой вызвало исключительную ситуацию.
Число машинных тактов при выполнения
Обычная команда LDR выполняется за 1S + 1N + 1I, а команда LDR PC - за 2S + 2N + 1I машинных тактов, где S, N и I зависят от типа машинных тактов. Команда STR выполняется за 2N машинных тактов.
Синтаксис в ассемблере
<LDR|STR>{cond}{B}{T} Rd,<Адрес>
где:
LDR: |
чтение данных из памяти и запись их в регистр |
STR: |
запись данных в память из регистра; |
{cond}: |
двухсимвольная мнемоника условия выполнения команды (см. табл. 6); |
{B}: |
передача байта (при отсутствии - передача слова); |
{T}: |
установить в команде бит W в единицу в постиндексной команде, переводя ядро в непривилегированный режим для выполнения передачи (для прединдексной адресации T недопустим); |
Rd: |
выражение, которое определяет номер регистра общего назначения; |
Rn и Rm: |
выражения, которые определяют номер регистров общего назначения, если Rn = R15, то ассемблер вычтет 8 из смещения, активируя конвейер команд ARM7TDMI (в этом случае бит W=0, т.е. недопустима операция write-back); |
<Адрес>: |
возможны следующие варианты: |
- Адрес вычисляется в процессе компиляции согласно выражению:
<выражение>
Ассемблер попытается выполнить команду, используя содержимое PC в качестве базового адреса, а выражение - в качестве непосредственного смещения в виде константы. В этом случае этот адрес является прединдексным относительно регистра PC. Если вычисленный адрес выходит за допустимые пределы, то будет сгенерирована ошибка.
- Прединдексная адресация:
[Rn] <смещение>
[Rn,<#выражение>]{!}
[Rn,{+/-}Rm{,<сдвиг>}]{!}
- Постиндексная адресация:
[Rn],<#выражение>
[Rn],{+/-}Rm{,<сдвиг>}
|
<Сдвиг>: |
обычная команда сдвига (см. команды обработки данных), но ограниченная невозможностью указания числа операций сдвига через регистр общего назначения. |
{!}: |
разрешить запись вычисленного адреса обратно в базовый регистр (устанавливает в команде в единицу бит W). |
Примеры
STR R1,[R2,R4]! ; Сохранить косвенно R1 по адресу в R2+R4
; (оба - регистры) и записать этот адрес в R2
STR R1,[R2],R4 ; Сохранить косвенно R1 по адресу R2
; и записать этот адрес в R2 сумму R2+R4
LDR R1,[R2,#16] ; Прочитать из памяти косвенно по адресу R2+16
; записать в R1, но уже не сохранять адрес.
LDR R1,[R2,R3,LSL#2] ; Загрузить косвенно R1 по адресу R2+R3*4
LDREQB R1,[R6,#5] ; По условию загрузить в R1 (биты 7:0)
; байт по адресу R6+5, заполнив нулями
; биты 31:9 регистра R1
STR R1,PLACE ; Вычислить для R1 относительное смещение
; адреса PLACE относительно текущего адреса
PLACE:
|
Передача 16-битных данных и данных со знаком (LDRH, STRH, LDRSB, LDRSH)
Эти команды будут выполнены, если условие истинно. Все различные условия их выполнения перечислены в таблице 6. Машинные коды команд приведены на рис.25 и рис. 26.
Команды применяются для чтения (загрузки) или записи (хранения) 16-битных данных (полуслово: half-word) как без знака, так и со знаком. Адрес ячейки памяти, используемой в этих командах передачи, вычисляется посредством сложения или вычитания с некоторым смещением относительно указанного базового регистра. Если требуется применение автоиндексации, то результат этого вычисления может быть записан обратно в этот же базовый регистр.
Рис. 25. Команды передачи 16-битных данных и данных со знаком со смещением, заданным в регистре
Рис. 26. Команды передачи 16-битных данных и данных со знаком со смещением, заданным в виде константы
Смещения и автоиндексирование
Смещение относительно базового регистра может быть задано либо в виде 12-битной константы, указанной в двух полях кода команды (4 старших бита и 8 младших), или в виде второго регистра-операнда (при выполнении команды его содержимое может быть подвергнуто логическому сдвигу). Само смещение может быть либо добавлено (U=1), либо вычтено (U=0) из базового регистра Rn. Такие модификации смещения могут быть выполнены либо до выполнения пересылки (прединдексация, P=1) или после нее (постиндексация, P=0).
Бит W позволяет выбрать режим адресации: инкремент или декремент. Модифицированное значение базового адреса либо записывается обратно в него же (W=1), либо остается без изменений (W=0). В случае постиндексной адресации бит W теряет смысл и поэтому обнуляется, в этом случае можно сохранить прежнее значение базового адреса посредством установки смещения, равным нулю. Передача данных с постиндексированием всегда модифицируют содержимое базового адреса.
При использовании постиндексной адресации недопустима ситуация, когда бит команды W установлен единицу.
Чтение и запись 16-битных данных
При S=0 и H=1 можно осуществлять передачу данных без знака или полуслов между регистрами ARM7TDMI и памятью. Действия команд LDRH и STRH зависят от управляющего сигнала BIGEND, все вариации которого описаны ниже.
Чтение 16-битных данных и данных со знаком
Бит S определяет то, что будет осуществляться чтение данных со знаком либо без знака. При S=1 бит H определяет тип данных: байты (H=0) или полуслова (H=1). Бит L не должен быть равен нулю (команда записи), когда бит производятся операции с операндами со знаком (S=1).
Команда LDRSB производит чтение одного байта из памяти и размещает его в младших 8-ми битах регистра-получателя, при этом все остальные биты этого регистра [31:8] заполняются одним и тем же значением - битом 7 байта, т.е. его знаком.
Команда LDRSH производит чтение полуслова из памяти и размещает его в младших 16-ти битах регистра-получателя, при этом все остальные биты этого регистра [31:16] заполняются одним и тем же значением - битом 15 этого полуслова, т.е. его знаком.
Действия команд LDRSB и LDRSH зависят от управляющего сигнала BIGEND, все вариации которого описаны ниже.
Режим Little-Endian
Команда чтения байта со знаком (LDRSB) считывает данные с шины данных D[7:0], если адрес байта находится на границе слова, с D [15:8] - если адрес на единицу больше и т.д. После чего прочитанный байт размещается в младших 8-ми битах регистра-получателя, а остальные байты этого регистра заполняются битом знака этого байта - бит 7 (см. рис. 5).
Команда чтения полуслова (LDRSH или LDRH) считывает данные с шины данных D[15:0], если адрес байта находится на границе целого слова (A[1]=0) или с шины данных D[31:16], если адрес находится на границе полуслова (A[1]=1). Адрес полуслова всегда должен быть выровнен по границе полуслова, в противном случае (т.е. A[0]=1) прочитанное значение будет недостоверным.
После чего прочитанное полуслово будет размещено в младших 16-ти битах регистра-получателя (младшее полуслово). Для полуслов без знака (LDRH) старшие 16 бит регистра-получателя будут заполнены нулями, а для полуслов со знаком (LDRSH) - старшие 16 бит регистра-получателя будут заполнены знаком этого полуслова (бит 15).
Команда записи полуслова в память (STRH) вычитывает из регистра-источника младшие 16 бит (младшее полуслово), копируя его дважды по всей ширине шины данных D[31:16] и D[15:0]. Система управления внешней памятью (если используется), должна активизировать работу соответствующего узла для возможности чтения/записи одного полуслова. Необходимо помнить, что адрес должен быть выровнен строго по границе полуслова, в противном случае записанное значение нельзя считать достоверным.
Режим Big-Endian
Команда чтения байта со знаком (LDRSB) считывает данные с шины данных D[31:24], если адрес байта находится на границе слова, с D[23:16] - если адрес на единицу больше и т.д. После чего прочитанный байт размещается в младших 8-ми битах регистра-получателя, а остальные байты этого регистра заполняются битом знака байта, т.е. 7-м битом (см. рис. 4).
Команда чтения полуслова (LDRSH или LDRH) считывает данные с шины данных D[31:16], если адрес байта находится на границе целого слова (A[1]=0) или с шины данных D[15:0], если адрес находится на границе полуслова (A[1]=1). Адрес полуслова всегда должен быть выровнен по границе полуслова, в противном случае (т.е. A[0]=1) прочитанное значение будет недостоверным.
После чего прочитанное полуслово будет размещено в старших 16-ти битах регистра-получателя (старшее полуслово). Для полуслов без знака (LDRH) старшие 16 бит регистра-получателя будут заполнены нулями, а для полуслов со знаком (LDRSH) - старшие 16 бит регистра-получателя будут заполнены знаком этого полуслова (бит 15).
Команда записи полуслова в память (STRH) вычитывает из регистра-источника младшие 16 бит (младшее полуслово), копируя его дважды по всей ширине шины данных D[31:16] и D[15:0]. Система управления внешней памятью (если используется), должна активизировать работу соответствующего узла для возможности чтения/записи одного полуслова. Необходимо помнить, что адрес должен быть выровнен строго по границе полуслова, в противном случае записанное значение нельзя считать достоверным.
Использование регистра R15
Недопустимо использование регистра R15 в качестве базового регистра (Rn), если в команде передаче данных бит перезаписи W=1 (write-back). Если W=0 и R15 используется в качестве базового регистра, то необходимо помнить, что этот регистр хранит адрес текущей команды.
Недопустимо использование R15 в качестве регистра, определяющего смещение (Rm). Если в команде записи полуслова из регистра в память (STRH) регистр R15 используется вместо регистра-источника (Rd), то сохраненное этой командой значение будет равно адресу команды плюс 12 байт.
Ограничения при использовании базового регистра
Чтение или запись по существующему адресу может вызвать проблемы для систем управления памятью. Например, в системах с применением виртуальной памяти запрашиваемые данные могут отсутствовать в физической памяти. Диспетчер памяти может сообщить об этом процессору, вызвав исключительную ситуацию ABORT. В результате чего системное приложение должно решить эту проблему и перезапустить ту команду, выполнение которой вызвало исключительную ситуацию.
Число машинных тактов при выполнении
Обычная команда LDR(H,SH,SB) выполняется за 1S + 1N + 1I, а команда LDR(H,SH,SB) PC - за 2S + 2N + 1I машинных тактов, где S, N и I зависят от типа машинных тактов. Команда STRH выполняется за 2N машинных тактов.
Синтаксис в ассемблере
<LDR|STR>{cond}<|SH|SB> Rd,<Адрес>
где:
LDR: |
чтение данных из памяти и запись их в регистр; |
STR: |
запись данных в память из регистра; |
{cond}: |
двухсимвольная мнемоника условия выполнения команды (см. табл. 6); |
H: |
передача полуслов (16 бит); |
SB: |
передача байта со знаком (только для команды LDR); |
SH: |
передача полуслова со знаком (только для команды LDR); |
Rd: |
выражение, которое определяет номер регистра общего назначения; |
<Адрес>: |
возможны следующие варианты: |
- Адрес вычисляется в процессе компиляции согласно выражению:
<выражение>
Ассемблер попытается выполнить команду, используя содержимое PC в качестве базового адреса, а выражение - в качестве непосредственного смещения в виде константы. В этом случае этот адрес является прединдексным относительно регистра PC. Если вычисленный адрес выходит за допустимые пределы, то будет сгенерирована ошибка.
- Прединдексная адресация:
[Rn] <смещение>
[Rn,<#выражение>]{!}
[Rn,{+/-}Rm{,<сдвиг>}]{!}
- Постиндексная адресация:
[Rn],<#выражение>
[Rn],{+/-}Rm{,<сдвиг>}
|
<Сдвиг>: |
обычная команда сдвига (см. команды обработки данных), но ограниченная невозможностью указания числа операций сдвига через регистр общего назначения. |
{!}: |
разрешить запись вычисленного адреса обратно в базовый регистр (устанавливает в команде в единицу бит W). |
Пример
LDRH R1,[R2,-R3]! ; Прочитать полуслово по адресу R2-R3,
; и записать его в регистр R1
; В R2 записать результат R2-R3.
STRH R3,[R4,#18] ; Сохранить младшее полуслово R3
; по адресу R14+18, но не изменять R14.
LDRSB R8,[R2],#-223 ; Прочесть из памяти байт со знаком,
; записать его в R8 и присвоить R2=R2-223.
LDRNESH R11,[R0] ; По условию загрузить в R11 полуслово со знаком
; по адресу, содержащемуся в R0.
HERE ; Вычислить адрес относительно метки HERE.
; Записать в R5 полуслово по адресу
; со смещение (FRED-HERE-8) относительно PC.
STRH R5, [PC, #(FRED-HERE-8)]
……
FRED
|
<---- Вернуться к Системе команд --->
|