Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПАСМС LW5_MC

.pdf
Скачиваний:
9
Добавлен:
30.03.2015
Размер:
1.05 Mб
Скачать

ЛАБОРАТОРНАЯ РАБОТА № 5 ОРГАНИЗАЦИЯ ПОДПРОГРАММ

Цель работы: изучение принципов организации подпрограмм и передачи па-

раметров; освоение команд, обеспечивающих взаимодействие вызывающей программы с подпрограммой.

ОСНОВНЫЕ СВЕДЕНИЯ

В большой и сложной программе можно выделить последовательности команд, выполняющие некоторые законченные функции (процедуры). Если та-

кие последовательности команд оформить в виде отдельных модулей – под-

программ (routine, subroutine), то в программе эти команды могут быть заме-

нены вызовами соответствующих подпрограмм. Такое модульное (структурное)

программирование даёт следующие преимущества:

ускоряется и упрощается отладка всей программы;

подпрограммы, реализующие универсальные функции, могут использо-

ваться при разработке других программ;

в одной программе могут быть объединены модули, полученные после трансляции программ, написанных на разных языках программирования.

Для взаимодействия вызывающей программы с подпрограммой необхо-

димо выполнение следующих условий:

вызывающей программе должно быть известно положение подпро-

граммы в общей структуре программы;

должны быть определены способы вызова подпрограммы и возврата из неё;

должен быть выбран способ обмена данными между вызывающей про-

граммой и подпрограммой.

1

Положение подпрограммы в общей структуре программы определяется по её имени. Имя подпрограммы на ассемблере, задаваемое символической меткой, является стартовым адресом исполняемой части подпрограммы.

Вызов подпрограммы подразумевает передачу в неё управления ходом выполнения команд. Передача управления осуществляется путём загрузки в программный счётчик (РС) стартового адреса подпрограммы. При этом необ-

ходимо обеспечить сохранение адреса возврата из подпрограммы, т. е. адреса команды, следующей за командой вызова подпрограммы. Для хранения адре-

сов возврата из подпрограмм используется стек (stack).

Стек – специальным образом организованная последовательность ячеек памяти с дисциплиной обслуживания «последним пришёл – первым вышел»

(LIFO: Last-In – First-Out). При занесении в стек новых данных предыдущие дан-

ные сохраняются, но становятся временно недоступными («опускаются»). Вы-

гружаются из стека («поднимаются», «выталкиваются») данные в обратном по-

рядке. Стек может быть реализован как аппаратно, так и программно. Аппарат-

ный стек (Hardware Stack) выполняется непосредственно в составе процессора в виде набора специальных регистров и, как правило, имеет небольшую глуби-

ну. Программный стек (Software Stack) организуется в оперативной памяти;

глубина определяется размером и степенью использования памяти.

Адрес очередной свободной ячейки стека содержится в специальном ре-

гистре – указателе стека SP (Stack Pointer). При записи в стек число помещается в ячейку с адресом, содержащимся в указателе стека, после чего содержимое указателя стека уменьшается на единицу (рис. 23, а). При чтении из стека про-

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

держимого указателя стека (рис. 23, б). Таким образом, при записи стека и чте-

нии из него содержимое указателя стека изменяется.

Механизм использования стека для хранения адресов возврата из подпро-

грамм состоит в следующем. Когда в программе встречается команда вызова

подпрограммы, в ячейку памяти, определяемую указателем стека, записывает-

ся адрес возврата; значение указателя стека декрементируется; в про-

граммный

Исходное

После записи

Исходное

После чтения

состояние

числа С

состояние

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

.

 

 

.

 

 

.

 

 

.

 

.

 

 

.

 

 

.

 

 

.

 

.

 

 

.

 

 

.

 

 

 

SP

***

Addr–1

SP

***

Addr–1

 

 

 

SP

***

Addr

С

Addr

 

С

Addr

SP

***

Addr

 

 

 

 

 

 

 

 

 

 

 

 

.

 

.

 

 

.

 

 

.

 

 

.

 

.

 

 

.

 

 

.

 

 

.

 

.

 

 

.

 

 

.

 

а) б)

Рис. 23. Операции записи в стек (а) и чтения из стека (б):

*** – очередная свободная ячейка стека; Addr – адрес

счётчик загружается стартовый адрес подпрограммы. Далее выполняются ко-

манды подпрограммы. Когда в подпрограмме встречается команда возврата в вызывающую программу, значение указателя стека инкрементируется; сохра-

нённый в стеке адрес возврата загружается в программный счётчик (рис. 24).

Использование стека для работы с подпрограммами позволяет одной подпро-

грамме вызывать другую, т. е. обеспечивает возможность вложения подпро-

грамм. Глубина вложения подпрограмм ограничивается размером стека.

Основная программа

Загрузка в стек адреса

Подпрограмма

 

 

.

возврата; загрузка в

 

.

программный счѐтчик

 

стартового адреса

SUBR: ...

.

подпрограммы

 

.

Вызов п/п SUBR

 

 

.

Следующая команда

 

 

.

.

 

Извлечение из стека

Возврат

.

адреса возврата; загрузка

.

 

адреса возврата в

 

 

программный счѐтчик

 

Рис. 24. Механизм вызова подпрограммы и возврата в вызывающую программу

3

В большинстве AVR-микроконтроллеров стек размещается в оперативной памяти. Указатель стека представляет собой пару 8-разрядных регистров SPH

(старший байт указателя стека) и SPL (младший байт указателя стека), находя-

щихся в адресном пространстве регистров ввода-вывода. В микроконтроллерах,

размер оперативной памяти которых не превышает 256 байт, для хранения ука-

зателя стека используется только один регистр SPL (SP). Микроконтроллеры, не имеющие оперативной памяти, содержат трёхуровневый аппаратный стек.

Организуемый в оперативной памяти стек «растёт» от старших адресов к младшим. Учитывая, что начальное значение указателя стека после сброса микроконтроллера равно нулю, в инициализирующей (начальной) части про-

граммы необходимо произвести его установку, если предполагается использо-

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

LDI

R16, low(RAMEND)

; младшая

часть

адреса RAMEND

OUT

SPL, R16

; инициализация

SPL

LDI

R16, high(RAMEND)

;

старшая

часть

адреса RAMEND

OUT

SPH, R16

;

инициализация

SPH

Команда OUT осуществляет запись содержимого регистра общего назначения в регистр ввода-вывода; RAMEND – символическое имя адреса последней ячейки внутренней оперативной памяти. Для того чтобы использовать в программе символические имена адресов периферийных устройств AVR-микро-

контроллера, необходимо при помощи директивы .include подключить файл определения адресов периферийных устройств (inc-файл). Например, для мик-

роконтроллера ATmega8535 следует подключить файл m8535def.inc:

.include "m8535def.inc"

К подключаемому inc-файлу должен быть указан путь в поле Include Path окна

AVR Assembler, вызов которого осуществляется командой AVR Assembler Setup

меню Project. При использовании директивы .include нет необходимости

включать в программу директиву .device, так как она содержится в соответст-

вующем inc-файле.

Избежать появления в листинге трансляции текста inc-файла позволяет директива .nolist отключения листинга. Директива .nolist используется совместно с директивой .list включения листинга (по умолчанию режим генерации листинга включѐн). Исключение inc-файла из листинга трансляции может быть произведено следующим образом:

.nolist

; отключить генерацию листинга

.include "m8535def.inc"

;

подключить inc-файл

.list

;

включить генерацию листинга

Вызов подпрограммы на языке ассемблера AVR-микроконтроллеров осу-

ществляется командами RCALL, ICALL, CALL и EICALL. Команда RCALL (Relative Call – относительный вызов) обеспечивает вызов подпрограммы, смещение на-

чального адреса которой относительно текущего значения программного счёт-

чика лежит в пределах 2 Кслов ( 4 Кбайт), с помощью относительной адреса-

ции памяти программ. Команда ICALL (Indirect Call – косвенный вызов) произво-

дит косвенный вызов подпрограммы по адресу памяти программ, содержаще-

муся в регистре-указателе Z; максимальное смещение начального адреса под-

программы составляет 64 Кслов (128 Кбайт). Команда CALL (Call – вызов) обеспе-

чивает вызов подпрограммы из памяти программ размером до 4 Мслов (8

Мбайт) с использованием непосредственной адресации. Команда EICALL (Extended Indirect Call – расширенный косвенный вызов) позволяет выполнять кос-

венный вызов подпрограмм из памяти программ размером до 4 Мслов (8

Мбайт). При выполнении команд RCALL, ICALL, CALL и EICALL текущее значение программного счётчика заносится в стек (2 байта в микроконтроллерах с 16-

разрядным программным счётчиком или 3 байта в микроконтроллерах с 22-

5

разрядным программным счётчиком). Содержимое указателя стека (SPH:SPL)

уменьшается соответственно на 2 или 3.

Примеры использования команд вызова подпрограмм:

RCALL

subr1

; относительный

вызов подпрограммы subr1

; косвенный вызов подпрограммы subr2

LDI

R30, low(subr2)

 

LDI

R31, high(subr2)

 

ICALL

 

; команда icall

не имеет операндов

Для возврата из подпрограмм используется команда RET. При выполнении команды RET адрес возврата загружается из стека в программный счётчик. При этом содержимое указателя стека увеличивается на 2 или 3 в зависимости от разрядности программного счётчика (см. выше).

Стек может также использоваться для сохранения содержимого РОН на время выполнения подпрограмм. Для сохранения в стеке и извлечения из стека содержимого РОН служат команды PUSH и POP. Команда PUSH заносит содер-

жимое регистра в стек по адресу, хранящемуся в указателе стека, при этом зна-

чение указателя стека уменьшается на единицу (SPH:SPL = SPH:SPL – 1). Коман-

да POP выполняет обратные действия: значение указателя стека увеличивается на единицу (SPH:SPL = SPH:SPL + 1); содержимое ячейки памяти по адресу, хра-

нящемуся в указателе стека, загружается в регистр.

Программы с использованием подпрограмм обычно начинаются с коман-

ды относительного перехода к основной программе, в которой прежде всего производится инициализация стека (рис. 25).

.nolist

; отключить

генерацию листинга

.include "m8535def.inc"

; подключить inc-файл

.list

; включить генерацию листинга

RJMP RESET

;

переход к

основной программе

PODPR:

;

подпрограмма PODPR

 

 

 

 

; ...

 

RET

 

; возврат в основную программу

RESET:

 

; основная программа

LDI

R16, low(RAMEND)

 

OUT

SPL, R16

; инициализация SPL

LDI

R16, high(RAMEND)

 

OUT

SPH, R16

; инициализация SPH

; ...

 

 

RCALL

PODPR

; вызов подпрограммы PODPR

; ...

 

 

Рис. 25. Пример программы с использованием подпрограммы

При работе с подпрограммами важно обеспечить передачу параметров из вызывающей программы в подпрограмму и возврат результатов выполнения подпрограммы обратно в вызывающую программу. В ассемблере AVR-микро-

контроллеров способы обмена данными между вызывающей программой и подпрограммой не формализованы. Для передачи параметров могут исполь-

зоваться регистры общего назначения, ячейки оперативной памяти и стек.

Передача параметров через регистры общего назначения пригодна только для небольшого числа параметров, так как число РОН ограничено и за-

нятые под параметры регистры уже нельзя использовать в подпрограмме для участия в других вычислениях и хранения других данных. Однако это самый простой и прозрачный способ передачи параметров, обеспечивающий самый быстрый доступ к передаваемым параметрам.

Использование оперативной памяти для передачи параметров требует жёсткой регламентации правил обращения к ним. Например, можно организо-

вать в памяти массив (таблицу) для непосредственного хранения значений пе-

редаваемых параметров или их адресов; адрес начала массива занести в РОН.

Имея начальный адрес массива, вызывающая программа и подпрограмма смо-

гут получить доступ к требуемым параметрам.

7

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

LDI

R16, $33

;

R16 <- $33

PUSH

R16

;

сохранение содержимого регистра R16 в стеке

то в подпрограмме можно получить к нему доступ:

IN

R30, SPL

; младший байт указателя стека

IN

R31, SPH

;

старший байт указателя стека

LDD

R20, Z+3

;

загрузка числа $33 из стека в регистр R20

(команда IN служит для считывания содержимого регистра ввода-вывода в РОН). Аналогично можно использовать стек для хранения адреса массива передаваемых параметров, расположенного в оперативной памяти данных.

ЗАДАНИЕ

1. Составить программу, использующую для вызова подпрограммы команду RCALL. Выполняемую подпрограммой функцию взять из задания лабораторной работы № 4 (по указанию преподавателя). Для передачи параметров в подпрограмму использовать регистры общего назначения. Выполнить программу в пошаговом режиме, отслеживая изменение содержимого программного счётчика, указателя стека, а также занесение в стек адреса возврата из подпрограммы.

2. Выполнить задание п. 1, используя стек для передачи параметров в под-

программу. Проследить в симуляторе занесение передаваемых параметров в

стек.

3. Выполнить задание п. 2, применив для вызова подпрограммы команду

ICALL.

СОДЕРЖАНИЕ ОТЧЁТА

Отчёт должен содержать: титульный лист с указанием номера и названия лабораторной работы, номера группы и фамилий выполнивших работу; цель работы; листинги трансляции программ в соответствии с заданием.

КОНТРОЛЬНЫЕ ВОПРОСЫ

1.Условия взаимодействия вызывающей программы и подпрограммы.

2.Принципы организации и назначение стека.

3.Механизм вызова подпрограмм.

4.Команды работы с подпрограммами на ассемблере микроконтроллеров се-

мейства AVR.

5.Способы обмена данными между вызывающей программой и подпрограм-

мой.

9

ПРИЛОЖЕНИЕ 1

Основные характеристики микроконтроллеров

групп Tiny AVR, Mega AVR и LCD AVR

 

 

 

 

 

 

 

 

Tiny AVR

 

 

 

 

 

Mega AVR

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Характеристика

 

 

ATtiny13

 

ATtiny15L

 

ATtiny26

 

ATtiny28

 

ATtiny2313

 

ATmega48

 

ATmega8

ATmega88

ATmega8515

ATmega8535

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Объём

памяти

программ

1

1

2

2

2

 

4

8

8

8

8

 

(FLASH), Кбайт

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Объём

внутренней

оперативной

64

 

128

 

128

 

256

512

512

512

512

 

памяти данных (SRAM), байт

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Объём энергонезависимой памяти

64

64

128

 

128

 

512

 

1K

1K

512

512

 

данных (EEPROM), байт

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Количество команд

 

 

120

90

118

90

120

 

130

130

130

130

130

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Количество линий ввода-вывода

6

6

16

20

18

 

23

23

23

35

32

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Количество векторов прерываний

10

9

12

6

19

 

19

19

19

17

21

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Разрядность программного счётчи-

16

16

16

16

16

 

16

16

16

16

16

 

ка (PC)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Стек1

 

 

 

 

 

П

 

А

 

П

 

А

 

П

 

П

 

П

П

П

П

 

 

 

 

 

 

 

 

 

 

 

 

 

 

8-разрядный таймер-счётчик

1

2

2

1

1

 

2

2

2

1

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

16-разрядный таймер-счётчик

 

 

 

 

 

1

 

1

1

1

1

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Сторожевой таймер

 

 

+

+

+

+

+

 

+

+

+

+

+

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Аналоговый компаратор

+

+

+

+

+

 

+

+

+

+

+

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

АЦП (10 разрядов), каналов

4

4

11

 

 

 

8

8

8

8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Аппаратный умножитель

 

 

 

 

 

 

 

+

+

+

+

+

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Универсальный

асинхронный

 

 

 

 

 

1

 

1

1

1

1

1

 

приёмопередатчик (УАПП)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Интерфейс SPI для обмена данны-

 

 

 

 

 

 

 

2

1

2

1

1

 

ми