В HTML      В PDF
микроэлектроника, микросхема, транзистор, диод, микроконтроллер, память, msp430, Atmel, Maxim, LCD, hd44780, t6963, sed1335, avr, mega128
Предприятия Компоненты Документация Применения Статьи Новости

 
Пересюхтюмя


13-я Международная выставка электронных компонентов и комплектующих для электронной промышленности





Выставка Передовые Технологии Автоматизации





Главная > Обзоры по типам > Микроконтроллеры > ARM > Система команд
Пересюхтюмя


13-я Международная выставка электронных компонентов и комплектующих для электронной промышленности





Выставка Передовые Технологии Автоматизации


Примеры применения команд в режиме ARM

В примерах, приведенных ниже, указаны основные способы для достижения высокой эффективности кода с применением основных команд ядра ARM7TDMI. Все эти примеры в основном оптимизированы по размеру кода, а не по скорости выполнения (хотя некоторые из примеров все же позволяют достичь достаточно большой скорости их выполнения).

Использование команд, выполняемых по условиям

Применение условий для логического ИЛИ

    CMP      Rn,#p    ; Если Rn=p OR Rm=q то перейти на Label.
    BEQ      Label
    CMP      Rm,#q
    BEQ      Label
Эквивалентный код:
    CMP      Rn,#p
    CMPNE    Rm,#q    ; Если условие не выполнено, то провести другой тест.
    BEQ      Label

Абсолютное значение

TEQ    Rn,#0     ; Проверить знак
RSBMI  Rn,Rn,#0  ; и, если необходимо, дополнить до 2-х.

Умножение на 4, 5 или 6

MOV     Rc,Ra,LSL#2   ; Умножить на 4,
CMP     Rb,#5         ; проверить значение,
ADDCS   Rc,Rc,Ra      ; закончить умножение на 5,
ADDHI   Rc,Rc,Ra      ; закончить умножение на 6.

Сочетание частичной проверки и проверки диапазона

TEQ     Rc,#127     ; Частичная проверка,
CMPNE   Rc,#" "-1   ; проверка диапазона
MOVLS   Rc,#"."     ; ЕСЛИ Rc<=" " ИЛИ Rc=ASCII(127)
                    ; ТО Rc:="."

Деление и остаток от деления

Как правило, подпрограммы деления для конкретных задач предоставляется в виде исходной кодов библиотек стандарта ANSI C, поставляемых вместе с набором выбранных средств разработки (ARM Cross Development Toolkit). В целях ознакомления ниже приведены лишь некоторые из подпрограмм деления.

                               ; Делимое находится в Ra, делитель - в Rb.
MOV      Rcnt,#1               ; Бит, управляющий делением.
Div1     CMP Rb,#0x80000000    ; Перемещать Rb до тех пор, пока он больше Ra
CMPCC    Rb,Ra
MOVCC    Rb,Rb,ASL#1
MOVCC    Rcnt,Rcnt,ASL#1
BCC      Div1
MOV      Rc,#0
Div2     CMP Ra,Rb              ; Проверить на возможность простого вычитания.
SUBCS    Ra,Ra,Rb               ; Вычесть если все ОК,
ADDCS    Rc,Rc,Rcnt             ; разместить соответствующий бит в результат
MOVS     Rcnt,Rcnt,LSR#1        ; бит, управляющий сдвигом
MOVNE    Rb,Rb,LSR#1            ; делить на 2, пока не закончено.
BNE      Div2
                                ; Результат деления размещен в Rc
                                ; Остаток от деления - в Ra.

Контроль за переполнением в ARM7TDMI

  1. Переполнение при умножении чисел без знака с 32-битным результатом

    UMULL   Rd,Rt,Rm,Rn     ; От 3 до 6 (включительно) машинных тактов 
    TEQ     Rt,#0           ; +1 такт при переполнении регистра
    BNE     overflow
    
  2. Переполнение при умножении чисел со знаком с 32-битным результатом

    SMULL   Rd,Rt,Rm,Rn         ; От 3 до 6 (включительно) машинных тактов 
    TEQ     Rt,Rd ASR#31        ; +1 такт при переполнении регистра
    BNE     overflow
    
  3. Переполнение при умножении с накоплением чисел без знака с 32-битным результатом

    UMLAL   Rd,Rt,Rm,Rn     ; От 3 до 7 (включительно) машинных тактов 
    TEQ     Rt,#0           ; +1 такт при переполнении регистра
    BNE 	overflow
    
  4. Переполнение при умножении с накоплением чисел со знаком с 32-битным результатом

    SMLAL   Rd,Rt,Rm,Rn      ; От 4 до 7 (включительно) машинных тактов 
    TEQ     Rt,Rd, ASR#31    ; +1 такт при переполнении регистра
    BNE     overflow
    
  5. Переполнение при умножении с накоплением чисел без знака с 64-битным результатом

    UMULL   Rl,Rh,Rm,Rn       ; От 3 до 6 (включительно) машинных тактов
    ADDS    Rl,Rl,Ra1         ; накопление для младшего слова
    ADC     Rh,Rh,Ra2         ; накопление для старшего слова
    BCS     overflow          ; +1 такт при переполнении обоих регистров
    
  6. Переполнение при умножении с накоплением чисел со знаком с 64-битным результатом

    SMULL   Rl,Rh,Rm,Rn        ; От 3 до 6 (включительно) машинных тактов
    ADDS    Rl,Rl,Ra1          ; накопление для младшего слова
    ADC     Rh,Rh,Ra2          ; накопление для старшего слова
    BVS     overflow           ; +1 такт при переполнении обоих регистров
    

Примечание: контроль за переполнением не имеет смысла при умножении чисел со знаком и без знака с 64-битным результатом, т.к. операнды - 32-битные слова, и поэтому переполнение в этом случае никогда не возникает.

Генератор псевдослучайных чисел

Часто при разработке программ требуются генераторы псевдо-случайных чисел. Самые эффективные алгоритмы основаны на командах исключающее ИЛИ вместе с командами циклического побитового сдвига. К сожалению, для генерации 32-битного результата требуется более одной обратной связи, чтобы добиться максимального диапазона (т.е. 2^32-1 циклов перед повторение псевдослучайной последовательности), поэтому приведенный ниже пример использует в своей работе 33-битный регистр с "рабочими" битами 33 и 20. Формула для работы алгоритма: <новый бит>=<бит 33> EOR <бит 20>, сдвиг влево 33-битного числа и размещение <нового бита> в младшем разряде; эта операция требует обработки всех <новых битов> (т.е. 32 бита). Вся цепочка по получении одного псевдослучайного числа выполняется за 5S машинных тактов:

                            ; Опорное случайное число в Ra (32 бита),
                            ; + 1 бит в младшем бите Rb, используется Rc.
TST     Rb,Rb,LSR#1         ; Старший бит поместить во флаг переноса
MOVS    Rc,Ra,RRX           ; 33-битный циклический сдвиг вправо
ADC     Rb,Rb,Rb            ; перенос разместить в младшем бите Rb
EOR     Rc,Rc,Ra,LSL#12
EOR     Ra,Rc,Rc,LSR#20     ; Новое псевдослучайное число размещается Ra.

Умножение на константу с использованием операций сдвига

Умножение на 2^n (1,2,4,8,16,32..)

MOV	Ra, Rb, LSL #n

Умножение на 2^n+1 (3,5,9,17..)

ADD	Ra,Ra,Ra,LSL #n

Умножение на 2^n-1 (3,7,15..)

RSB	Ra,Ra,Ra,LSL #n

Умножение на 6

ADD	Ra,Ra,Ra,LSL #1     ; multiply by 3
MOV	Ra,Ra,LSL#1         ; and then by 2

Умножение на 10 с добавлением числа

ADD	Ra,Ra,Ra,LSL#2      ; multiply by 5
ADD	Ra,Rc,Ra,LSL#1      ; multiply by 2 and add in next digit

Общий рекурсивный метод для Rb := Ra*C, C - константа:

  1. Если C - четное, то C = 2^n*D, D - нечетное:

    D=1:   MOV Rb,Ra,LSL #n
    D<>1:  {Rb := Ra*D}
    MOV    Rb,Rb,LSL #n
    
  2. Если C MOD 4 = 1, то C = 2^n*D+1, D - нечетное, n>1:

    D=1:    ADD Rb,Ra,Ra,LSL #n
    D<>1:   {Rb := Ra*D}
    ADD     Rb,Ra,Rb,LSL #n
    
  3. Если C MOD 4 = 3, то C = 2^n*D-1, D - нечетное, n>1:

    D=1:    RSB Rb,Ra,Ra,LSL #n
    D<>1:   {Rb := Ra*D}
    RSB     Rb,Ra,Rb,LSL #n
    

Эта часть кода не совсем оптимальна, но близка к этому. Пример ее неоптимальности - умножение на 45:

RSB    Rb,Ra,Ra,LSL#2      ; multiply by 3
RSB    Rb,Ra,Rb,LSL#2      ; multiply by 4*3-1 = 11
ADD    Rb,Ra,Rb,LSL#2      ; multiply by 4*11+1 = 45
Другой вариант:
ADD    Rb,Ra,Ra,LSL#3      ; multiply by 9
ADD    Rb,Rb,Rb,LSL#2      ; multiply by 5*9 = 45

Чтение слова при неизвестном выравнивании

                            ; Адрес находится в Ra (32 бита),
                            ; используются регистры Rb, Rc; результат в Rd.
                            ; d должно быть менее чем, например, 0,1.
BIC     Rb,Ra,#3            ; выровнить адрес по границе одного слова.
LDMIA   Rb,{Rd,Rc}          ; Прочитать 64 бита, содержащие ответ
AND     Rb,Ra,#3            ; Фактор коррекции в байтах
MOVS    Rb,Rb,LSL#3         ; ...теперь в битах и проверка на выравненность.
MOVNE   Rd,Rd,LSR Rb        ; Выделить младшую часть результата слова
                            ; (если не выровнено)
RSBNE   Rb,Rb,#32           ; get other shift amount
ORRNE   Rd,Rd,Rc,LSL Rb     ; combine two halves to get result
                            ; Получить число других сдвигов
                            ; Комбинируя двумя половина, сформировать 
                            ; результат