|
МК
Команды обработки
данных (Лабораторная работа)
Цели
работы: изучение команд
арифметических и логических операций, сдвигов и битовых операций, практическое
освоение приемов программирования на Ассемблере, изучение директив.
1.
Общие сведения
Для обработки данных микроконтроллер ATmega128 использует группу команд, реализующих
арифметические и логические операции, сдвиги и операции над отдельными битами.
Арифметические операции являются операциями над 8-разрядными целыми числами.
Для выполнения целочисленных операций над длинными словами служат команды
сложения и вычитания с учетом флага переноса.
Арифметические и логические команды приведены в табл. 4 и 5.
Таблица 4. Арифметические и логические команды
Мнемоника
|
Операнды
|
Описание
|
Операция
|
Флаги
|
К-во циклов
|
|
ADD
|
Rd,Rr
0£d£31
0£r£31
|
Сложить без переноса
|
Rd ¬ Rd + Rr
|
Z, C, N, V, H
|
1
|
|
ADC
|
Rd,Rr
0£d£31
0£r£31
|
Сложить с переносом
|
Rd ¬ Rd + Rr + С
|
Z, C, N, V, H
|
1
|
|
ADIW
|
Rd,K
d½Î{24,26,28,30}
0£K£63
|
Сложить непосредственное
значение со словом
|
Rdh:Rdl ¬ Rdh:Rdl + K
|
Z, C, N, V
|
2
|
|
SUB
|
Rd,Rr
0£d£31
0£r£31
|
Вычесть без заема
|
Rd ¬ Rd - Rr
|
Z, C, N, V, H
|
1
|
|
SUBI
|
Rd, K
16£d£31
0£K£255
|
Вычесть непосредственное
значение
|
Rd ¬ Rd - K
|
Z, C, N, V, H
|
1
|
|
SBC
|
Rd, Rr
0£d£31
0£r£31
|
Вычесть c
заемом
|
Rd ¬ Rd - Rr - С
|
Z, C, N, V, H
|
1
|
|
SBCI
|
Rd, K
16£d£31
0£K£255
|
Вычесть непосредственное
значение c заемом
|
Rd ¬ Rd - K - С
|
Z, C, N, V, H
|
1
|
|
|
SBIW
|
Rd, K
d½Î{24,26,28,30}
0£K£63
|
Вычесть непосредственное
значение из слова
|
Rdh:Rdl ¬ Rdh:Rdl - K
|
Z, C, N, V
|
2
|
|
AND
|
Rd, Rr
0£d£31
0£r£31
|
Выполнить логическое AND
|
Rd ¬ Rd · Rr
|
Z, N, V
|
1
|
|
ANDI
|
Rd, K
16£d£31
0£K£255
|
Выполнить логическое AND
|
Rd ¬ Rd · K
|
Z, N, V
|
1
|
|
OR
|
Rd, Rr
0£d£31
0£r£31
|
Выполнить логическое OR
|
Rd ¬ Rd Ú Rr
|
Z, N, V
|
1
|
|
ORI
|
Rd, K
16£d£31
0£K£255
|
Выполнить логическое OR с непосредственным значением
|
Rd ¬ Rd Ú K
|
Z, N, V
|
1
|
|
EOR
|
Rd, Rr
0£d£31
0£r£31
|
Выполнить исключающее OR
|
Rd ¬ Rd Å Rr
|
Z, N, V
|
1
|
|
COM
|
Rd 0£d£31
|
Выполнить дополнение до
единицы
|
Rd ¬ SFF - Rd
|
Z, C, N, V
|
1
|
|
NEG
|
Rd 0£d£31
|
Выполнить дополнение до
двух
|
Rd ¬ S00 - Rd
|
Z, C, N, V, H
|
1
|
|
SBR
|
Rd, K
16£d£31
0£K£255
|
Установить биты в регистре
|
Rd ¬ Rd Ú K
|
Z, N, V
|
1
|
|
CBR
|
Rd, K
16£d£31
0£K£255
|
Очистить биты в регистре
|
Rd ¬ Rd · (SFF - K)
|
Z, N, V
|
1
|
|
INC
|
Rd 0£d£31
|
Инкрементировать
|
Rd ¬ Rd + 1
|
Z, N, V
|
1
|
|
DEC
|
Rd 0£d£31
|
Декрементировать
|
Rd ¬ Rd - 1
|
Z, N, V
|
1
|
|
TST
|
Rd
0£d£31
|
Проверить на ноль или минус
|
Rd ¬ Rd · Rd
|
Z, N, V
|
1
|
|
CLR
|
Rd 0£d£31
|
Очистить регистр
|
Rd ¬ Rd Å Rd
|
Z, N, V
|
1
|
|
SER
|
Rd
16£d£31
|
Установить все биты регистра
|
Rd ¬ SFF
|
Нет
|
1
|
|
CP
|
Rd, Rr
0£d£31
0£r£31
|
Сравнить
|
Rd - Rr
|
Z, C, N, V, H
|
1
|
|
CPC
|
Rd, Rr
0£d£31
0£r£31
|
Сравнить с учетом переноса
|
Rd - Rr - С
|
Z, C, N, V, H
|
1
|
|
CPI
|
Rd, K
16£d£31
0£K£255
|
Сравнить с константой
|
Rd - K
|
Z, C, N, V, H
|
1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Таблица 5. Команды сдвигов и операций с битами
Мнемо-ника
|
Операн-ды
|
Описание
|
Операция
|
Флаги
|
Кол-во циклов
|
LSL
|
Rd
0£d£31
|
Логически сдвинуть влево
|
Rd(n+1) ¬ Rd(n),
Rd(0) ¬0, C ¬ Rd(7)
|
Z,C,N,V,H
|
1
|
LSR
|
Rd
0£d£31
|
Логически сдвинуть вправо
|
Rd(n) ¬ Rd(n+1),
Rd(7) ¬0, C ¬ Rd(0)
|
Z,C,N,V
|
1
|
ROL
|
Rd
0£d£31
|
Сдвинуть влево через перенос
|
Rd(0) ¬С,
Rd(n+1) ¬ Rd(n),
C ¬ Rd(7)
|
Z,C,N,V,H
|
1
|
ROR
|
Rd
0£d£31
|
Сдвинуть вправо через перенос
|
Rd(7) ¬С,
Rd(n) ¬ Rd(n+1),
C ¬ Rd(0)
|
Z,C,N,V
|
1
|
ASR
|
Rd
0£d£31
|
Арифметически сдвинуть
вправо
|
Rd(n) ¬ Rd(n+1),
C ¬ Rd(0),
n=0...6
|
Z,C,N,V
|
1
|
SWAP
|
Rd
0£d£31
|
Поменять полубайты местами
|
Rd(3...0)
« Rd(7...4)
|
Нет
|
1
|
BSET
|
s
0£s£7
|
Установить флаг
|
SREG(s)¬ 1
|
SREG(s)
|
1
|
BCLR
|
s
0£s£7
|
Очистить флаг
|
SREG(s)¬ 0
|
SREG(s)
|
1
|
SBI
|
P,b
0£P£31
0£b£7
|
Установить бит в регистр
I/O
|
I/O(P,b)¬ 1
|
Нет
|
2
|
CBI
|
P,b
0£P£31
0£b£7
|
Очистить бит в регистре I/O
|
I/O(P,b)¬ 0
|
Нет
|
2
|
BST
|
Rd,b
0£d£31
0£b£7
|
Переписать бит из регистра
во флаг Т
|
T¬ Rd(b)
|
T
|
1
|
BLD
|
Rd,b
0£d£31
0£b£7
|
Загрузить флаг Т в бит регистра
|
Rd(b) ¬ T
|
Нет
|
1
|
SEC
|
–
|
Установить флаг переноса
|
С¬ 1
|
С
|
1
|
CLC
|
–
|
Очистить
флаг переноса
|
С¬ 0
|
С
|
1
|
SEN
|
–
|
Установить флаг отрицательного
значения
|
N¬ 1
|
N
|
1
|
CLN
|
–
|
Очистить флаг отрицательного
значения
|
N¬ 0
|
N
|
1
|
SEZ
|
–
|
Установить флаг нулевого значения
|
Z¬ 1
|
Z
|
1
|
CLZ
|
–
|
Очистить флаг нулевого значения
|
Z¬ 0
|
Z
|
1
|
|
SEI
|
–
|
Установить флаг глобального
прерывания
|
I¬ 1
|
I
|
1
|
|
CLI
|
–
|
Очистить флаг глобального
прерывания
|
I¬ 0
|
I
|
1
|
|
SES
|
–
|
Установить флаг знака
|
S¬ 1
|
S
|
1
|
|
CLS
|
–
|
Очистить флаг знака
|
S¬ 0
|
S
|
1
|
|
SEV
|
–
|
Установить флаг переполнения
|
V¬ 1
|
V
|
1
|
|
CLV
|
–
|
Очистить флаг переполнения
|
V¬ 0
|
V
|
1
|
|
SET
|
–
|
Установить флаг Т
|
T¬ 1
|
T
|
1
|
|
CLT
|
–
|
Очистить флаг Т
|
T¬ 0
|
T
|
1
|
|
SEH
|
–
|
Установить флаг полупереноса
|
H¬ 1
|
H
|
1
|
|
CLH
|
–
|
Очистить флаг полупереноса
|
H¬ 0
|
H
|
1
|
|
NOP
|
–
|
Выполнить холостую команду
|
–
|
Нет
|
1
|
|
SLEEP
|
–
|
Установить режим SLEEP
|
См. описание команды [1, 3]
|
Нет
|
1
|
|
WDR
|
–
|
Сбросить сторожевой таймер
|
См. описание команды [1, 3]
|
Нет
|
1
|
|
2. Выполнение работы
1. Изучить набор команд арифметических, логических,
битовых операций и сдвигов, выполняемых микроконтроллером ATmega128.
2. Запустить на персональном компьютере интегрированную
систему программирования AVRStudio. Командой Project | New Project создать новый проект Lesson2. С использованием редактора текста создать демонстрационную
программу:
Таблица. Листинг программы
.device ATmega128
.include "m128def.inc"
;***** Определение констант ******************************
.EQU IniX =$0100
.EQU IniY =$0110
.EQU IniZ =$0120
.EQU SPadr =$10FF
.EQU NCircle =16
;*** Инициализация указателя стека
************************
Ldi R20, $FF; загрузка промежуточного регистра R20
;
младшим байтом адреса начала стека
out SPL, R20
; загрузка младшего байта указателя стека
ldi R20, $10 ; загрузка промежуточного регистра R20
; старшим байтом адреса начала стека
out SPH, R20
; загрузка старшего байта указателя стека
;*** Инициализация указателeй, счетчика циклов и флага управления переносом
***
ldi R26,low(IniX) ; загрузка рег. X значением указателя
ldi R27,high(IniX) ; на память данных
ldi R28,low(IniY) ; загрузка рег. Y значением указателя
ldi R29,high(IniY) ; на память данных
ldi R30,low(IniZ) ; загрузка рег. Z значением указателя
ldi R31,high(IniZ) ; на память данных
ldi R16,Ncircle ; в R16 –
счетчик циклов=2*NЧИСЕЛ
ldi R17,$00 ; в R17 – 0
ldi R18,$01 ; в R18 – 1 в младший бит
;*** Сложение массивов 16-разрядных чисел
***************
LP1:
sbrs R17, 0
clc
LP2: ld R3, X+; загрузка байта 1-операнда
ld R4, Y+ ; загрузка байта 2-операнда
adc R3, R4 ; сложение байтов операндов с учетом
переноса
st Z+, R3 ; запись результата в память
eor R17, R18 ; чередование 0 и 1 в младшем бите R17
dec R16 ; декремент счетчика байтов
brne LP1 ;зацикливание, если счетчик байтов не равен
нулю
loop:
rjmp loop ; зацикливание программы для исключения зависаний
|
Эта программа читает восемь пар двухбайтных операндов из ОЗУ данных, складывает операнды побайтно с
учетом флага переноса и посылает результаты также в ОЗУ. В программе использованы
директивы EQU, с помощью которых
определяются имена констант, встречающихся далее в тексте. Этими константами
являются значения адреса областей ОЗУ, где хранятся операнды и результаты,
количество циклов сложения. Область первых операндов начинается с адреса $0100,
вторых операндов – с $0110, результата – с $0120. Количество циклов равно
2байта*8операндов=16.
Для сокращения числа команд внутри цикла предусмотрена
одинаковая обработка первых байтов операндов, которые складываются без учета переноса,
и вторых байтов, складываемых с учетом значения бита
С. Единый цикл использует команду ADC, но
дополнительно привлекается бит 0 регистра R17, значение которого изменяется при каждом проходе.
При R17.0==0 (обработка первых байтов) бит переноса
обнуляется. Такой алгоритм применим только для 16-разрядных операндов. Для
работы программы необходим счетчик, три указателя на области ОЗУ и флаг
обнуления бита переноса. В качестве счетчика циклов используется регистр R16.
Его содержимое декрементируется и проверяется командой BRNE, которая организует цикл. В качестве указателей на
ячейки-источники операндов используются регистры X и Y. На текущую
ячейку-приемник результата указывает регистр Z.
3. Выполнить команду Project/Build для
компиляции проекта.
4. При успешной компиляции с помощью команды Debug/Start
Debugging запустить симулятор. Командой View/Memory открыть
окно с ячейками ОЗУ. Используя прямое редактирование ОЗУ данных (матрица Data в окне Memory) занести
в ячейки с адреса $0100 шестнадцать байтов любого кода, которые будут
представлять восемь первых двухбайтных операндов. С адреса $0110 занести
шестнадцать байтов другого кода, которые будут представлять восемь вторых
двухбайтных операндов.
Рис. Окно Memory
5. Выполнить программу по шагам, выполняя команду Debug/Step Intro (F11). Наблюдать
изменение значений в регистрах микроконтроллера и ячейках ОЗУ данных. При
указанных выше операндах результаты должны быть, как на рисунке ниже.
Рис. Изменения в окне Memory
6. Составить программу выполнения задания, провести
пошаговое выполнение программы, продемонстрировать полученный результат.
3. Задания для самостоятельней работы
1. Выполнить попарно сложение 16-разрядных чисел со
знаком, содержащихся в двух массивах объемом по 15 чисел с начальными адресами
$xx, $yy, результаты сохранить в массиве с начальным адресом $zz. Номера чисел, при сложении которых возникло
переполнение, записать в регистры R20 и R21. Общее количество переполнений указать в регистре R22.
2. Выполнить попарное
вычитание 16-разрядных чисел со знаком, содержащихся в двух массивах объемом по
10 чисел с начальными адресами $xx, $yy, результаты сохранить в массиве с начальным адресом $zz. При переполнении результат округлять до максимального положительного или отрицательного значения.
Общее количество округлений указать в регистре R22.
3. Выбрать числа с минимальным и
максимальным значениями из массива, содержащего 40 16-разрядных чисел со
знаком, которые размещены в памяти, начиная с адреса $xx.
Минимальное и максимальное числа записать в регистры R20, R21, а
порядковые номера этих чисел в исходном массиве данных - в регистры R22 и R23.
4. Выполнить сравнение 8-разрядных
чисел, содержащихся в массиве объемом из 50 чисел с начальным адресом $xx, с эталоном, хранящимся в регистре R17. Числа, не
совпадающие с эталоном, разместить в массиве с начальным адресом $yy. Общее число несовпадающих чисел записать в регистр R20.
|
|