Стек

Стек

Стек представляет собой область памяти, которую ЦПУ использует для сохранения и восстановления адресов возврата из подпрограмм.

Практически у всех микроконтроллеров 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 <-> 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. Поэтому стек таких микропроцессоров имеет совсем другое устройство. Он реализован аппаратно в виде недоступной для программиста области памяти. Глубина стека – всего три уровня вложения, что, соответственно, позволяет вызвать не более трех подпрограмм. Аппаратный стек не предназначен для сохранения данных.

Перейти к следующей части:


Категория: Микроконтроллеры
Метки:

Написать коментарий

*
= 4 + 5

Добавить изображение

Последние статьи