Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Частина 2 посл 1 укр.doc
Скачиваний:
1
Добавлен:
07.05.2019
Размер:
1.8 Mб
Скачать

10.5 Контрольні запитанння

1) Призначення, види й особливості операцій розгалужування;

2) Прийняття рішень і альтернативи в програмуванні;

3) Принцип організації чи циклу розгалужування в програмі;

4) Особливості використання умов при переходах;

5) Техніка виконання команд переходів.

Лабораторна робота № 11 маніпуляції зі стеком.Виклик і повернення з підпрограм.Переривання

11.1 Мета роботи

Вивчення стекової організації пам'яті, особливостей роботи з підпрограмами.

11.2 Загальні відомості

Стеком називають спеціально організовану область пам'яті (ОЗП), використовувану для збереження і відновлення даних і адрес, що функціонує за конвейерним безадресним принципом.

Стек являє собою послідовний динамічний лінійний список даних, що передбачає доступ до нього з одного кінця. Тому часто використовують для визначення стека поняття-синоніми - магазинна пам'ять чи список типу "ввійшов останнім, вийшов першим".

Фізично стек може бути реалізований у виді набору внутрішніх регістрів мікропроцесора, як це є в розглянутому випадку, чи розміщений у пам'яті. Стан стека відображається в регістрі, аналогічному регістровой парі, названій покажчиком стека.

Запам'ятовування в стеці називають занесенням і позначають (), а вибірку з нього – витягом (). Звертання до стеку можливо тільки через одну комірку - верхню чи нижню. Адреса зазначеної комірки зберігається в регістрі загального призначення (РЗП), що використовується як покажчик стека (SP).

На практиці стек використовується для збереження і відновлення вмісту регістрів, при роботі з підпрограмами і перериваннях слід зазначити, що в останніх двох випадках стек використовується автоматично.

В НМК передбачені три типи операцій зі стеком: запис, відновлення й обмін. Границя області стека визначається 16-розрядним регістром - покажчиком стека ПС (SP). Запис у стек здійснюється при збереженні в пам'яті вмісту пар регістрів, при виклику підпрограми (адреса повернення), а також при перериваннях.

Запис у стек робиться в такий спосіб:

1) з покажчика стека віднімається 1;

2) за адресою покажчика стека записується старший байт (старший регістр чи старший байт адреси);

3) з покажчика стека віднімається 1;

4) за адресою покажчика записується молодший байт.

Таким чином, щораз, коли в стек міститься один байт інформації, здійснюється від'ємне збільшування покажчика стека. Стек заповнюється в напрямку зменшення значень адрес пам'яті.

Схематичне збереження вмісту пари регістрів R1,R2 за допомогою стека показане на рисунку 11.1.

а - схема запису вмісту регістрової пари в стек;

б - відновлення вмісту регістрової пари

Рисунок 11.1 – Збереження та відновлення вмісту регістрової пари

Відновлення вмісту пари регістрів і повернення здійснюється в зворотному (описаному вище) порядку:

1) за адресою в покажчику стека зчитується молодший байт;

2) до покажчика стека додається 1;

3) зчитується вміст старшого байта;

4) до покажчика стека додається 1.

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

Н априклад: якщо в стек записана послідовність BC, DE, HL, то відновлення робиться в зворотному порядку HL, DE, BC. Обмін зі стеком, як операція, припускає обмін вмісту верхнього елемента і пари регістрів HL. Значення покажчика стека при цьому не змінюється. Графічно зазначений процес виконується в такий спосіб, як зображено на рисунку 11.2.

Рисунок 11.2 – Обмін зі стеком

При виклику підпрограми в стек записується адреса команди, що виконується за командою виклику підпрограми. При поверненні з підпрограми. зі стека в лічильник команд записується адреса повернення. При цьому необхідно пам'ятати, щоб безпосередньо перед виконанням команди верхнім елементом стека було значення адреси повернення. Це значить, що в програмі між командами виклику підпрограми і повернення не повинно бути команд завантаження стека без відновлення.

Особливістю звертання до підпрограми є забезпечення як виходу з головної програми, так і повернення. При цьому повернення необхідно зробити саме в те місце, з якого відбулося звертання. Схематично організація переходу при використанні підпрограми, у тому числі і вкладеної, представлена на рисунку 11.3. Для спрощення умовно показані чотири біта адреси.

а - схема звертання до підпрограми і повернення в основну програму;

б - організація виконання підпрограм

Рисунок 11.3 – Організація переходу

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

Підпрограма за суттю являє собою фрагмент програми, звертання до якої може мати місце в будь-якій точці головної програми звичайно значну кількість разів. Тому легше домогтися зазначеної мети за допомогою команди виклику підпрограм. Механізм її дії заснований на запам'ятовуванні поточного вмісту лічильника команд у момент звертання до підпрограми, що дозволяє легко здійснити повернення в перервану послідовність команд головної програми. На практиці зазначені операції реалізуються лічильником команд, стеком і покажчиком стека. Схематично їхня взаємодія представлена на рисунку 11.4

Чергова область стека

МБ ЛК підпрограми

СБ ЛК підпрограми

МБ ЛК головної програми

СБ ЛК головної програми


00CD

. . .

00CE

SUB CALL

00CF

СБ адреси

00D0

МБ адреси

00D1

INC A

00D2

JNZ

00D3

СБ адреси

00D4

МБ адреси

00D5

. . .

a б

а - фрагмент області основної програми в момент звертання до підпрограми;

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

Рисунок 11.4 – Звертання до підпрограми

При звертанні до підпрограми поточний вміст лічильника команд завантажується в стек і вказує адресу повернення (місцеположення наступної команди). Щораз, коли в стек міститься 1 байт інформації, здійснюється від'ємне збільшення покажчика стека. Стек заповнюється в напрямку вказівки значень адрес пам'яті.

Після завантаження адреси повернення в стек, у лічильник команд завантажується адреса області пам'яті, з якої починається виконання підпрограми (другий і третій байти команди виклику підпрограми). Попередній вміст лічильника команд зберігається в стеці і витягається при збільшенні значення ПС на одиницю при закінченні виконання підпрограми по команді повернення.

Якщо в процесі виконання підпрограми відбувається звертання з неї до іншої підпрограми, то адреса повернення підпрограми так само міститься в стек, як показано на рисунку 11.4,б. При цьому виконується підпрограма другого рівня вкладення. Можливий рівень вкладення підпрограм визначається числом областей - комірок, які має стек. Простір пам'яті, що відводиться під стек, не може одночасно використовуватися іншими частинами програми. Об'єм стека обмежений. Для восьмирозрядного МП ПС - 16 біт. Отже стек може займати до 65536 байт. На практиці, якщо обсяг стека надмірно зростає, відбувається його накладання на робочу область пам'яті і робота МПС порушується, тому що МП не може повернутися до виконання вихідної програми.

Команда виклику підпрограми поєднує функції операцій завантаження в стек і переходу. Спочатку вона завантажує стек вмістом команд, потім лічильник команд завантажується адресою переходу.

Послідовність операцій така:

1) декремент покажчика стека на 1 байт;

2) старший байт лічильника команд завантажується в стек по отриманій адресі;

3) декремент покажчика стека на 1 байт;

4) молодший байт лічильника команд завантажується в стек по отриманій адресі;

5) молодший байт адреси переходу завантажується в молодший байт лічильника команд.

Розглянемо послідовність операцій при виконанні команди повернення:

1) вершина стека витягається, її вміст передається в лічильник команд ( молодший байт );

2) покажчик стека інкрементується на 1;

3) нова вершина стека ( а+1 ) витягається, її вміст передається в старший байт лічильника команд;

4) покажчик стека інкрементується на 1.

Лічильник команд містить шістнадцятирозрядну адресу наступної команди, що витягається з пам'яті. У такий спосіб по команді повернення вміст стека передається в лічильник команд.

Переривання - непередбачене звертання до підпрограми.

Переривання по своїй природі нагадують апаратно реалізований виклик підпрограми, оскільки МП має спеціальні входи, на які можуть подаватися запити на переривання від зовнішніх пристроїв (уведення / виведення). Поява на вході переривання запиту на переривання обумовлює виконання МП визначеної послідовності дій:

1) завершується виконання поточної команди;

2) записується в стек вміст лічильника команд;

3) у лічильник команд завантажується вміст певних областей пам'яті.

11.2.1 Команди переривання

EI — команда дозволу переривання.

DI — команда заборони переривання.

RST n — перехід до спеціальної підпрограми (n = 0... 7).

Для імітації апаратних переривань може бути використана кнопка < ПЕРЕРИВАННЯ > на панелі НМК чи сигнали зовнішніх пристроїв.

МП має спеціальний тригер - дозволу переривання ( ДПР ), що може бути встановлений у "1" чи скинутий у "0" командами EI чи DI відповідно. Якщо тригер ДПР скинутий у "0", система переривань блокована і сигнали ( запити ) не сприймаються. Якщо МП приймає запит переривання, то після виконання поточної команди тригер ДПР скидається в "0", і пристрій, що перериває, апаратно формує команду і посилає її в МП для виконання. Особливість зазначеної команди полягає в тому, що вона не розташовується в пам'яті, не впливає на зміну вмісту лічильника команд, користувач не може змінити. Пристрій, що перериває, формує команду RST, що викликає одну з восьми підпрограм, розташованих у перших комірках пам'яті (RST0... RST7).

Підпрограма обробки переривання повинна зберігати ознаки результату і відновлювати їх при поверненні в основну програму. Для дозволу прийому й обслуговування наступних переривань у підпрограму обробки кожного переривання повинна бути включена команда EI, після чого підпрограма може бути перервана. Таким чином, типова структура підпрограми обробки переривань така:

SUB: PUSH PSW

EI

< Тіло підпрограми >

POP PSW

RET

11.2.2 Команди запису в стек, відновлення й обміну стеком

PUSH B - запис у стек вмісту регістрової пари ВС.

PUSH D - те ж DE.

PUSH H - - // - HL.

PUSH PSW - - // - F, A.

POP D - відновлення вмісту регістрової пари DE.

POP H - те ж HL.

POP PSW - - // - F, A.

XTHL - обмін вмісту верхнього елемента стека і HL.

Як приклад, рекомендується виконати такі завдання:

1) записати до пам'яті, з адреси 800Н коди програми зберігання вмісту регістрів: BC, DE, HL, FA.

Таблиця 11.1

800

LXI SP, 920 H

31 20 09

Завантаження SP = 920H

803

PUSH B

C5

Запис BC у стек

804

PUSH D

D5

Запис DE у стек

805

PUSH H

E5

Запис HL у стек

806

PUSH PSW

F5

Запис FA

Виконати програму командою <CT> 800 <–> 807 <ВП> і заповнити таблицю 11.2.

Таблиця 11.2

BC

DE

HL

PSW

SP

Змінити вміст регістрів: B, C, D, E, H, L, A, F

2) записати програму відновлення регістрів.

Таблиця 11.3

800

POP PSW

F1

Відновлення регістрового стану

801

POP H

E1

Відновлення HL

802

POP D

D1

Відновлення DE

803

POP B

C1

Відновлення BC

Виконати програму командою <CT> 800 <–> 804 <ВП> і заповнити таблицю 11.4.

Таблиця 11.4

BC

DE

HL

FA

SP

Значення регістрів B, C, D, E, H, L, F, A повинні збігатися з відповідними значеннями таблиці 11.2. Значення покажчика стека SP = 0920 H

3) записати в пам'ять програму пересилання даних з одного масиву в інший, використовуючи для адресації регістрову пару HL і команду обміну стеком.

Таблиця 11.5

800

LXI H, 900H

21 00 09

Завантажити HL = 900H, адреса другого масиву

803

LXI SP, 0800H

31 00 08

Завантажити SP = 800H, нижня межа стека

806

PUSH H

E5

Запис HL в стек

Продовження табл. 11.5

807

LXI H, 0

21 00 00

Завантажити HL = 0, адреса другого масиву

80A

MVI C, 80H

0E 80

Завантажити C = 80H - довжина масиву

80C

MOV A, M

7E

Пересилання A  M, елемент першого масиву

80D

INX H

23

HL = HL + 1, збільшення адреси другого масиву

80E

XTHL

E3

Обмін стека з HL

80F

MOV M, A

77

Запис MA, елемент другого масиву

810

INX H

23

HL = HL + 1, збільшення адреси другого масиву

811

XTHL

E3

Обмін стека з HL

812

DCR C

0D

C = C - 1, зменшення довжини масиву

813

JNZ 80CH

C2 0C 08

Продовжити, якщо довжина > 0

816

POP D

D1

Очищення стека

Виконати програму командою <CT> 800 <–> 817 <ВП>. Підрахувати КС вихідного масиву ( 0-7FH ) і КС другого масиву (900Н-97FH), вони повинні збігатися. Заповнити табл. 11.6. При цьому HL – адреса першого масиву, DE – адреса другого масиву, С – довжина масиву.

Таблиця 11.6

HL

DE

C

КС

перший масив

КС

другий масив

11.2.3 Команди виклику підпрограм і повернення з них

CALL addr - виклик підпрограми по заданій адресі.

RET - повернення з підпрограми.

Слід пам'ятати, що при записі кодів команди виклику підпрограми в пам'яті спочатку розміщається молодший байт адреси, а потім старший, аналогічно з записом кодів команд завантаження регістрових пар.

Як приклад, рекомендується виконати такі завдання:

1) записати в пам'ять програму, що використовує виклики підпрограм, що здійснює порівняння вмісту HL і DE.

Таблиця 11.7

800

LXI H, 900H

21 00 09

Завантажити HL, початкова адреса масиву

803

LXI D, 97FH

11 7F 09

Завантажити DE, кінцева адреса масиву

806

LXI SP, 0B00H

31 00 0B

Завантажити ПС = B00H, нижня межа масиву

809

MVI B, 0

06 00

Завантажити B = 0, початкове значення КС

80B

MOV A, B

78

А  В

80C

ADD M

86

Підрахунок КС масиву пам'яті

80D

MOV B, A

47

В  А

80E

INX H

23

HL = HL + 1, адреса наступної комірки

80F

CALL 816H

CD 16 08

Виклик підпрограми

812

JNC 80BH

D2 0B 08

Підпрограма порівняння

Якщо HL > DE, біт переносу 1

Інакше біт переносу 0

815

NOP

00

816

MOV A, E

7B

817

SUB L

95

818

MOV A, D

7A

819

SBB H

9C

81A

RET

C9

Виконати програму поетапно, установлюючи точки зупину (ТЗ) командоюи <CT> 800 <–> ТЗ <BП> відповідно до табл.11.8. Перевірити значення стека в ТЗ.

Таблиця 11.8

ТЗ

80FH

816H

81AH

812H

815H

ПС

В точці зупину ТЗ 3 ( 81АН ) переглянути вміст комірок з адресами ПС, ПС + 1. У них повинні знаходитися молодший і старший байти адреси відповідно до табл.11.9.

Таблиця 11.9

M (ПС)

12

M (ПС +1)

08

2) записати в пам'ять програму, що містить виклик програми з передачею параметрів через стек.

Таблиця 11.10

800

LXI SP, 0B00H

31 00 0B

Завантажити ПС = 0B00H

803

LXI H, 5678H

21 78 56

Завантажити HL = 5678H

806

LXI B, 0123H

01 23 01

Завантажити BC = 0123H

809

LXI D, 9ABCH

11 BC 9A

Завантажити DE = 9ABCH

80C

PUSH H

E5

Запис значень регістрів у стек

80E

PUSH D

D5

Те ж

80F

CALL 813H

CD 13 08

Виклик підпрограми

812

POP H

E1

Завантажити HL - адреса повернення

813

POP D

D1

Відновлення DE

814

POP B

C1

Відновлення BC

815

XTHL

E3

Обмін стеку і HL. Стек - адреса повернення, HL - відновлення значення

816

RET

C9

Повернення

Виконати програму командою <CT> 800 <–> 817 <ВП>.

Перевірити значення регістрів у відповідності до табл 11.11.

Таблиця 11.11

BC

DE

HL

ПС

0123

9ABC

5678

0A00