Попался на глаза ассемблерный код для avr-gcc, вспомнил про тему. Данный код собирался с ключами -nostartfiles -nodefaultlibs, чтобы avr-gcc ничего не добавлял, в том числе таблицу векторов. Так-то он самовольничает, пихает и таблицу, и стек конфигурить лезет.. А может мне вектора и не нужны, а нужны пара десятков свободных байтов?
Вернусь к теме. Вот так в gas (gcc assembly) выглядит таблица векторов прерываний и код переключающий светодиод. Секция .vectors будет размещена с нулевого адреса (типа ORG 0), и сразу за ней секция .text с кодом main, где и стек установится, и пустой цикл закрутится.
Выравнивание этих секций 16 бит (flash/progmem), как и у опкодов, так что если проверить map или дизассемблер, то каждый вектор займёт по два байта. Иной раз можно и очевидные вещи повторить. (;
Код:
.section .vectors
vector_table: ; atmega8
rjmp main ; 0 Reset Handler
rjmp def_vect ; 1
rjmp def_vect ; 2
rjmp def_vect ; 3
rjmp def_vect ; 4
rjmp def_vect ; 5
rjmp def_vect ; 6
rjmp def_vect ; 7
rjmp def_vect ; 8
rjmp toggle_led ; 9 Timer0 Overflow
rjmp def_vect ; A
rjmp def_vect ; B
rjmp def_vect ; C
rjmp def_vect ; D
rjmp def_vect ; E
rjmp def_vect ; F
rjmp def_vect ; 10
rjmp def_vect ; 11
rjmp def_vect ; 12
def_vect: rjmp vector_table
.global toggle_led
toggle_led: ; blinked on timer0 ovf (uC's alive)
sbis 0x10, 7 ; PIND
rjmp set_pin
cbi 0x12, 7 ; led on D7
rjmp ed
set_pin: sbi 0x12, 7 ; PORTD
ed:
reti
.section .text
main: ldi 16, 0xff ; stack
out 0x3d, 16 ; SPL
ldi 16, 0x03 ; and
out 0x3e, 16 ; SPH
ldi 16, (1<<7) ; led port direction
out 0x11, 16
ldi 16, 0b00011111 ; enables 2 sec watchdog
out 0x21, 16
ldi 16, 0b00000101 ; timer0 clock/1024
out 0x33, 16
ldi 16, 1 ; timer0 ovf
out 0x39, 16 ; timsk
sei ; sreg
loop:
wdr
rjmp loop