Вот так LSTOUT-
;
;************************************************
;* *
;* (c) Copyright Князев В.А. 2004 *
;* *
;* Макроопределения для работы со стеком *
;* *
;************************************************
;
; File: stack.inc
;
; 25-Apr-04 BK Начальная редакция
; 28-Aug-11 BK Последнее изменение
;
; Описание:
; Данные макроопределения позволяют упростить создание
; кодов программ с переменными, расположенными в стеке.
; При этом предполагается, что стековая память организована
; в соответствии с соглашениями, принятыми в компиляторе Си
; фирмы IAR Systems для семейства микроконтроллеров AVR, и
; в качестве указателя стековой памяти используется Y-регистр.
;
; Переменная STACK$ в макроопределениях используется для
; отслеживания текущего уровня стека.
; В тех макрокомандах, где одним из аргументов является список регистров,
; последний заключается в скобки в соответствии с правилами,
; принятыми в языке ассемблера. По умолчанию используются скобки <>.
; Элементы списка разделяются символом запятой. Если список
; регистров состоит из одного элемента, скобки можно опустить.
;
; Предупреждения:
; 1. Хотя размер резервируемой области для стека практически не ограничен,
; корректный доступ к стеку с использованием даных макрокоманд возможен
; ТОЛЬКО В ПРЕДЕЛАХ 64 БАЙТ, считая от вершины стека;
; 2. Порядок доступа к элементам стека определяется порядком размещения
; аргументов в списке, который ПОЛНОСТЬЮ ОПРЕДЕЛЯЕТСЯ ПРОГРАММИСТОМ.
; Будьте внимательны!
;
;
; ** STK$ALC -- Allocate stack
;
; Описание:
; Макрокоманда производит выделение необходимой стекой памяти.
; Поскольку данная макрокоманда устанавливает начальное значение
; текущего уровня стека, она ДОЛЖНА ВЫПОЛНЯТЬСЯ ПЕРВОЙ независимо
; от того, требуется ли фактическое выделение стека в данный момент
; или нет.
;
; Usage: STK$ALC value
;
STK$ALC macro value ; Stack allocation
STACK$ var value ; Текущий уровень
стека
if STACK$ == 0 ; Стековая область не
требуется,
exitm ; то выход
endif ;
;
; Выделить стек
;
if STACK$ < 64 ; One instruction is needed
sbiw r29:r28, STACK$
else ; Two instructions are used
subi r28, LOW(STACK$)
sbci r29, HIGH(STACK$)
endif
endm ; STK$ALC
;
; ** STK$RLS -- release stack
;
; Описание:
; Макрокоманда освобождает ранее выделенную стековую память.
; Эта макрокоманда ДОЛЖНА ВЫПОЛНЯТЬСЯ ПОСЛЕДНЕЙ, чтобы гарантировать
; корректное завершение работы со стеком.
;
; Usage: STK$RLS
;
STK$RLS macro ; Stack release
if STACK$ == 0 ; Стек пуст,
exitm ; то выход
endif ;
;
; Освободить стек
;
if STACK$ < 64 ; One instruction is needed
adiw r29:r28, STACK$
else ; Two instructions are used
subi r28, LOW(-STACK$)
sbci r29, HIGH(-STACK$)
endif
STACK$ var 0 ; Clear stack level
endm ; STK$RLS
;
; ** STK$PUSH -- push on stack
;
; Описание:
; Макрокоманда поочередно заталкивает в стек регистры из списка
; аргументов.
; Данная макрокоманда ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Usage: STK$PUSH <register list>
;
STK$PUSH macro list ; Push register(s) on stack
repti rg, list
STACK$ var STACK$+1
st -Y, rg
endr
endm ; STK$PUSH
;
; ** STK$POP -- pop off stack
;
; Описание:
; Макрокоманда поочередно выталкивает из стека регистры из списка
; аргументов.
; Данная макрокоманда ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Usage: STK$POP <register list>
;
STK$POP macro list ; Pop register(s) off stack
repti rg, list
STACK$ var STACK$-1
ld rg, Y+
endr
endm ; STK$POP
;
; ** STK$GET -- read from stack
;
; Описание:
; Макрокоманда последовательно записывает данные из области стека
; с начальным смещением offset в регистры из списка аргументов.
; Данная макрокоманда НЕ ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Usage: STK$GET offset, <register list>
;
STK$GET macro offset, list ; Read from stack
temp$ var STACK$ - offset
repti rg, list
ldd rg, Yй$
temp$ var temp$ + 1
endr
endm ; STK$GET
;
; ** STK$PUT -- write to stack
;
; Описание:
; Макрокоманда последовательно записывает данные в область стека
; с начальным смещением offset из регистров из списка аргументов.
; Данная макрокоманда НЕ ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Usage: STK$PUT offset, <register list>
;
STK$PUT macro offset, list ; Write to stack
temp$ var STACK$-offset
repti rg, list
std Yй$, rg
temp$ var temp$ + 1
endr
endm ; STK$PUT
LSTOUT+