Не в тему. Вы большой любитель ассемблера. Как Вы оцените мои макрокоманды для работы со стеком?
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Bill 07 июня 2004 г. 11:31
В ответ на: Знамо дело - некрасиво. А что, программно сваять религия не позволяет? Хоть 20 УАРТов. отправлено =mse= 07 июня 2004 г. 11:02


LSTOUT-
;
;************************************************
;* *
;* (c) Copyright Князев В.А. 2004 *
;* *
;* Макроопределения для работы со стеком *
;* *
;************************************************
;
; File: stack.inc
;
; 25-Apr-04 BK Начальная редакция
; 27-Apr-04 BK Последнее изменение
;
; Описание:
; Данные макроопределения позволяют упростить создание
; кодов программ с переменными, расположенными в стеке.
; При этом предполагается, что стековая память организована
; в соответствии с соглашениями, принятыми в компиляторе Си
; фирмы IAR Systems для семейства микроконтроллеров AVR, и
; в качестве указателя стековой памяти мспользуется Y-регистр.
;
; Переменная STACK$ в макроопределениях используется для
; отслеживания текущего уровня стека.
; В тех макрокомандах, где одним из является список регистров,
; последний заключается в скобки в соответствии с правилами,
; принятыми в языке ассемблера. По умолчанию используются скобки <>.
; Элементы списка разделяются символом запятой. Если список
; регистров состоит из одного элемента, скобки можно опустить.
;
; Предупреждения:
; 1. Хотя размер резервируемой области для стека практически не ограничен,
; корректный доступ к стеку с использованием даных макрокоманд возможен
; ТОЛЬКО В ПРЕДЕЛАХ 64 БАЙТ, считая от вершины стека;
; 2. Порядок доступа к элементам стека определяется порядком размещения
; аргументов в списке, который ПОЛНОСТЬЮ ОПРЕДЕЛЯЕТСЯ ПРОГРАММИСТОМ.
; Будьте внимательны!
;

;
; ** STK$ALC -- выделение стека
;
; Описание:
; Макрокоманда производит выделение необходимой стекой памяти.
; Поскольку данная макрокоманда устанавливает начальное значение
; текущего уровня стека, она ДОЛЖНА ВЫПОЛНЯТЬСЯ ПЕРВОЙ независимо
; от того, требуется ли фактическое выделение стека в данный момент
; или нет.
;
; Вызов: STK$ALC value
;
STK$ALC macro value ; Stack allocation

STACK$ var value ; Текущий уровень стека
if STACK$ == 0 ; Стековая область не требуется,
exitm ; то выход
endif ;
;
; Выделить стек
;
if STACK$ < 64 ; Достаточно одной команды
sbiw r29:r28, STACK$
else ; требуется две команды
subi r28, LOW(STACK$)
sbci r29, HIGH(STACK$)
endif
endm ; STK$ALC

;
; ** STK$RLS -- освобождение стека
;
; Описание:
; Макрокоманда освобождает ранее выделенную стековую память.
; Эта макрокоманда ДОЛЖНА ВЫПОЛНЯТЬСЯ ПОСЛЕДНЕЙ, чтобы гарантировать
; корректное завершение работы со стеком.
;
; Вызов: STK$RLS
;
STK$RLS macro ; Stack release

if STACK$ == 0 ; Стек пуст,
exitm ; то выход
endif ;
;
; Освободить стек
;
if STACK$ < 64 ; Достаточно одной команды
adiw r29:r28, STACK$
else ; требуется две команды
subi r28, LOW(-STACK$)
sbci r29, HIGH(-STACK$)
endif
STACK$ var 0 ; Обнулить указатель уровня стека
endm ; STK$RLS

;
; ** STK$PUSH -- затолкнуть в стек
;
; Описание:
; Макрокоманда поочередно заталкивает в стек регистры из списка
; аргументов.
; Данная макрокоманда ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Вызов: STK$PUSH <список регистров>
;
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 -- вытолкнуть из стека
;
; Описание:
; Макрокоманда поочередно выталкивает из стека регистры из списка
; аргументов.
; Данная макрокоманда ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Вызов: STK$POP <список регистров>
;
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 -- чтение данных из стека
;
; Описание:
; Макрокоманда последовательно записывает данные из области стека
; с начальным смещением offset в регистры из списка аргументов.
; Данная макрокоманда НЕ ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Вызов: STK$GET offset, <список регистров>
;
STK$GET macro offset, list ; Read from stack

temp$ var STACK$ - offset
repti rg, list
ldd rg, Y+temp$
temp$ var temp$ + 1
endr
endm ; STK$GET

;
; ** STK$PUT -- чтение данных из стека
;
; Описание:
; Макрокоманда последовательно записывает данные в область стека
; с начальным смещением offset из регистров из списка аргументов.
; Данная макрокоманда НЕ ИЗМЕНЯЕТ значение указателя текущго уровня стека.
;
; Вызов: STK$PUT offset, <список регистров>
;
STK$PUT macro offset, list ; Write to stack

temp$ var STACK$-offset
repti rg, list
std Y+temp$, rg
temp$ var temp$ + 1
endr
endm ; STK$PUT

LSTOUT+


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru