Стек

  • Час 16-12-2014, 16:34
  • Автор admin
  • Коментарів 0 Комент.
  • Силка url

Стек являє собою область пам'яті, яку ЦПУ використовує для збереження і відновлення адрес повернення з підпрограм.
Практично у всіх мікроконтролерів AVR стек розміщується в SRAM. Для адресації поточного елемента (вершини стека) використовується покажчик стека SP (Stack Pointer). Це однобайтовий РВВ SPL у моделей з об'ємом пам'яті даних до 256 б, або багатобайтових SPH: SPL (SPH - старший байт, SPL - молодший байт).

Коли мікропроцесор зустрічає одну з інструкцій викликів rcall / call / ecall / icall / eicall, то адреса наступного за ними слова в пам'яті програм апаратно копіюється в стек. У момент виходу з підпрограми по команді ret адресу повернення відновлюється з стека в програмний лічильник. У моделях з об'ємом пам'яті програм 128 і 256 к / слів для збереження PC в стеку потрібно 3 байта, для всіх інших - 2 байти. При збереженні кожного байта вміст SP зменшується не одиницю, а при відновленні, відповідно збільшується.

Стек

Рис.9 Розташування стека в пам'яті даних

Програміст повинен самостійно визначити місце розташування стека на самому початку програми. З точки зору максимальної його глибини, вершину стека потрібно помістити в самому кінці SRAM, як це показано на рис.9:

.include "m8def.inc" ldi temp, low (RAMEND); встановлюємо SP = RAMEND out SPL, temp; для ATmega8 SP = 0x045F ldi temp, high (RAMEND) out SPH, temp

Константа RAMEND зі стандартного заголовного файлу m8def.inc має значення адреси останньої клітинки SRAM. 

У діапазоні адрес SRAM між РВВ і поточним становищем SP розміщуються змінні прикладної програми. Тому дуже важливо попередньо оцінити максимальний розмір стека (глибину стека). Може статися так, що вершина стека підніметься дуже високо і почне "затирати" дані користувача, а це одна з найбільш складно-що виявляються помилок!

Стек AVR, крім збереження адрес повернення, має ще одне дуже важливе призначення. Він дозволяє зберігати будь-які дані спеціально призначеними для цього командами push Rr (завантаження в стек) і pop Rd (вивантаження з стека). Кожен раз при виконанні push Rr вміст Rr копіюється в стек, після чого SP зменшується на одиницю. При виконанні pop Rr вміст комірки стека, на яку вказує SP, відновлюється в Rr, а саме значення SP инкрементируется. Стек подібного роду має організацію Last In First Out (Перший Увійшов Останній Вийшов): регістр, збережений останньою командою push, буде відновлений першою командою pop:

; SP Рівень стека після команди push R16; зберігаємо R16 0x045F R16? ? push R17; зберігаємо R17 0x045E R16 R17? push R18; зберігаємо R18 0x045D R16 R17 R18 ???????? pop R18; відновлюємо R18 0x045D R16 R17? pop R17; відновлюємо R17 0x045E R16? ? pop R16; відновлюємо R16 0x045F? ? ?

Через стек дуже просто можна обміняти вміст регістрів місцями:

; Обмін R16 lt; -gt; R17 SP Рівень стека після команди push R16; зберігаємо R16 0x045F R16? push R17; зберігаємо R17 0x045E R16 R17 pop R16; відновлюємо R16 0x045E R16? pop R17; відновлюємо R17 0x045F? ?

Стек

Рис.10 Приклад роботи стека

На рис.10 наведено невеликий фрагмент коду, в якому покроково розглянуто процес зміни стека при вході і виході з підпрограми toggle і збереженні та відновленні регістра R17. Це типовий приклад, де можуть знадобитися інструкції push / pop. Підпрограма toggle використовує РОН R17 у своїх потребах, але цей-же регістр може використовуватися і в ході основної програми. Тому, щоб уникнути пошкодження даних, R17 перед модифікацією завантажується в стек і відновлюється з нього перед командою ret.

У деяких застарілих моделей ATtiny відсутня SRAM. Тому стек таких мікропроцесорів має зовсім інший пристрій. Він реалізований апаратно у вигляді недоступною для програміста області пам'яті. Глибина стека - всього три рівні вкладення, що, відповідно, дозволяє викликати не більше трьох підпрограм. Апаратний стек не призначений для збереження даних.

Перейти до наступної частини: Переривання

Tags

Коментарі до новини