МК
Методы адресации, команды передачи
данных и управления (Лабораторная работа)
Цель
работы: изучение методов адресации,
команд передачи данных и управления.
1.
Общие сведения
При
создании программы для микроконтроллера (МК) на языке Ассемблер разработчик оперирует
программно-доступными ресурсами микропроцессорной системы. У микроконтроллера ATmega128 эти ресурсы включают: программно-доступные
регистры микроконтроллера, внутреннюю память данных, внешнюю память данных.
Каждая
команда языка Ассемблер сообщает процессору выполняемую операцию и методы
доступа к операндам. Командная строка Ассемблера включает метку (символический
адрес), мнемонику (символическое имя) команды, поле операндов, комментарий.
Методы
адресации представляют собой набор механизмов доступа к операндам. Одни из них
просты и поэтому приводят к компактному формату команды и быстрому доступу к
операнду, но объем доступных с их помощью ресурсов ограничен. Другие методы
адресации позволяют оперировать со всеми имеющимися в системе ресурсами, но команда
получается длинной, на ее ввод и выполнение тратится много времени. Набор
методов адресации в каждой системе команд является компромиссным сочетанием
известных механизмов адресации, выбранных проектировщиками архитектуры исходя
из набора решаемых задач.
Заметим,
что при двух операндах и приемнике результата имеет место трехадресная команда и каждый адрес формируется с использованием собственного
метода адресации. Если адрес операнда или приемника результата не указан в
команде, а подразумевается, то имеет место неявная адресация. В программах для
микроконтроллера ATmega128 используется прямая,
косвенная и относительная адресации. На рис.14 – 25 приведены схемы методов адресации.
Рис. Регистровая адресация
(один регистр общего назначения)
Рис. Регистровая адресация
(два регистра общего назначения)
Рис. Регистровая адресация
(регистры ввода-вывода)
Рис. Прямая адресация
данных
Рис. Косвенная адресация
данных со смещением
Рис. Косвенная адресация
данных
Рис. Косвенная адресация
данных с преддекрементом
Рис. Косвенная адресация
данных с постинкрементом
Рис. Адресация константы в
памяти программ в командах LPM и ELPM
Рис. Прямая адресация памяти
программ в командах JMP и CALL
Рис. Косвенная адресация памяти
программ в командах IJMP и ICALL
Рис. Относительная
адресация памяти программ в командах RJMP и RCALL
Команды передачи данных приведены в таблице ниже.
Таблица. Команды пересылки данных
Мнемо-ника
|
Операн-ды
|
Описание
|
Операция
|
Флаги
|
Кол-во циклов
|
ELPM
|
–
|
Расширенная загрузка из памяти программ в регистр R0
|
R0 ¬ (Z+RAMPZ)
|
Нет
|
3
|
MOV
|
Rd,Rr
0£d£31
0£r£31
|
Копировать регистр
|
Rd ¬ Rr
|
Нет
|
1
|
LDI
|
Rd,K
16£d£31
0£k£255
|
Загрузить непосредственное значение
|
Rd ¬ K
|
Нет
|
1
|
LDS
|
Rd,k
0£d£31
0£k£65535
|
Загрузить из ОЗУ
|
Rd ¬ (k)
|
Нет
|
3
|
LD
|
Rd,X
0£d£31
|
Загрузить косвенно
|
Rd ¬ (X)
|
Нет
|
2
|
LD
|
Rd,X+
0£d£31
|
Загрузить косвенно с постинкрементом
|
Rd ¬ (X),
X ¬ X+1
|
Нет
|
2
|
LD
|
Rd,-X
0£d£31
|
Загрузить косвенно с преддекрементом
|
X ¬ X - 1,
Rd ¬ (X)
|
Нет
|
2
|
LD
|
Rd,Y
0£d£31
|
Загрузить косвенно
|
Rd ¬ (Y),
|
Нет
|
2
|
LD
|
Rd,Y+
0£d£31
|
Загрузить косвенно с постинкрементом
|
Rd ¬ (Y),
Y ¬ Y+1
|
Нет
|
2
|
LD
|
Rd,-Y
0£d£31
|
Загрузить косвенно с преддекрементом
|
Y ¬ Y - 1,
Rd ¬ (Y)
|
Нет
|
2
|
LDD
|
Rd,Y+q
0£d£31
0£q£63
|
Загрузить косвенно со смещением
|
Rd ¬ (Y+q)
|
Нет
|
2
|
LD
|
Rd,Z
0£d£31
|
Загрузить косвенно
|
Rd ¬ (Z)
|
Нет
|
2
|
LD
|
Rd,Z+
0£d£31
|
Загрузить косвенно с постинкрементом
|
Rd ¬ (Z),
Z ¬ Z+1
|
Нет
|
2
|
LD
|
Rd,-Z
0£d£31
|
Загрузить косвенно с преддекрементом
|
Z ¬ Z - 1,
Rd ¬ (Z)
|
Нет
|
2
|
LDD
|
Rd,Z+q
0£d£31
0£q£31
|
Загрузить косвенно со смещением
|
Rd ¬ (Z+q)
|
Нет
|
2
|
STS
|
k,Rr
0£r£31
0£k£65535
|
Загрузить непосредственно в ОЗУ
|
(k) ¬ Rr
|
Нет
|
3
|
ST
|
X,Rr
0£r£31
|
Записать косвенно
|
(X) ¬ Rr
|
Нет
|
2
|
ST
|
X+,Rr
0£r£31
|
Записать косвенно с постинкрементом
|
(X) ¬ Rr,
X ¬ X + 1
|
Нет
|
2
|
ST
|
-X,Rr
0£r£31
|
Записать косвенно с преддекрементом
|
X ¬ X - 1,
(X) ¬ Rr
|
Нет
|
2
|
ST
|
Y,Rr
0£r£31
|
Записать косвенно
|
(Y) ¬ Rr
|
Нет
|
2
|
ST
|
Y+,Rr
0£r£31
|
Записать косвенно с постинкрементом
|
(Y) ¬ Rr,
Y ¬ Y + 1
|
Нет
|
2
|
ST
|
-Y,Rr
0£r£31
|
Записать косвенно с преддекрементом
|
Y ¬ Y - 1,
(Y) ¬ Rr
|
Нет
|
2
|
STD
|
Y+q,Rr
0£r£31
0£q£63
|
Записать косвенно со смещением
|
(Y+q) ¬ Rr
|
Нет
|
2
|
ST
|
Z,Rr
0£r£31
|
Записать косвенно
|
(Z) ¬ Rr
|
Нет
|
2
|
ST
|
Z+,Rr
0£r£31
|
Записать косвенно с постинкрементом
|
(Z) ¬ Rr,
Z ¬ Z + 1
|
Нет
|
2
|
ST
|
-Z,Rr
0£r£31
|
Записать косвенно с преддекрементом
|
Z ¬ Z - 1,
(Z) ¬ Rr
|
Нет
|
2
|
STD
|
Z+q,Rr
0£r£31
0£q£63
|
Записать косвенно со смещением
|
(Z+q) ¬ Rr
|
Нет
|
2
|
LPM
|
|
Загрузить байт из памяти программ
|
R0 ¬ (Z)
|
Нет
|
3
|
IN
|
Rd,P
0£d£31
0£P£63
|
Загрузить данные из порта I/O в регистр
|
Rd ¬ P
|
Нет
|
1
|
OUT
|
P,Rr
0£r£31
0£P£63
|
Записать данные из регистра в порт I/O
|
P ¬ Rr
|
Нет
|
1
|
PUSH
|
Rr
0£r£31
|
Сохранить регистр в стеке
|
STACK ¬ Rr
|
Нет
|
2
|
POP
|
Rd
0£d£31
|
Выгрузить регистр из стека
|
Rd ¬ STACK
|
Нет
|
2
|
Из таблицы видно, что набор этих команд представляет собой
сочетание восьми операций с различными методами адресации.
Команды передачи
управления (переходов) приведены в табл. 3.
Таблица. Команды
переходов
Мнемо-ника
|
Операнды
|
Описание
|
Операция
|
Флаги
|
Кол-во циклов
|
1
|
2
|
3
|
4
|
5
|
6
|
RJMP
|
k
-2K£k£2K
|
Перейти относительно
|
PC ¬ PC + k + 1
|
Нет
|
2
|
LJMP
|
|
Перейти косвенно
|
PC ¬ Z
|
Нет
|
2
|
JMP
|
k
0£k£4M
|
Перейти
|
PC ¬ k
|
Нет
|
3
|
RCALL
|
K
-2K£k£2K
|
Вызвать подпрограмму относительно
|
PC ¬ PC + k + 1
|
Нет
|
3
|
ICALL
|
–
|
Вызвать подпрограмму косвенно
|
PC ¬ Z
|
Нет
|
3
|
CALL
|
K
0£k£64K
|
Выполнить длинный вызов подпрограммы
|
PC ¬ k
|
Нет
|
4
|
RET
|
–
|
Вернуться из подпрограммы
|
PC ¬ STACK
|
Нет
|
4
|
RETI
|
–
|
Вернуться из прерывания
|
PC ¬ STACK
|
1
|
4
|
CPSE
|
Rd,Rr
0£d£31, 0£r£31
|
Сравнить и пропустить, если равно
|
if Rd=Rr then
PC ¬PC + 2 (or 3)
|
Нет
|
1/2/3
|
SBRC
|
Rr,b
0£r£31
0£b£7
|
Пропустить, если бит в регистре очищен
|
if Rr(b)=0 then
PC ¬PC + 2 (or 3)
|
Нет
|
1/2/3
|
SBRS
|
Rr,b
0£r£31
0£b£7
|
Пропустить, если бит в регистре установлен
|
if Rr(b)=1 then
PC ¬PC + 2 (or 3)
|
Нет
|
1/2/3
|
SBIC
|
P,b
0£P£31
0£b£7
|
Пропустить, если бит в регистре I/O очищен
|
if I/OP(b)=0 then
PC ¬PC + 2 (or 3)
|
Нет
|
1/2/3
|
SBIS
|
P,b
0£r£31
0£b£7
|
Пропустить, если бит в регистре I/O установлен
|
if I/OP(b)=1 then
PC ¬PC + 2 (or 3)
|
Нет
|
1/2/3
|
BRBS
|
s,k
0£s£7
-64£k£+63
|
Перейти, если бит в регистре статуса установлен
|
if SREG(s)=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRBC
|
s,k
0£s£7
-64£k£+63
|
Перейти, если бит в регистре статуса очищен
|
if SREG(s)=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BREQ
|
k
-64£k£+63
|
Перейти, если равно
|
if Rd=Rr(Z=1) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRNE
|
k
-64£k£+63
|
Перейти, если не равно
|
if Rd¹Rr(Z=0) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRCS
|
k
-64£k£+63
|
Перейти, если флаг переноса установлен
|
if С=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRCC
|
k
-64£k£+63
|
Перейти, если флаг переноса очищен
|
if С=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRSH
|
k
-64£k£+63
|
Перейти, если равно или больше (без знака)
|
if Rd³Rr (C=0) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRLO
|
k
-64£k£+63
|
Перейти, если меньше
(без знака)
|
if Rd<Rr (C=1) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRMI
|
k
-64£k£+63
|
Перейти, если минус
|
if N=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRPL
|
k
-64£k£+63
|
Перейти, если плюс
|
if N=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRGE
|
k
-64£k£+63
|
Перейти, если больше или равно (с учетом знака)
|
if Rd³Rr (NÅV=0) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRLT
|
k
-64£k£+63
|
Перейти, если меньше, чем (со знаком)
|
if Rd<Rr (NÅV=1) then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRHS
|
k
-64£k£+63
|
Перейти, если флаг полупереноса
установлен
|
if H=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRHC
|
k
-64£k£+63
|
Перейти, если флаг полупереноса
очищен
|
if H=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRTS
|
k
-64£k£+63
|
Перейти, если флаг T
установлен
|
if T=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRTC
|
k
-64£k£+63
|
Перейти, если флаг T очищен
|
if T=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRVS
|
k
-64£k£+63
|
Перейти, если флаг переполнения установлен
|
if V=1 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRVC
|
k
-64£k£+63
|
Перейти, если флаг переполнения очищен
|
if V=0 then
PC ¬ PC + k + 1
|
Нет
|
1/2
|
BRIE
|
k
-64£k£+63
|
Перейти, если глобальное
прерывание разрешено
|
if I=1 then
PC ¬
PC + k + 1
|
Нет
|
1/2
|
BRID
|
k
-64£k£+63
|
Перейти, если глобальное
прерывание запрещено
|
if I=0 then
PC ¬
PC + k + 1
|
Нет
|
1/2
|
|
|
|
|
|
|
|
Из табл. 2 и 3 видно, что команды пересылки данных и команды
переходов значения флагов регистра SREG не изменяют.
2. Домашнее
задание
1. Изучить описание структуры микроконтроллера ATmega128 и интегрированной системы его программирования на
языке Ассемблер AVRStudio.
2. Изучить реализуемые микроконтроллером способы адресации и команды
пересылки данных.
3.
Порядок выполнения работы
1. Запустить на персональном компьютере
интегрированную систему программирования AVRStudio. Командой Project | New Project создать новый проект Lesson1. С использованием редактора текста создать
демонстрационную программу:
.device ATmega128
.include "m128def.inc"
;***** Инициализация указателя стека
**********************
ldi R20,$FF; загрузка промежуточного регистра R20 младшим
; байтом адреса начала стека
out SPL,R20;
загрузка младшего байта указателя стека
ldi R20,$10; загрузка промежуточного регистра R20 старшим
; байтом адреса начала стека
out SPH,R20;
загрузка старшего байта указателя стека
;***** Выполнение команд пересылок
**************************
ldi R20,$57; загрузка регистра R20 константой
ldi
R30,$00;загрузка
регистровой пары Z (R30,R31) с адресом $0100
ldi
R31,$01;по которому
расположена первая ячейка внутреннего ОЗУ
st Z,R20 ;загрузка косвенно адресуемой ячейки
ОЗУ с адресом $0100
; значением из регистра R20 ($57)
lds
R19,$0100 ; загрузка
регистра R19 из ячейки ОЗУ с адресом
$0100
sts $0101,R19;загрузка ячейки с адресом $0101 из регистра
R19
call
Rout ; вызов подпрограммы Rout
loop:
rjmp loop ; зацикливание программы
;*** Подпрограмма копирования значения из
памяти программ ***
Rout:
push
R30 ; сохранение
указателя Z в
стеке
push
R31
ldi
R20, $00; загрузка
регистра R20 новой константой
ldi
R30, $80; загрузка
регистровой пары Z
удвоенным адресом ячейки
ldi
R31, $00; памяти
программ
lpm ; загрузка регистра R0
значением ячейки памяти программ с адресом $0040
cpse R0,R20
; пропустить следующую команду
;если значения регистров R0 и R20 равно
sts
$0102,R0 ; загрузка ячейки
ОЗУ с адресом $0102 из регистра R0
pop
R31 ; извлечение указателя Z из стека
pop
R30
ret ; возврат из подпрограммы
;*********************************************************
|
2. Выполнить команду Project/Build для
компиляции проекта.
3. С помощью команды Debug/Start
Debugging запустить симулятор. Командой View/Memory открыть
окно с ячейками памяти программ. Прямым редактированием занести любой код в
ячейку $40 памяти программ.
4.
Выполнить программу по шагам, выполняя команду Debug/Step Intro (F11). После
выполнения текущей команды курсор в окне редактора текста указывает на
следующую команду.
5.
Проверить правильность пересылки данных.
6.
Составить программу выполнения заданной преподавателем последовательности
операций передачи данных, провести пошаговый прогон программы,
продемонстрировать полученный результат.