Важно: в ассемблере нет линковки, подключаемые файлы вставляются по месту директивы include. Потом весь текст транслируется.
Обычно .inc файлы вставляются в начале main файла, .asm файлы - в конце.
.inc файл предполагает описание макросов, констант, имен регистров и т.п. природа inc файла аналогична сишному .h.
.asm - файл непосредственно с кодом.
Поэтому .inc так же как и .h в C целесообразно подключать вначале файла, а .asm - по месту, и наиболее благоприятное место для них - в конце файла. Таким образом легко можно просмотреть какие файлы подключены к проекту, не блуждая по километровому main.
;===========-----------------
.nolist ;данная директива отключает генерацию кода в листинг, т.е. далее в файле *.lss не будет фиксироваться ассемблерный код
.list ;данная директива включает генерацию кода в листинг, т.е. далее в файле *.lss будет фиксироваться ассемблерный код
.include "m8def.inc" ;подключение стандартного заголовочного файла для ATmega8
.set ИМЯ_КОНСТАНТЫ = ЗНАЧЕНИЕ_КОНСТАНТЫ ;устанавливаем соответствие между символьным именем и ее значением, в программе препроцессор заменит данное имя на её значение
.equ ИМЯ_КОНСТАНТЫ = ЗНАЧЕНИЕ_КОНСТАНТЫ ;тоже самое что и .set, только переустановить значения больше нельзя. Обычно используется для обозначения имен регистров и их бит для портов ввода/вывода и периферии.
.def ИМЯ_КОНСТАНТЫ = R* ;тоже самое, что .set и .equ, только для регистров общего назначения (R0-R31). Активно до операции:
.undef ИМЯ_КОНСТАНТЫ.
;===========-----------------
.cseg ;данная директива означает, что дальше идет код программы
.org 0x00 ;данная директива означает, что код программы будет располагаться с 0-ого адреса в FLASH
name: .db ЗНАЧЕНИЕ ;резервирует один байт во FLASH для значения. Обращение по name.
name: .dw СЛОВО ;резервирует слово (2 байта) во FLASH.
name: .dd ;массив двойных слов — четыре байта
name: .dq ;массив четверных слов — восем байт.
;===========-----------------
.dseg ;данная директива означает, что дальше идет код секция SRAM
.org 0x60
name: .byte 2 ;резервирование 2-х байт в ОЗУ. К ним теперь можно обращаться по метке name.
Запись в счетные 16-битные регистры таймеров производится в порядке: High - Low. Т.е. сначала старший байт, потом младший.
Не забываем про атомарность - запрещаем прерывания, если они могут вклиниться в процесс записи двубайтного числа.
Программный код обязательно начинается с таблицы прерываний или вектора прерывания.
;INTERRUPT VECTORS
rjmp initial ;прерывание от RESET, ссылаемся на обработчик прерывания - initial
rjmp 0 ;rjmp service_INT0 ;внешнее прерывание 0
rjmp 0 ;rjmp service_INT1 ;внешнее прерывание 1
rjmp 0 ;rjmp service_OC2 ;совпадение TCNT2 и OCR2
rjmp 0 ;rjmp service_OVF2 ;переполнение TCNT2
rjmp 0 ;rjmp service_ICP1 ;захват в ICP1
rjmp 0 ;rjmp service_OC1A ;совпадение TCNT1 и OCR1A
rjmp 0 ;rjmp service_OC1B ;совпадение TCNT1 и OCR1B
rjmp 0 ;rjmp service_OVF1 ;переполнение TCNT1
rjmp 0 ;rjmp service_OVF0 ;переполнение TCNT0
rjmp 0 ;rjmp service_SPI ;прерывание от модуля SPI
rjmp 0 ;rjmp service_URXC ;получение байта по USART
rjmp 0 ;rjmp service_UDRE ;опустошение UDR в USART
rjmp 0 ;rjmp service_UTXC ;передача байта по USART
rjmp 0 ;rjmp service_ADCC ;прерывание от АЦП
rjmp 0 ;rjmp service_ERDY ;завершение записи в EEPROM
rjmp 0 ;rjmp service_ACI ;прерывание от компаратора
rjmp 0 ;rjmp service_TWI ;прерывание от модуля TWI
rjmp 0 ;rjmp service_SPMR ;завершение выполнения spm
.org 0x20 ;данная директива означает, что код программы будет располагаться с слова 0x20 в FLASH или с адреса 0x40 (т.е. с 0x40 байта). В FLASH адресация осуществляется по словам, а не по байтам, одно слово равно двум байтам.
;STACK INITIALISATION
initial:
ldi R16,low(RAMEND) ;скопируем в R16 младщий байт из константы RAMEND, которая определена в m8def.inc и хранит размер SRAM
out SPL,R16 ;скопируем значение из R16 в SPL
ldi R17,high(RAMEND) ;скопируем в R16 старший байт из константы RAMEND, которая определена в m8def.inc
out SPH,R17 ;скопируем значение из R17 в SPH
;PERIPHERY INITIALISATION
; -----//-----
; ..
; ..
; -----//-----
;MAIN PROGRAM
main: ; -----//-----
; ..
; ..
; -----//-----
rjmp main