По порядку....
Сначала покажите мне в ассемблере такую сущность как переменная. ИХ ТАМ НЕТ. То что мы называем переменными - это абстракция более высокого уровня чем ассемблер. Ассемблер и процессор не работает с переменными - он работает с РЕГИСТРАМИ и такой большой абстракцией как память. ДА! то что вы называете памятью это не обязательно ячейки с долговременным хранением данных, просто чаще всего память используется для хранения данных, но вот сюрприз - это не всегда так. И это становится большой неожиданностью для некоторых программистов, особенно в таких специфических штуках как микроконтроллеры и встраиваемые системы. Поэтому для процессора память не более чем устройство с которого можно читать и записывать данные адресно. Таким же образом ассемблер не может в принципе дать вам то что не может процессор, но перед ассемблером есть ещё надстройки всевозможные, которые реализуют тот или иной "человеческий" функционал и некоторое подобие так называемых переменных. Но тут возникает диллема. С одной стороны для человека "переменная" звучит однозначно и понятно, но для процессора.... начинается АД. Ведь процессор может адресовать совершенно различные виды памяти - РЕГИСТРЫ, ВНУТРЕННЕЕ адресное пространство, ВНЕШНЕЕ адресное пространство, всевозможные параллельные и последовательные чипы памяти как с программным доступом так и аппаратным - I2C, SPI, параллельный доступ... Вы хотите чтобы ассемблер прозрачно поддерживал всё это разнообразие прямо из коробки? Так этого не будет. Такая поддержка потянет за собой накладные расходы. И получим в итоге... язык С. Вот что значит изобретать велосипед.
Основной смысл – не изобретать велосипед, а использовать готовую функцию.
Думаю, встроенную функцию вызвать проще, соответственно, удобней.
А чем встроенная будет отличаться от не встроенной? По времени вызова? по скорости работы? А вот встроенность потянет за собой дополнительные ограничения - вы не сможете изменить код этой функции под свои потребности, не сможете убрать лишнее, будете мириться с ограничениями накладываемыми этой функцией...
Это какую такую траву надо курить, чтобы придумать метод набора двоичного числа в группу смежных бит одного регистра путем сдвигов нулей или единиц на обозначенное символически число бит? Я имею в виду конструкцию, вроде 0<<CS02 | 1<<CS01 | 1<<CS00 для прескалера таймера 0 вместо простого и понятного (допустим) T0prs64, которое в подключаемом по .Include файле было бы определено, как 0x03.
Это не трава, а тот же самый способ задания констант что и ваш. Только более безопасный. Ваша константа в инклуднике даже в таком виде является магической - это просто плохая практика написания кода, которая предрасполагает к ошибкам по невнимательности. В случае, если в другой ревизии контроллера поменяется адрес этих бит вам придётся шерстить весь исходник в поисках этой константы и заменять на правильную(открывать даташит, пересчитывать константу и прочее), при этом есть вероятность пропустить какое-то место и одну такую константу не поменять. Это неудобный, но ошибкоустойчивый способ задания подобных констант. И его кстати не придумали, ведь это не более чем логические операции над целыми числами которые встроены в язык/препроцессор. Вы вольны делать определения констант так как вы показали, но когда вам понадобится переиспользовать ваш же код в другом проекте с другим родственным контроллером(не писать же для него код с нуля?) вы столкнётесь с такими неочевидными проблемами как разные адреса функциональных бит в регистрах, и все ваши вшитые константы будут требовать пересмотра и проверки, а так же все места где они используются - нет ли там неочевидных способов работы с константами, которые могут поломаться если их адреса поменяются. С записью вроде приведённой вами как "травокурной" такого не будет - там изначально имеется в виду что адрес бита может измениться.
В СИ приходится делать вставки из ассемблера - это вроде как костыли. А костыли свидетельствуют об инвалидности программы, здоровому костыли не нужны.
Это не костыли а необходимость. Причем, обратите внимание сколько при этом нужно предоставить сведений о вашей вставке компилятору чтобы он не поломал ваш код. И сколько требований предъявляется к вставке чтобы она не поломала СИ-шный код. Всё это плата за высокоуровневость.
Но в принципе, хорошо зная язык можно строить такие конструкции на ЯВУ которые разворачиваются компилятором и оптимизатором в быстрый код. Но да, при этом надо много знать особенностей и всяких заморочек.