Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Я всё прекрасно понимаю, но похоже придумал себе невесть что.
Я понял так:
1. Создаем простой файл на Си.
2. В этом файле имеем строку "asm()".
3. Включаем файл (инклюдом) с программой, написаной на асм.
4. Транслируем и получаем результат.

Это моя глобальная ошибка?
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

trofim2 писал(а):Это моя глобальная ошибка?
вот это - глобальнейшая ошибища:
trofim2 писал(а):Включаем файл (инклюдом) с программой, написаной на асм
никогда никаких инклюдов других файлов с исходными текстами быть не должно! в Си инклюдятся только заголовочные файлы, которые не должны содержать реализаций функций - только описания и определения, да и то с ограничениями!

asm - это "оператор" ассемблерной вставки, он имеет особый формат, сильно отличающийся от привычного ассемблерного исходника.
сравните сами:
ассемблерная вставка
Спойлер

Код: Выделить всё

asm volatile ( ";                 \n\t \
  ldi   %[status],%[TX_Disable]     \n\t \
  sts   %[UCSRnB_addr], %[status]   \n\t \
  sbi   %[cs_port],%[cs_pin]        \n\t \
  ldi   %[counter], %[delay]  ;1    \n   \
WAIT_LOOP%=:                        \n\t \
  dec   %[counter]            ;1    \n\t \
  brne  WAIT_LOOP%=           ;1/2  \n\t \
  cbi   %[cs_port],%[cs_pin]  ;2    \n\t \
  ldi   %[status],%[TX_Enable]      \n\t \
  sts   %[UCSRnB_addr], %[status]   \n   \
  "
  : [counter] "=d" (counter), [status] "=d" (status)
  : [delay] "I" (_ST7735_SPI_RAMRD_DELAY_CYCLES_/3+1),
    [UCSRnB_addr] "M" (_ST7735_SPI_UCSRnB_ADDRESS_),
    [TX_Enable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(1<<TXEN0)),
    [TX_Disable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(0<<TXEN0)),
    [cs_port] "I" (PIN_TO_PORTn_OFFSET(ST7735_CHIPSELECT_PIN)),
    [cs_pin] "I" (PIN_TO_PINn_BIT(ST7735_CHIPSELECT_PIN))
  : "cc" );
обычный ассемблерный код примерно с тем же функционалом
Спойлер

Код: Выделить всё

  ldi   r16,TX_Disable
  sts   UCSRnB_addr, r16
  sbi   PORTB, cs_pin
  ldi   r22, delay
WAIT_LOOP:
  dec   r22
  brne  WAIT_LOOP
  cbi   PORTB, cs_pin
  ldi   r16, TX_Enable
  sts   UCSRnB_addr, r16
поэтому правильное использование ассемблерного модуля должно быть таким:
1. создаем проект WinAVR (в AVR Studio 4.xx - как в более новых, не знаю)
2. создаем файл с расширением .S
3. добавляем его в проект
4. задаем опции проекта - тип МК, частоту и т.п.
5. компилируем

в файле .S у вас могут быть описанные по правилам синтаксиса avr-as функции, которые можно использовать в других исходниках (файлы .c или .S), причем сами эти функции тоже могут использовать глобальные переменные, определенные в других файлах проекта... но в самом простейшем случае у вас может быть единственный исходник .S - в этом случае он обязательно должен содержать глобальную метку main - это и будет главная функция. при этом следует знать, что ДО перехода на эту метку автоматически будет настроен указатель стека и проведена очистка памяти под глобальные неинициализированные переменные, а инициализированные будут проинициализированы - все как в Си.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

Никого не хочу обидеть, но не слишком ли много, скажем так - действий, ради более мощного препроцессора. Или я ошибаюсь, и выигрываешь ещё что-то?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

писать на ассемблере - само по себе уже слишком много действий... однако ж это вас не останавливает...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

ARV писал(а):
ptr128 писал(а):Я вот тоже все никак не пойму народ.
внутри asm() нельзя применять макросы - основная плюшка avr-as.
С какого перепугу?

Компилирует и работает:

Код: Выделить всё

static inline void st7735_spi_tft_read_cs_strobe(void)
{
  uint8_t counter, status;

  asm volatile ( ";                 \n\t \
  		.macro SUM  parm              \n\t \
  		add   r0, \\parm              \n\t \
  		.endm                         \n\t \
  SUM   r1                          \n\t \
  ldi   %[status],%[TX_Disable]     \n\t \
  sts   %[UCSRnB_addr], %[status]   \n\t \
  sbi   %[cs_port],%[cs_pin]        \n\t \
  ldi   %[counter], %[delay]  ;1    \n   \
WAIT_LOOP%=:                        \n\t \
  dec   %[counter]            ;1    \n\t \
  brne  WAIT_LOOP%=           ;1/2  \n\t \
  cbi   %[cs_port],%[cs_pin]  ;2    \n\t \
  ldi   %[status],%[TX_Enable]      \n\t \
  sts   %[UCSRnB_addr], %[status]   \n\t \
  "
  : [counter] "=d" (counter), [status] "=d" (status)
  : [delay] "I" (_ST7735_SPI_RAMRD_DELAY_CYCLES_/3+1),
    [UCSRnB_addr] "M" (_ST7735_SPI_UCSRnB_ADDRESS_),
    [TX_Enable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(1<<TXEN0)),
    [TX_Disable] "M" ((0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(0<<RXEN0)|(0<<TXEN0)),
    [cs_port] "I" (PIN_TO_PORTn_OFFSET(ST7735_CHIPSELECT_PIN)),
    [cs_pin] "I" (PIN_TO_PINn_BIT(ST7735_CHIPSELECT_PIN))
  : "cc" );
}
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Реклама
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

Мда... Однако... Интересную тему затронули. Большое спасибо всем за информацию, самому бы пришлось долго копаться, что-бы получить какое-то внятное представление. Я думаю, что если в будущем понадобится писать что-то больше 8 - 16Кбайт, то одним ассемблером наверно не обойдусь. Но пока хватает avrasm2.
Реклама
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Меня вполне устраивает avrasm2, кроме отсутствия локальных меток.
Надеялся, что можно будет написать макросы для этих целей.
Можно сделать вывод, что для тех кто очень любит ассемблер можно забыть о avr-as.
Какие еще варианты могут быть? Какие еще трансляторы есть?
Друг Кота
Аватара пользователя
Сообщения: 15792
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Как это "локальных меток нет"?
:shock:
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Приведи пример.
Встал на лапы
Сообщения: 139
Зарегистрирован: Сб май 07, 2011 17:00:42
Откуда: Оттуда

Сообщение bondyara »

После перехода на Linux начал использовать компилятор AVRA.
Возникла проблема. Раньше в макросах для универсальности и исключения вывода ошибок использовал конструкции вида:

Код: Выделить всё

.ifndef PORTB
	.equ	PORTB = 0
.endif
Теперь получаю ошибку: Can't redefine constant PORTB, use .SET instead
Что интересно, если заменить .equ на .set получаю ошибку: PORTB have already been defined as a .EQU constant. Замкнутый круг.
Получается, ifndef не работает. Потестировал - действительно, содержимое .ifdef и .ifndef срабатывают, независимо от того, объявлена ли константа.

Как выйти из ситуации?
Пробовал делать так:

Код: Выделить всё

.set PORTB = (PORTB | 0)
Та же проблема: PORTB have already been defined as a .EQU constant

Чтобы не было вопросов "А зачем?" - использую при создании виртуального порта, далее идет

Код: Выделить всё

.if @1 == PORTB
	.equ	VPORT0 = PORTB
	.equ	VDDR0 = DDRB
	.equ	VPIN0 = PINB
Сейчас посмотрел объявление констант в разных МК, в принципе всегда:
DDRB = PORTB - 1, PINB = PORTB - 2
Можно код упростить, тогда и проверка существования констант не нужна, но все же как проверять правильно?
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Насколько я знаю константы определенные через equ не могут быть изменены, для этого используется .set.

Вот что касается
.ifndef <symbol>

Includes the code present between the .ifndef and the
corresponding .else or .endif if the symbol is not
defined. Only symbols declared by .EQU or .SET are
evaluated by .ifndef; symbols defined by the .def
directives are treated differently by the assembler and
cannot be used with .ifndef.
Наверное PORTB определен через define.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Встал на лапы
Сообщения: 139
Зарегистрирован: Сб май 07, 2011 17:00:42
Откуда: Оттуда

Сообщение bondyara »

Z_h_e писал(а):Наверное PORTB определен через define.
Как раз через EQU.
Друг Кота
Аватара пользователя
Сообщения: 15792
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

В данном сдучае нужно не присваивание (equ/set) а что-то из директив, аналогичных микрочиповской #define - директивы определяющей замену текста (переназначение ранее назначенных имен при сохранении исходного значения метки).
пример из проекта под mplab8.92:
#define test_port PORTB
Только вот у атмелевского компилятора для АВР #define выполняет несколько иной функционал...
:(
Так что покопайтесь в директивах конкретного компилятора - может чего и накопается...
:dont_know:
Кстати... у того же атмелевского компилятора для mcs51 - c51asm.exe функционал переприсвоения выглядит таким образом:
test_port equ PORTB
или равноценно
.equ test_port=PORTB
:roll:
Первый раз сказал Мяу!
Сообщения: 31
Зарегистрирован: Сб сен 17, 2016 18:56:30

Сообщение dimmer »

AVRASM2 игнорирует всё, что написано между .if и .endif , если условие ложно. Там могут быть даже синтаксические ошибки (если мне память не изменяет). AVRA видимо работает иначе. Можно попробовать сделать так, вдруг прокатит:

Код: Выделить всё

.ifndef PORTB
   .undef PORTB
	.equ	PORTB = 0
.endif
Или вводить дополнительную псевдопеременную

Код: Выделить всё

.set _PORTB = PORTB
и дальше работать с ней.
Ну самый некрасивый вариант - переделать апнотовский файл .inc: заменить все .equ на .set .
Друг Кота
Аватара пользователя
Сообщения: 15792
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

undef отключит определение по всем участкам программы.
Посему при больших текстовках не есть хорошо (ежли используются попеременно оба определения).
:(
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

А может решить проблему радикально и перейти на gnu-assembler (его автоматически вызывает avr-gcc для *.S - файлов)? В нем хотя бы есть нормальный препроцессор.
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Расскажите или покажите пример, каким образом вызвать gnu-assembler для *.S - файлов.
Я в Си ничего не понимаю.
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Код: Выделить всё

wiselord@wiselord ~ $ avr-as --help
Использование: avr-as [параметр...] [asm-файл...]
Спойлер

Код: Выделить всё

Параметры:
  -a[доп-параметры...]    создать листинг
                          Доп-параметры [по умолчанию hls]:
                          c      пропускать ложные ветви
                          d      пропускать отладочные директивы
                          g      включать общую информацию
                          h      включить исходный код высокого уровня
                          l      включать ассемблерный код
                          m      включать раскрытие макросов
                          n      пропускать разбивку на страницы
                          s      включать символы
                          =ФАЙЛ  записывать в ФАЙЛ (должно быть последним)
  --alternate             сразу включить альтернативный синтаксис макросов
  --compress-debug-sections
                          compress DWARF debug sections using zlib
  --nocompress-debug-sections
                          don't compress DWARF debug sections
  -D                      выводить ассемблерные отладочные сообщения
  --debug-prefix-map OLD=NEW
                          map OLD to NEW in debug information
  --defsym СИМ=ЗНА        назначить СИМволу нужно ЗНАчение
  --execstack             требовать исполняемый стек для этого объекта
  --noexecstack           не требовать исполняемый стек для этого объекта
  --size-check=[error|warning]
                          ELF .size directive check (default --size-check=error)
  -f                      не выполнять пред-обработку пробелов и комментариев
  -g --gen-debug          генерировать отладочную информацию
  --gstabs                генерировать отладочную информацию STABS
  --gstabs+               генерировать отладочную информацию STABS
                          с расширениями GNU
  --gdwarf-2              генерировать отладочную информацию DWARF2
  --gdwarf-sections       generate per-function section names for DWARF line information
  --hash-size=<знач>      задать размер хэш таблицы близким к <значению>
  --help                  показать это сообщение и закончить работу
  --target-help           показать параметры, подходящие только к этой цели                      
  -I КАТ                  добавить КАТалог в список поиска, используемого                        
                          директивами .include                                                   
  -J                      не предупреждать о знаковом переполнении                               
  -K                      warn when differences altered for long displacements                   
  -L,--keep-locals        сохранять локальные символы (например,                                 
                          начинающиеся с L)                                                      
  -M,--mri                ассемблировать в режиме совместимости с MRI                            
  --MD ФАЙЛ               записывать информацию о зависимостях в ФАЙЛ                            
                          (по умолчанию не записывается)
  -nocpp                  игнорируется
  -o OBJ-ФАЙЛ             имя объектного файла результата (по умолчанию a.out)
  -R                      поместить раздел данных в раздел текста
  --reduce-memory-overheads 
                          prefer smaller memory use at the cost of longer
                          assembly times
  --statistics            print various measured statistics from execution
  --strip-local-absolute  удалить локальные абсолютные символы
  --traditional-format    использовать родной для ассемблера формат,
                          если возможно
  --version               показать версию ассемблера и закончить работу
  -W  --no-warn           не показывать предупреждения
  --warn                  показывать предупреждения
  --fatal-warnings        считать предупреждения ошибками
  -w                      игнорируется
  -X                      игнорируется
  -Z                      генерировать объектный файл не смотря на ошибки
  --listing-lhs-width     set the width in words of the output data column of
                          the listing
  --listing-lhs-width2    set the width in words of the continuation lines
                          of the output data column; ignored if smaller than
                          the width of the first line
  --listing-rhs-width     set the max width in characters of the lines from
                          the source file
  --listing-cont-lines    set the maximum number of continuation lines used
                          for the output data column of the listing
  @ФАЙЛ                   прочитать парамеры из ФАЙЛа
AVR Assembler options:
  -mmcu=[avr-name] select microcontroller variant
                   [avr-name] can be:
                   avr1  - classic AVR core without data RAM
                   avr2  - classic AVR core with up to 8K program memory
                   avr25 - classic AVR core with up to 8K program memory
                           plus the MOVW instruction
                   avr3  - classic AVR core with up to 64K program memory
                   avr31 - classic AVR core with up to 128K program memory
                   avr35 - classic AVR core with up to 64K program memory
                           plus the MOVW instruction
                   avr4  - enhanced AVR core with up to 8K program memory
                   avr5  - enhanced AVR core with up to 64K program memory
                   avr51 - enhanced AVR core with up to 128K program memory
                   avr6  - enhanced AVR core with up to 256K program memory
                   avrxmega2 - XMEGA, > 8K, < 64K FLASH, < 64K RAM
                   avrxmega3 - XMEGA, > 8K, <= 64K FLASH, > 64K RAM
                   avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM
                   avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM
                   avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM
                   avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM
                   avrtiny   - AVR Tiny core with 16 gp registers
  -mall-opcodes    accept all AVR opcodes, even if not supported by MCU
  -mno-skip-bug    disable warnings for skipping two-word instructions
                   (default for avr4, avr5)
  -mno-wrap        reject rjmp/rcall instructions with 8K wrap-around
                   (default for avr3, avr5)
  -mrmw            accept Read-Modify-Write instructions
  -mlink-relax     generate relocations for linker relaxation
Known MCU names:
  avr1 avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1
  avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny
  at90s1200 attiny11 attiny12 attiny15 attiny28 at90s2313 at90s2323
  at90s2333 at90s2343 attiny22 attiny26 at90s4414 at90s4433 at90s4434
  at90s8515 at90c8534 at90s8535 ata5272 attiny13 attiny13a attiny2313
  attiny2313a attiny24 attiny24a attiny4313 attiny44 attiny44a attiny84
  attiny84a attiny25 attiny45 attiny85 attiny261 attiny261a attiny461
  attiny461a attiny861 attiny861a attiny87 attiny43u attiny48 attiny88
  attiny828 at86rf401 at43usb355 at76c711 atmega103 at43usb320 attiny167
  at90usb82 at90usb162 ata5505 atmega8u2 atmega16u2 atmega32u2 attiny1634
  atmega8 ata6289 atmega8a ata6285 ata6286 atmega48 atmega48a atmega48pa
  atmega48p atmega88 atmega88a atmega88p atmega88pa atmega8515 atmega8535
  atmega8hva at90pwm1 at90pwm2 at90pwm2b at90pwm3 at90pwm3b at90pwm81
  at90pwm161 ata5790 ata5795 atmega16 atmega16a atmega161 atmega162
  atmega163 atmega164a atmega164p atmega164pa atmega165 atmega165a
  atmega165p atmega165pa atmega168 atmega168a atmega168p atmega168pa
  atmega169 atmega169a atmega169p atmega169pa atmega32 atmega32a atmega323
  atmega324a atmega324p atmega324pa atmega325 atmega325a atmega325p
  atmega325pa atmega3250 atmega3250a atmega3250p atmega3250pa atmega328
  atmega328p atmega329 atmega329a atmega329p atmega329pa atmega3290
  atmega3290a atmega3290p atmega3290pa atmega406 atmega64rfr2
  atmega644rfr2 atmega64 atmega64a atmega640 atmega644 atmega644a
  atmega644p atmega644pa atmega645 atmega645a atmega645p atmega649
  atmega649a atmega649p atmega6450 atmega6450a atmega6450p atmega6490
  atmega6490a atmega6490p atmega64rfr2 atmega644rfr2 atmega16hva
  atmega16hva2 atmega16hvb atmega16hvbrevb atmega32hvb atmega32hvbrevb
  atmega64hve at90can32 at90can64 at90pwm161 at90pwm216 at90pwm316
  atmega32c1 atmega64c1 atmega16m1 atmega32m1 atmega64m1 atmega16u4
  atmega32u4 atmega32u6 at90usb646 at90usb647 at90scr100 at94k m3000
  atmega128 atmega128a atmega1280 atmega1281 atmega1284 atmega1284p
  atmega128rfa1 atmega128rfr2 atmega1284rfr2 at90can128 at90usb1286
  at90usb1287 atmega2560 atmega2561 atmega256rfr2 atmega2564rfr2
  atxmega16a4 atxmega16a4u atxmega16c4 atxmega16d4 atxmega32a4
  atxmega32a4u atxmega32c4 atxmega32d4 atxmega32e5 atxmega16e5 atxmega8e5
  atxmega32x1 atxmega64a3 atxmega64a3u atxmega64a4u atxmega64b1
  atxmega64b3 atxmega64c3 atxmega64d3 atxmega64d4 atxmega64a1 atxmega64a1u
  atxmega128a3 atxmega128a3u atxmega128b1 atxmega128b3 atxmega128c3
  atxmega128d3 atxmega128d4 atxmega192a3 atxmega192a3u atxmega192c3
  atxmega192d3 atxmega256a3 atxmega256a3u atxmega256a3b atxmega256a3bu
  atxmega256c3 atxmega256d3 atxmega384c3 atxmega384d3 atxmega128a1
  atxmega128a1u atxmega128a4u attiny4 attiny5 attiny9 attiny10 attiny20
  attiny40
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18789
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я уже свое мнение высказывал: не надо использовать avr-as отдельно, запуская его из командной строки! потому что потом потребуется ld вызывать - а оно вам надо? если уж все так плохо, что сделать makefile не получается (хотя в комплекте WinAVR вполне себе приличные "визард" есть для упрощенного создания makefile), тогда уж лучше просто вызывать avr-gcc с соответствующими параметрами для компиляции .S файла...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Еще бы пример синтаксиса на асм для as.
Ответить

Вернуться в «AVR»