В каждом проекте приходится ручками прописывать имя_регистра/номер регистра, флаги/номера, переменные в памяти/адреса. При переносимости кусков все приходится переписывать. И не факт, что всегда без ошибок. Сколько раз попадался на том, что некорректно были заданы адреса в памяти, номера флагов. Было и такое, что на поиски ошибок уходило до нескольких дней.
Потерянное время никто вам не вернет. Его не повернуть вспять. И тем более обидно за потерянное время из-за мелочной ошибки.
Поэтому я старался и стараюсь максимально сократить время, затрачиваемое на создание проекта. Созданием макросов, шаблонов. Автоматически определяемые переменные.
С переменными в памяти я решил. Это просто, но пришлось помучиться при пробах. Шаблон:
main.asm:
;=========================================================================
.nolist
.include	"mcudef.inc"
.list
;=========================================================================
;=========================================================================
.equ	XTAL	= 16000000
;=========================================================================
;=============== Функции и глобальные определения проекта ================
#define func(x) High(x), Low(x)
#define NO	0
#define YES 1
#define GLOBAL_TIMERS YES
;=========================================================================
;=========================================================================
;----------- List used register ------------------------------------------
;							n/u - Not Used
;					= r0	result mul
;					= r1	result mul
;					= r2	n/u
;					= r3	n/u
.def	RSREG		= r4
.def	RCLR		= r5
.def	RSER		= r6
.def	EEDREG		= r7
;					= r8	n/u
;					= r9	n/u
;					= r10	n/u
;					= r11	n/u
;					= r12	n/u
;					= r13	n/u
;					= r14	Used. Keyboard_Driver
;					= r15	Used. Keyboard_Driver
;-------------------------------------------------------------------------
.def	TEMP		= r16
;					= r17	Used. Everywhere
;					= r18	n/u
;					= r19	n/u
;					= r20
.def	FLAGS		= r21
.def	CNT			= r22
.def	STREG		= r23 ; Set Task, Set Timer, FSM
.def	DATA_L		= r24 ; adiw/sbiw
.def	DATA_H		= r25 ; adiw/sbiw
;					= r26	XL
;					= r27	XH
;					= r28	YL
;					= r29	YH
;					= r30	ZL
;					= r31	ZH
;=========================================================================
;=========================================================================
.set	NUM_FLG = -1
.macro Set_Flags
.set NUM_FLG = (NUM_FLG+1)
.equ @0 = NUM_FLG
.endmacro
;-------------------------------------------------------------------------
; Ôëàãè.
;	FLAGS:
	Set_Flags	SYSTEM_TICK_FLG
	Set_Flags	TIME_OUT_FLG
	Set_Flags	KEYS_PRESSED_FLG
	Set_Flags	KEYS_HOLD_FLG
	Set_Flags	DEFINE_KEYS_FLG
	Set_Flags	KBD_MSG_FLG
;.equ	SYSTEM_TICK_FLG		= 0
;.equ	TIME_OUT_FLG		= 1
;.equ	KEYS_PRESSED_FLG	= 2
;.equ	KEYS_HOLD_FLG		= 3
;.equ	DEFINE_KEYS_FLG		= 4
;.equ	KBD_MSG_FLG			= 5
;=========================================================================
;=========================================================================
.include	"vectors_atmega8535.inc"
.include	"macros.inc"
.include	"sram.inc"
.include	"eeprom.inc"
.include	"system_timer.inc"
#if (GLOBAL_TIMERS==YES)
.include	"global_timers.inc"
#endif
.include	"service_timers.inc"
.include	"keyboard_driver_init.inc"
.include	"types_keys.inc"
.include	"keyboard_driver_def.inc"
.include	"keyboard_driver_macros.inc"
.include	"keyboard_driver.inc"
.include	"process_errors.inc"
;=========================================================================
;=========================================================================
Initial:
;-------------------------------------------------------------------------
Check_WDRF:
	in		r16,MCUCSR
	sbrs	r16,WDRF
	rjmp	Init
	cbr		r16,1<<WDRF
	sbi		DDRC,0
	out		MCUCSR,r16
Empty_Cycle:
	rjmp	Empty_Cycle
Init:
;-------------------------------------------------------------------------
	Init_Stack
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
	clr		RCLR
	ser		FLAGS
	mov		RSER,FLAGS
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
	Clear_SRAM
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
	Init_Timer2
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
	sei
;-------------------------------------------------------------------------
;----------------------------- Отладка -----------------------------------
	out		PINA,RSER
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
Main:
	rjmp	Main
;=========================================================================
;=========================================================================
Empty_Action:
	ret
;=========================================================================
Модули:
system_timer.inc:
;=========================================================================
;------------------- Âûáîð ðàçìåðà ñèñòåìíûõ òàéìåðîâ --------------------
#define SELECT_S_TIMERS_SIZE S_TIMERS_SMALL
#define S_TIMERS_SMALL	0
#define S_TIMERS_LONG	1
#define	ST_SIZE	ST_SMALL
#define ST_SMALL 2
#define ST_LONG 4
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
#define	SYSTEM_TICK	1 ; Ïåðèîä ñèñòåìíîãî òàéìåðà 1 ìñ
#define SECOND		SYSTEM_TICK*1000
#define MINUTE		SECOND*60
#define HOUR		MINUTE*60
#define DAY			HOUR*24
;-------------------------------------------------------------------------
.dseg
;-------------- Ñïèñîê è îïðåäåëåíèÿ ñèñòåìíûõ òàéìåðîâ ------------------
.equ	S_TIMERS_QUANTITY	= 3 ; Êîëè÷åñòâî ñèñòåìíûõ òàéìåðîâ.
;--------------- Ñïèñîê è ðàçìåð ñèñòåìíûõ òàéìåðîâ ----------------------
.equ	ST_ID_0				= 0
.equ	ST_ID_1				= 1
.equ	ST_ID_2				= 2
.set	ST_PROCESS_KEYS		= ST_ID_0
.set	ST_PERIOD_REPEAT	= ST_ID_1
;--------------------- Ôëàãè ñèñòåìíûõ òàéìåðîâ --------------------------
.equ	ST_BLOCK_FLG		= 0
.equ	ST_TIME_OUT_FLG		= 1
.equ	ST_RERUN_FLG		= 2
.equ	ST_BLOCK			= 1<<ST_BLOCK_FLG
.equ	ST_TIME_OUT			= 1<<ST_TIME_OUT_FLG
.equ	ST_RERUN			= 1<<ST_RERUN_FLG
;-------------------------------------------------------------------------
;------------------------- Ñèñòåìíûé òàéìåð ------------------------------
SYSTEM_TIMER:
SYSTEM_TIMER_0:
.byte	1
SYSTEM_TIMER_1:
.byte	1
#if (SELECT_S_TIMERS_SIZE==S_TIMERS_LONG)
SYSTEM_TIMER_2:
.byte	1
SYSTEM_TIMER_3:
.byte	1
#endif
;-------------------------------------------------------------------------
;-------------------- Î÷åðåäü ñèñòåìíûõ òàéìåðîâ ------------------------
S_TIMERS_QUEUE:
.byte	S_TIMERS_QUANTITY*(ST_SIZE+1)
;-------------------------------------------------------------------------
.cseg
	nop
	nop
	nop
	ret
Осталось только с регистрами разобраться.