“Напрямую пишущий” ничего не гарантирует. Напрямую тоже можно всякой чуши написать.
Особенно когда этот человек не знает, нужен слвиг влево или нет …
Вообще, по моим наблюдениям. больше всего ратуют за ассемблер те, кто просто не знает СИ
“Напрямую пишущий” ничего не гарантирует. Напрямую тоже можно всякой чуши написать.
Особенно когда этот человек не знает, нужен слвиг влево или нет …
Вообще, по моим наблюдениям. больше всего ратуют за ассемблер те, кто просто не знает СИ
Да не в I2C дело. Приведенную функцию для инициализации дисплея вполне можно написать и на С. На быстродействии это не скажется.
Но ведь у меня там будут и другие функции, и некоторые такие, где максимум можно выжать именно на ассемблере.
Да и для меня ассемблер просто намного проще и визуально понятнее чем С.
Проблема не в том нужен сдвиг или нет. Проблема - нужен ли сдвиг в GNU.
Я подозреваю что он там не нужен потому что там изначально значение уже сдвинуто.
Вполне возможно.
Это утверждение неочевидно и нуждается в доказательстве.
Обычно для коротких фрагментов результат получается один в один. А в случае длинных компилятор, как правило, выигрывает, т.к. может следить за несколькими десятками переменных, а человек - нет.
А вот с такими людьми мне приходилось общаться.
А потом выяснилось, что этот человек не знает, как разместить надпись по центру экрана. А причина оказалась именно в Ассемблере: арифметическое выражение на несколько действий на ЯВУ записывается в одну строчку, а на Ассемблере - нужно не меньше десятка. Отсюда и образ мышления.
Ассемблер просто ограничивает фантазию, не давая возможности кратко записать что либо, содержащее более одного действия.
А, как известно, наиболее эффекктивна не кодовая оптимизация (единственная доступная Ассемблеру), а алгоритмическая, которую гораздо удобнее делать на ЯВУ.
А про тот случай, когда у Вас есть код для AVR, а Вам надо использовать его для STM32, я даже не говорю.
Как правило, и Ассемблера - тоже.
Вот прямо на уровне диагноза: если человек утверждает, что некоторый алгоритм можно записать только на Ассемблере, но нельзя на ЯВУ, это практически на 100% означает, что он не знает ни Ассемблера, ни ЯВУ.
Покажите как вы это видите. LTO может вам сильно навалить …
Ну например когда-то решил поиграться с адресной лентой. Почитал как она работает и написал так:
(в каждом адресном светодиоде 4 светодиода: красный, зеленый, синий и белый. Информация для зажигания одного светодиода передается 32 импульсами)
.ino
extern "C" {
void start();
void SetOneLed(byte Red, byte Green, byte Blue, byte white);
.S
#define __SFR_OFFSET 0x00
#include "avr/io.h"
.global start
.global SetOneLed
start: sbi DDRB, 5
cbi PORTB, 5
ret
SetOneLed: cli
push r26
ldi r26, 32 ;Передавать будем 32 бита из r22, r24, r20, r18
; Тело цикла должно содержать 20 тактов 6+8+6 (установка бита, задержка 6, условное изменение бита, задержка 8, сброс бита, задержка 6)
cont1: nop
nop
sbi PORTB, 5
; прокручиваем все 4 байта, получаем текущий бит в флаге С
lsl r18
rol r20
rol r24
rol r22
brcs send1
cbi PORTB, 5
send1: adc r18, r24 ; восстанавливаем утерянный бит из флага С (чтобы к концу работы регистры r22,r24,r20,r18 приняли прежнее значение)
sub r18, r24 ; надо оно или нет - хз, но тут программе все равно делать нечего, так что это замена nop'ов
nop
nop
nop
nop
nop
cbi PORTB, 5
dec r26
brne cont1
pop r26
sei
ret
Где-то читал что первые параметры передаются через регистры от R24 до R8, если параметров сильно много, то остальные через стек.
только один ЛЕД зажигаете?
Кстати, с помощью objdump посмотрел что там получилось. Оказалось действительно в моем случае при работе с AVRASM сдвиг нужен, а при работе с GNU нет.
А зачем больше?
Функция написанная на ассемблере зажигает, только один.
А вообще я зажигал 300 светодиодов (ленту длиной 5м), только это уже писал на СИ используя вышеупомянутую функцию.
логично…
Хотя почему-то все писатели обычно пишут на асме и выборку данных из внешнего массива.
Хотя как у вас - и правда проще.
Скорость там особо некритична, тайминги с запасом
Это, если ничего другого делать не надо.
Ну да. нужные тайминги при передаче 4 байт одному светодиоду выдержаны благодаря ассемблеру. Так хоть четко знаешь сколько тактов выполняется каждая команда и никаких неожиданностей не будет. А следующий светодиод можно зажечь хоть сразу, хоть спустя некоторое время от зажигания предыдущего. Главное не превысить некоторое критическое время, после которого все начинается сначала.
Делаем массив длиной равной кол-ву светодиодов, шириной 1-4 байта, в зависимости от необходимого кол-ва цветов, в цикле выводим его на ленту и готовим следующий кадр. обычно даже делай вставлять после этого приходилось.
Я делал матрицу из 300 светодиодов 30x10, рисовал там елочку на фоне падающего снега, бегущую надпись, типа “С Новым Годом!!!”, некоторые другие эффекты. На прочее фантазии не хватило. Но быстродействия хватало с запасом. даже задержки дополнительные ставил, чтобы FPS не был слишком высоким, и лента гарантированно успевала сбрасываться. Вернее задержки delay были тем кодом, которые потребляли большую часть процессорного времени.
Можно конечно и без массива. Но так навряд ли получится реализовать несколько объектов движущихся на фоне друг друга, причем в разные стороны
Собственно это хоть и не ответ на первоначальный вопрос, но разобраться с проблемой мне помог именно он.
Три строки в platform.txt и листинг будет создаваться на автомате:
compiler.objdump.cmd=avr-objdump
compiler.objdump.flags=--disassemble --source --line-numbers --demangle --section=.text
recipe.hooks.objcopy.postobjcopy.1.pattern.windows=cmd /C echo. && "{compiler.path}{compiler.objdump.cmd}" {compiler.objdump.flags} "{build.path}/{build.project_name}.elf" > "{build.path}/{build.project_name}_{build.mcu}_{build.f_cpu}.lst"
Если вместо третьей строки вставить:
recipe.hooks.objcopy.postobjcopy.1.pattern.windows=cmd /C echo. && "{compiler.path}{compiler.objdump.cmd}" {compiler.objdump.flags} "{build.path}/{build.project_name}.elf" > "{build.source.path}/{build.project_name}_{build.mcu}_{build.f_cpu}.lst"
То файл с листингом будет лежать там же где лежит скетч.
Вот уж спасибо! Подозревал, что как-то так можно, но деталей не знал, а копаться лень было.
Спасибо!
@glukmaker, не моё, конечно, дело, но Вы бы не злоупотребляли со сдвигами и вообще, с адресной арифметикой. В том же GNU Asm если структуры, они позволяют записать что Вам нужно (примерно, как в С), а об адресах полей ассемблер позаботится.
Компилятор не сможет. Он хуже программиста. Гораздо.
Отлично. А нет ли возможности чтобы предотвратить дизассемблирование тех участков, где находятся данные, а не код?