Написал тестовую программу на Ассемблере и Си для Attiny2313.
Программа элементарна, при нажатии на кнопку загорается светодиод, при отпускании гасится.
Вот код на ассемблере:
Код
;##########################################
;## Нажатие на кнопку включает светодиод ##
;##########################################
.include "/usr/share/avra/includes/tn2313def.inc" ; Подключаем файл описаний
.list ; Включаем листинг
.def temp = R16 ; Определение главного рабочего регистра
.cseg ; Выбор сегмента программного кода
.org 0 ; Установка текущего адреса на 0
ldi temp, RAMEND ; Записываем адрес вершины стека в регистр temp
out SPL, temp ; Записываем адрес вершины стека из регистра temp в регистр стека
ldi temp, 0 ; Записываем 0 в регистр temp
out DDRD, temp ; Записываем 0 из регистра temp в DDRD (порт PD на ввод - кнопка)
ldi temp, 0b11111111; Записываем 11111111 в регистр temp
out DDRB, temp ; Записываем 11111111 из регистра temp в DDRB (порт PB на вывод - LED)
out PORTB, temp ; Записываем 11111111 из temp в PORTB (тушим светодиод)
out PORTD, temp ; Записываем 11111111 из temp в PORTD (включаем внутр. резистры)
;--------------- Основной цикл ---------------------;
main: in temp, PIND ; Читаем содержимое порта PD
out PORTB, temp ; Записываем содержимое temp в порт PB
rjmp main ; Переход к началу программы
Затем я дизассемблирил HEX файл, получился точно такой же код:
Код
00000000 <.sec1>:
0: 0f ed ldi r16, 0xDF ; 223
2: 0d bf out 0x3d, r16 ; 61
4: 00 e0 ldi r16, 0x00 ; 0
6: 01 bb out 0x11, r16 ; 17
8: 0f ef ldi r16, 0xFF ; 255
a: 07 bb out 0x17, r16 ; 23
c: 08 bb out 0x18, r16 ; 24
e: 02 bb out 0x12, r16 ; 18
10: 00 b3 in r16, 0x10 ; 16
12: 08 bb out 0x18, r16 ; 24
14: fd cf rjmp .-6 ; 0x10
Вот код на Си:
Код
/****************************************
* Prog1.c
* Нажатие на кнопку включает светодиод
****************************************/
#include <avr/io.h>
#include <avr/iotn2313.h>
void main(void) {
DDRB = 0b11111111; // Во всех разрядах регистра DDRB единицы --> все разряды PB работают на вывод (LED)
PORTB = 0b11111111; // Во всех разрядах PB единицы и все разряды регистра DDRB работаю на вывод --> тушим Led
DDRD = 0b00000000; // Во всех разрядах регистра DDRD нули --> все разряды PD работают на ввод (кнопка)
PORTD = 0b11111111; // Во всех разрядах PD единицы и все разряды регистра DDRD работаю на ввод --> подключаем внутренние резистры
// Вечный цикл
while (1) {
PORTB = PIND;
}
}
После дизассемблера вид такой:
Код
00000000 <.sec1>:
0: 12 c0 rjmp .+36 ; 0x26
2: 17 c0 rjmp .+46 ; 0x32
4: 16 c0 rjmp .+44 ; 0x32
6: 15 c0 rjmp .+42 ; 0x32
8: 14 c0 rjmp .+40 ; 0x32
a: 13 c0 rjmp .+38 ; 0x32
c: 12 c0 rjmp .+36 ; 0x32
e: 11 c0 rjmp .+34 ; 0x32
10: 10 c0 rjmp .+32 ; 0x32
12: 0f c0 rjmp .+30 ; 0x32
14: 0e c0 rjmp .+28 ; 0x32
16: 0d c0 rjmp .+26 ; 0x32
18: 0c c0 rjmp .+24 ; 0x32
1a: 0b c0 rjmp .+22 ; 0x32
1c: 0a c0 rjmp .+20 ; 0x32
1e: 09 c0 rjmp .+18 ; 0x32
20: 08 c0 rjmp .+16 ; 0x32
22: 07 c0 rjmp .+14 ; 0x32
24: 06 c0 rjmp .+12 ; 0x32
26: 11 24 eor r1, r1
28: 1f be out 0x3f, r1 ; 63
2a: cf ed ldi r28, 0xDF ; 223
2c: cd bf out 0x3d, r28 ; 61
2e: 02 d0 rcall .+4 ; 0x34
30: 09 c0 rjmp .+18 ; 0x44
32: e6 cf rjmp .-52 ; 0x0
34: 8f ef ldi r24, 0xFF ; 255
36: 87 bb out 0x17, r24 ; 23
38: 88 bb out 0x18, r24 ; 24
3a: 11 ba out 0x11, r1 ; 17
3c: 82 bb out 0x12, r24 ; 18
3e: 80 b3 in r24, 0x10 ; 16
40: 88 bb out 0x18, r24 ; 24
42: fd cf rjmp .-6 ; 0x3e
44: f8 94 cli
46: ff cf rjmp .-2 ; 0x46
Меня интересует, что это за множество переходов в начале, для чего их делает компилятор?
Компилирую так:
avr-gcc -O2 -Os -mmcu=attiny2313 -o Prog1.elf Prog1..c
avr-objcopy -R .eeprom -O ihex Prog1.elf Prog1.hex