реклама на сайте
подробности

 
 
> Код на Си в два раза больше чем на ASM. Attiny2313, Много rjmp в дизассемблерном коде на Си
aivs
сообщение Mar 12 2013, 22:34
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



Написал тестовую программу на Ассемблере и Си для 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aivs
сообщение Mar 13 2013, 07:14
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



То что код на Си всегда будет больше чем на ассемблере это понятно.
Конкретно эту таблицу векторов прерываний как удалить из этой прошраммы?
Или если дайте почитать про так написать Makefile с нужными опциМи компиляции.
Свои примеры приветствуются!

Сообщение отредактировал aivs - Mar 13 2013, 07:15
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 13 2013, 07:26
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (aivs @ Mar 13 2013, 09:14) *
Конкретно эту таблицу векторов прерываний как удалить из этой программы?

1)Взять тут файл стартапа.
2)Отредактировать его, выкинув лишнее.
3)Ассемблировать.
4)Слинковать с основным модулем добавив линкеру ключ -nostartfiles.
5)Немного дописать основную программу
6)Убить кучу времени пытаясь понять, почему она перестала работать
7)Понять, что в п.2 удалили лишнее sm.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 13 2013, 09:06
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Сергей Борщ @ Mar 13 2013, 11:26) *
+1
Сейчас как раз идёт активное обсуждение добавления нового ключика к компилятору чтобы он сам использовал свободные вектора под код или данные для своего усмотрения.
Есть даже нечто рабочее в виде патча. Но до коммита в транк ещё видимо очень далеко.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.0141 секунд с 7
ELECTRONIX ©2004-2016