Некоторое время я был занят написанием простенького редактора для языка ассемблер под ARM Cortex семейства микроконтроллеров (подробности в моих статьях), и вот сейчас, поднакопив некоторый опыт как в части самого ассемблера так и способов написания программ в них решился на написание нового редактора.
Плюс еще подоспел интерес к RISC‑V архитектуре и было принято решением делать редактор который смог бы редактировать программы на ассемблере для различных архитектур (в том числе может быть и с лагеря AVR кто нить захочет присоединиться).
Беглое изучение синтаксиса асм инструкций архитектуры RISC‑V дал довольно удручающее впечатление. Если многие хейтеры ARM ассемблер считают излишне сложным (типа слишком много сложный инструкций для запоминания и оперирования ими), то у RISC‑V наоборот все слишком уже просто, настолько просто что я как то принял мысль что RISC‑V это архитектура созданная под компиляцию с языков высокого уровня, поскольку даже элементарные действия на ARM Cortex на RISC‑V превращается в какой то квест с двумя\тремя инструкциями...
Плюс, конечно же в RISC‑V пошли по пути введения новых мнемоник инструкций ассемблера (реальным ведь пользователям все равно как они пишутся, это задача для компилятора транслировать с Си на ассемблер, и потом отдать на компиляцию).
Плюс вспоминая про AVR...
В общем подумалось: а что если попытаться создать asm‑base'д язык программирования который при выборе архитектуры просто бы транслировался автоматически в асм инструкции выбранной платформы?
Плюсом, дополнительно есть желание реализовать некий уровень абстракции от периферии микроконтроллеров, чтобы оставаясь в том же псевдокоде управлять стандартной периферией микроконтроллера не сваливаясь в настройку регистров конкретного mcu.
Причем тут даже не надо менять архитектуру, банально GPIO в STM32F1 и STM32F4 настраивается по разному, хотя суть настроек остается плюс минус такой же. И вот от этого и хочется уйти. За более чем год использования первого редактора ассмеблера (ArmAsmEdit) я и сообщество накопили некоторое количество библиотек кода, и самое занятное что например для драйверов дисплея под разные микроконтроллеры надо создавать свои варианты этих библиотек — банально с cortex-m0 нет битбандинга, или в STM32F1 GPIO настраивается по другому (в том числе на работу с SPI).
Планируемое решение должно максимально облегчить такие задачи, в идеале рабочий драйвер должен получаться просто сменой микроконтроллера причем вне зависимости от архитектуры.
Вот такой примерно был ход мыслей.
Сразу скажу — я не желаю создавать очередной си‑подобный язык высокого уровня! (и не надо об этом писать в комментариях). Цель создать именно язык ассемблера, но с человеческим лицом, в идеале чтобы программисту который захочет его использовать не приходилось бы учить как пишется та или иная инструкция ассемблера в конкретной архитектуре и как она работает...
Задача не простая, но такое преимущество как быстродействие ассемблера терять не хочется (и не надо писать как здорово си компилирует код, смотрели уже, причем ни на какой то логике, где си действительно способен генерить почти прямой асм код, а в целом по программе... вывод — не способен), так что это должны быть достаточно простые инструкции, интуитивно понятные в наборе и одновременно транслируемые в асм инструкции (возможно несколько).
Например, инструкция присваивания может выглядеть вот так:
R0=5
и будет автоматически транслироваться в зависимости от значения присваивания в
MOV R0, 5
Или, если аргумент 16ти битный:
MOVW R0, 0x1234
Или, если значение превышает 16 бит
LDR R0, =0x12345678
Одновременно, при арифметических операциях так же хочется остаться в таком формате написания инструкций
R0=R1+10
будет преобразовано в
ADD R0, R1, 10
или иной формат если слагаемое выйдет за формат Operand2 или imm12. И так далее.
Это все мысли сходу.
Одновременно решил обратиться с вопросом каким бы вы хотели видеть синтаксис этого макроязыка и к тем кто возможно уже имеет опыт создания каких то языков программирования (ведь мало придумать синтаксис, потом еще нужно организовать его быстрый разбор и трансляцию): может быть есть более удачные языковые конструкции для асм‑base'д языка.
Основное пожелание (и цель) — не уйти в придумывание нового множества названий инструкций, а реализовать на интуитивно понятном синтаксисе систему команд например cortex‑m4.
Для участников группы телеграмм записал небольшое видео части мыслей, которые требуют проверки и корректировки:
Ну и если кто решит присоединиться или просто высказать свое авторитетное мнение то всегда можете приходить в телеграмм https://t.me/ArmAsmEditor раздел называется ASM2Concept.
P.S. в комментах спорить по ненужности\бесполезности\тупости\убогости не собираюсь.
Jl
Комментарии (93)
Jury_78
00.00.0000 00:00+5я не желаю создавать очередной си-подобный язык высокого уровня !
R0=5
Но согласитесь - очень похоже. :) Хотя бы на препроцессор Си.
netricks
00.00.0000 00:00+1Действительно, ассемблерные инструкции часто неудобочитаемы и в целом, сделать человекочитаемый ассемблер не кажется плохой идеей. Я вижу проблемы с портированием специфик различных архитектур, скажем, что делать если инструкция есть на одной системе комманд, но отсутствует на другой. И, кроме того, не очень понятно, как лаконично изложить некоторые армовские инструкции, типа тех, что в состав команды включают условность и прочие подобные.
olartamonov
00.00.0000 00:00+6И в итоге это вырастет в некую упрощённую версию C.
jobless
00.00.0000 00:00+2Для x86 есть же C-- (Си минус минус) https://ru.wikipedia.org/wiki/C--
olartamonov
00.00.0000 00:00+5Кстати, да.
А также, конечно,
perfect_genius
00.00.0000 00:00Но ведь с USB-C почти получилось.
datacompboy
00.00.0000 00:00К тому что теперь есть 15 взаимоисключающих проводов которые выглядят одинаково а работают непонятно как? :)
perfect_genius
00.00.0000 00:00Поэтому "почти".
Работают кое-как, но работают. А другие разъёмы не работали бы вообще :D
aamonster
00.00.0000 00:00+2А для 8080 – PL/M. На минуточку, на нём была написана ведущая операционка того времени.
acc0unt
00.00.0000 00:00+3Задачу "сделать человекочитаемый ассемблер" решали ещё в Analog Devices в нулевых. Ассемблер Blackfin как пример - восхитительное безумие.
Ne345
00.00.0000 00:00+7Я писал на ассемблере для ADSP-21xx. Это не безумие. Синтаксис этого ассемблера похож по идеологии, предложенной в этой статье. Синтаксис ассемблера был такой качественный, что написание программ мало отличалось от написания программ на C. Причина, по которой целесообразно было писать тогда на ассемблере - это очень малые ресурсы по памяти и требоваение учета архитектуры для эффективных проектов.
Синтаксис ассеблера ARM имеет исторические корни и изменение его сейчас не очень целесообразно по разным причинам.
Автору статьи - респект за способность мыслить нестандартно.acc0unt
00.00.0000 00:00+3Ну и я про то же.
Смотришь ты на этот синтаксис. Первая мысль - "что это за дичь вообще". Вторая - "а это прикольный синтаксис". И третья - "почему вообще все ассемблеры не сделаны вот так?"
AD осознали необходимость в "ассемблере с человеческим лицом" для нужд DSP и выкатили своё решение. Жаль даже что эти идеи не получили распространения.
byman
00.00.0000 00:00+1очень даже получили. После знакомства с Си-подобным ассемблером AD, я для всех своих микропроцессоров использовал только подобный синтаксис. Запоминать тьму мнемоник очень сложно. Хотя ассемблер обычно намного богаче и со сложными командами приходится все равно приходится что-то придумывать не похожее на Си.
aamonster
00.00.0000 00:00Синтаксис не очень многое меняет, честно говоря... Если команды из одной вариации ассемблера в другую взаимно-однозначно переводятся – то это только вопрос относительно недолгого привыкания.
emusic
00.00.0000 00:00У Borland в свое время получился очень удачный ассемблер для x86 - синтаксис Ideal в TASM, в противовес традиционному синтаксису MASM. Я в 90-х даже всерьез взялся за написание книги по нему, а потом перешел на C++, и задача потеряла актуальность. В этом синтаксисе все очень логично и изящно, поддержка параметров и локальных переменных в процедурах сделана очень удобно. Я на нем плотно писал несколько лет, после него читать программы на MASM - сущая пытка.
eugenk
00.00.0000 00:00+3Асм для dsp-процессоров Analog Devices выглядит примерно так. Хотя облегчает ли это программирование по сравнению с другими процессорами - черт его знает... Когда пришлось под это дело писать, его всё равно надо было плотно осваивать... Может Вы скорее о стандартизации мнемоник различных ассемблеров ???
Для меня вобщем-то примерно подобная задача сейчас тоже актуальна. Есть очень неплохой (на мой взгляд как автора разумеется) самопальный процессор, встраиваемый в FPGA (сейчас потихоньку готовлю серию публикаций о нём). Проблема - на чём его программировать. Усугубляется это в добавок тем, что он управляется микрокодом. Для того чтобы изменить под свою задачу систему команд (в разумных пределах конечно), не надо лезть в дебри верилога. Достаточно описать её на некоем простом языке(микроассемблере), получить микрокод и пересобрать проект(можно даже вообще без пересборки загрузить через аппаратный отладчик). Работы на час-полтора. А вот как менять средства разработки - черт его знает... Пока это у меня решается подробнейшим описанием на русском языке внутренностей ассемблера и симулятора. Чтобы пользователь без труда смог это переписать под свою систему команд. Но это уже ДНИ... Хотелось бы каких-то более фундаментальных решений.
P.S. На всякий случай утащил в закладки. Надеюсь в отличии от сотен и тысяч других, идея не мертворожденная.
P.P.S. Кстати можно подробнее о Вашем редакторе ??? Я сейчас тоже в качестве небольшого хобби и переключения задач пишу нечто, вдохновлённое вот этим https://github.com/rxi/lite , хотя и сильно по-своему.
jobless
00.00.0000 00:00+1История зациклилась как ей и предписано.
"С машиной поставлялся автокод АРМУ (Автокод Ряда Машин Урал), который был единым автокодом ряда ЭВМ типа “Урал”. Он был составлен с учетом особенностей этих машин и обеспечивал полную совместимость от меньшей машины к большей. Каждая ЭВМ “Урал” имела собственный транслятор с языка АРМУ на свой машинный язык. Таким образом, совместимость ЭВМ типа “Урал” была ограниченной и существовала только на уровне автокода АРМУ. "
https://computer-museum.ru/histussr/ural11.htm
p.s. первая программа, которой кто то кроме меня пользовался была написана 40 лет назад как раз для Урал-11
VitGo Автор
00.00.0000 00:00эхх.. и где бы почитать продолжение ? :-)
jobless
00.00.0000 00:00+3Про Уралы Серия https://computer-museum.ru/histussr/ural.htm
А вообще сайт кто то, к счастью, активно пополняет..
У меня мечта для пенсии, сделать эмулятор Урала с ПУЛЬТОМ
Кстати, я не только застал живым Урал-11 в 1983, но и в 1978 сдал первый зачёт по программированию на АЛГАМС
Tim0Ur
00.00.0000 00:00Советую обратить внимание на fasmg: https://flatassembler.net/docs.php?article=fasmg
aamonster
00.00.0000 00:00+4Почитайте про PL/M и C-- – вроде оба достаточно близки к задаче, которую вы себе поставили, возможно, почерпнёте идеи.
Ну и, естественно, готовьтесь к тому, что проект вы создаёте в основном для себя и большая популярность ему не светит...
VaalKIA
00.00.0000 00:00Как вам уже написали, делая кроссплатформенный ассемблер, вы приходите к языку высокого уровня.
Выглядит это примерно так: на одном процессоре есть какие-то инструкции, а на другом нет. Значит берём некое очень ограниченное подмножество инструкций, которые есть на всех рассматриваемых процессорах, а потом для каждого конкретного сворачиваем последовательность микрокодов в одну инструкцию с помощью хинтов (фактически - шаблонов), а там, где не свернулось, работает эта самая микропрограмма. пусть и не так эффективно (и даже может быть свёрнута в несколько операндов). Микрокоды, это некая стековая машина, PI код, или LLVM IR, поэтому, фактически, мы можем придти к тому. что сами микрокоды вообще не являются усечённым подмножеством любой из архитектур, а являются полностью виртуальными. На втором шаге, выделив типовые последовательности, микрокодов, для конкретных программ, даём им имена и получаем операторы ЯВУ и конкретный кроссплатформенный язык.
CrashLogger
00.00.0000 00:00+1Похоже большинство коментаторов не понимают, чем ассемблер (даже с макросами) отличается от языка высокого уровня. Когда мы пишем на ассемблере, мы сами определяем, какие инструкции и в каком порядке будут исполняться процессором. Когда мы пишем на ЯВУ - мы забываем про инструкции процессора и вообще не думаем о них. То, что делает автор статьи - это ассемблер, несмотря на то, что для разных процессоров одна и та же мнемоника транслируется в разные команды. Мы непосредственно оперируем регистрами и адресами в памяти, а не перекладываем это на компилятор. Мы можем сосчитать, сколько тактов процессора и сколько байт в памяти займет наша программа. Мне не приходилось писать на ассемблере одну программу под разные архитектуры, но, возможно, кому-то это будет полезно.
iamkisly
00.00.0000 00:00То что автор предлагает, это
ад, мрак с содомиянекоторое расширение.. чего? за счет препроцессора? компилятора? кто будет это поддерживать? без вендорного интереса?VitGo Автор
00.00.0000 00:00ну это не коммерческий проект.. да и до вендоров сейчас даже дальше чем до китая :-)
то что я пытаюсь сделать будет являться неким препроцессором результат которого будет скармливаться gnu as
RTFM13
00.00.0000 00:00Мы можем сосчитать, сколько тактов процессора и сколько байт в памяти
займет наша программа. Мне не приходилось писать на ассемблере одну
программу под разные архитектуры, но, возможно, кому-то это будет
полезно.Ничего, что у разных архитектур разные системы команд, которые не переводятся одна в другую 1:1 (а не которые вообще не похожи друг на друга) и реализация одних задач будет отличаться командами, количеством тактов и т.п.?
VitGo Автор
00.00.0000 00:00вот поэтому я и говорю о некотором подмножестве инструкций максимально приближенных к ассемблеру..
на счет подсчета количества тактов (гм.. со времен AVR этим не занимался) - но задумка редакторе что генерируемый асм код доступен постоянно - так что посчитать можно еще на этапе редактирования программы, а не искать тот или иной фрагмент в листинге компилятора...
lolikandr
00.00.0000 00:00Порядок инструкций всё же зависит от процессора. Вот вам ассемблер для семейства TMS320C672x - предположите, что произойдёт раньше:
прыжок по адресу B3 (строка 12) ?
запись A3 в *A4 (строка 16) ?
_SumF3: ldw *B4++, B5 || ldw *A6++, A5 ldw *B4++, B7 || ldw *A6++, A7 ldw *B4++, B6 || ldw *A6++, A3 nop 2 addsp A5, B5, A5 addsp A7, B7, A7 addsp A3, B6, A3 || b B3 nop stw A5, *A4++ stw A7, *A4++ stw A3, *A4 nop
Но проще понимается, конечно, вот такое:
void SumF3(float *dst, float *src1, float *src2) { *dst++ = *src1++ + *src2++; *dst++ = *src1++ + *src2++; *dst = *src1 + *src2; }
lamerok
00.00.0000 00:00Вы и на C++ можете ими(адресами, регистр это тоже ячейка памяти) оперировать.
DungeonLords
00.00.0000 00:00+3Я думаю в первую очередь мир нуждается в свободном симуляторе цифро-аналоговых цепей, таком как Proteus или может Simics. Потому что очень хочется сначала прототипировать, а потом паять.
yatanai
00.00.0000 00:00+4Я задумывался над этим вопросом...
Суть проблемы в том что трудно в целом мысленно организовать подобную идею.
Во первых - Многие архитектуры довольно сильно отличаются, потому сделать такую банальную вещь как "относительный переход" довольно запарно. Везде это будет работать по разному. То есть call type_add[ptr] может тупо не собраться и требовать специфических ассемблерных вставок. То есть, уже базовые механизмы работы с потоками управления\данными могут сильно отличаться и требовать неявно вставлять код. (грубо говоря, как AVR не поддерживает float и плодит кучу кода чтоб сделать 1.0+1.0)
Во вторых - этот язык должен быть одновременно "не типизрованным" и уметь в "типизацию". Для большинства архитектур в целом не важно что есть байты в памяти, это может быть как адрес-указатель так и float. При этом нужно учитывать что A + B невалидная операция, ибо что вообще есть +? Это SIMD расширение, 4float или 2double?? Это что-то от FPU? Это число, знаковое число?
В третьих - Есть типовые задачи которые максимально по разному работают на разных процессорах. Такая базовая вещь как "установить бит в памяти" может работать у всех абсолютно по разному, а это значит надо продумывать "std" библиотеки. Без них ты не сможешь гарантировать "нормальную" кроссплатформенность.
В четвёртых - Это всё будет нормально работать вплоть до того как не появится второе ядро. Тогда придётся вводить кучу абстракций чтоб победить все эти "страшные многоядерные проблемы".
Ну и в пятых - Это не имеет смысла для процессоров с микрокодом. Потому-что архитектура таких процессоров может неявно обрабатывать какие-то последовательности команд тупо лучше. Как в х86 есть суперкороткая команда, в 2 байта, для for циклов, но она раз в 10 медленнее чем последовательность test+jne+inc+jmp, которая чуть ли не под 16 байт памяти съедает. (точно не помню, но суть в этом)
В сумме к самой архитектуре должны быть предъявлены серьёзные ограничения, что бы она могла собираться из такого "низкоуровневое кода". Продумывание всех этих деталей, лично для меня, слишком геморная задача и я бросил это.
ЗЫ - помимо всего этого, должна быть явная поддержка чистого ассемблера со стороны компилятора + препроцессор (чем мудрёнее тем лучше). Чтоб можно было ручками более чётко прописать что ты хочешь от кода. (И моё ИМХО - не дёргать регистры руками. Этим умеет заниматься компилятор и более эффективно. Если надо то как-то отдельно помечать переменную явно как "регистровую")VitGo Автор
00.00.0000 00:00Во вторых - этот язык должен быть одновременно "не типизрованным" и уметь в "типизацию". Для большинства архитектур в целом не важно что есть байты в памяти, это может быть как адрес-указатель так и float. При этом нужно учитывать что A + B невалидная операция, ибо что вообще есть +? Это SIMD расширение, 4float или 2double?? Это что-то от FPU? Это число, знаковое число?
Ну тут все таки я говорю об ассемблере, а у него типизация всегда ложилась на голову программиста...
Опять таки, я занимаюсь программированием микроконтроллеров, и там далеко не все задачи требуют full hd сенсорного экрана с wifi... зачастую на микроконтроллерах реализуются намного более простые задачи, и часто вообще без float типов и вычислений !
не считайте меня человеком который готов ассемблер приплетать к любой задаче !! но и поверьте очень очень очень далеко не везде нужен даже просто си... особенно когда нужно еще и уместить в недорогой чип всю функциональность....
В третьих - Есть типовые задачи которые максимально по разному работают на разных процессорах. Такая базовая вещь как "установить бит в памяти" может работать у всех абсолютно по разному, а это значит надо продумывать "std" библиотеки. Без них ты не сможешь гарантировать "нормальную" кроссплатформенность.
да, и об этом я говорю в видео.. конечно часть библиотеки будет транслироваться в блоки кода.. а не в одну инструкцию
В четвёртых - Это всё будет нормально работать вплоть до того как не появится второе ядро. Тогда придётся вводить кучу абстракций чтоб победить все эти "страшные многоядерные проблемы".
неее, второе ядро, 480 мгц - это все уже СИ !!! с ума сходить надо потихоньку :-) асм не для таких задач.. и в наше время есть более подходящие языки (тут я первый об этом скажу!)
ЗЫ - помимо всего этого, должна быть явная поддержка чистого ассемблера со стороны компилятора + препроцессор (чем мудрёнее тем лучше). Чтоб можно было ручками более чётко прописать что ты хочешь от кода. (И моё ИМХО - не дёргать регистры руками. Этим умеет заниматься компилятор и более эффективно. Если надо то как-то отдельно помечать переменную явно как "регистровую")
вы просто читаете мои мысли... !
а вы свои размышления никак не формализовывали ? (чтобы я мог почитать) мне очень не хватает любого опыта (положительного, отрицательного, среднего) - просто чтобы примерно понять с тонкостями той или иной реализации...
yatanai
00.00.0000 00:00+1и там далеко не все задачи требуют full hd сенсорного экрана с wifi...
И всё равно если в целях сделать "популярный" язык, он должен охватывать довольно много кейсов. Просто для "простого кода для мк" некоторые используют язык блок-схем, кто-то даже свои программы компиляторы под это пишут. Говорят очень быстро и легко можно накидать код для слабого мк. Другая проблема что если они захотят чего-то большего, этот подход работать не будет...
второе ядро, 480 мгц - это все уже СИ
Этот "невероятно низкоуровневый" язык можно так же превратить в ООП мутанта. Я даже больше скажу, в теории если разработать гибкую систему метапрограммирования, то даже такую вещь как "класс" можно задавать своими руками. Тут другой вопрос - хватит ли времени на всё это и не забросится проект с такими амбициями. Потому-что "придумывать фичи" сложнее чем таскать их из других языков.
(Некоторые ассемблеры позволяют на препроцессоре свой бейсик собрать, но до "фич" языков с метакодом ему далеко.)а вы свои размышления никак не формализовывали ?
Увы но нет, это просто мои потные фантазии как бы я хотел что бы что-то работало. Мол, я писал и асм код и на JIT языках сидел и сейчас сижу на С++, и просто имея этот весь опыт, у меня сложилось понимание что и как можно сделать. Но время которое надо затратить чтоб придумать весь этот язык, отталкивает чтоб начать этим заниматься.
Иначе... Если есть вопрос, я могу сообразить ответ, а тут как раз статья...
lamerok
00.00.0000 00:00+2Мое мнение, Вы пытаетесь изобрести ООП, и хотите сделать статический полиформиз для поддержки разных архитектур, дак уже всё придумано С++ и шаблоны. вот, например, конфигурация Pin хоть в что, на любой платформе.
Pin<Config>::Set();
хотите сделать конфигурацию пина в во вход на любой платформе:
using PinToInput = Pin<ConfigToInput>: PinToInput::Set();
останется только определить Configи для разных платформ и реализации Set(), ну или Set() тоже может быть одинаковыми, но тогда реализация должна быть в Configах
Как то баловался таким.
ska9306
00.00.0000 00:00+2Мне кажется надо несколько по иному решать эту проблему. Имея большой опыт разработки программ на Ассемблере (программировал на ассемблер IBM, DEC, Intel) могу сказать, что основная сложность при программировании на Ассемблере не в написании команд МОV, ADD и т.п., а в написании инструкций по управлению самой программы. Если программист занимается программированием МК, то вряд ли он программирует несколько разных МК одновременно. То есть он эти команды для конкретного МК запоминает в течении 2-3 недель. А вот отсутствие возможности иметь операторы if, while, do (простом цикл), until является основной трудностью. Мною в дипломной работе были реализованы эти инструками для ассемблера ЕС ЭВМ. Для чего использовал ся макрогенератор ассемблера. Программа получалась со сложной логикой управления гораздо меньше по размерам, намного читабельной и более надежной. Минусом было увеличение времени трансляции.
VitGo Автор
00.00.0000 00:00может быть присоединитесь к моей группе телеграмм ? ( https://t.me/ArmAsmEditor )
мне нужен опыт (и желательно разный) от людей пишущих на асме...
в своем первом редакторе попытался некоторые задумки реализовать (заодно можете оценить, правда он для arm cortex ассемблера)..
может быть смогли бы предложить еще какие то идеи по функциональности....
ska9306
00.00.0000 00:00+1Может быть вопрос не ко мне. но могу мысль свою уточнить. Реализация структурного программирования для ассемблер была реализована в 1978 г. сейчас я осваиваю ассемблер AVR. Хочу освоить и научить внука. Так вот, основная идея - не создавать новый язык, а оставаясь в рамках ассемблера получить значительный рост производительности, читабельности и надежности, как я уже отмечал. Операторы if, do, while, until генерируют текст на ассемблере, реализующий эти операторы. Условные выражения в них имели вложенную скобочную структуру. Например:
if ((оп1.AND.оп2).OR.(оп2.OR.оп3))
где оп -- операнд
Анализ логического выражения выполнялся средствами макрогенератора самого ассемблера - по сути это нулевой проход при трансляции программы. Реализован с помощью рекурсии. Для каждого МК конечно надо будет реализовывать свою реализацию, но если реализовать анализ лог.выражения, то генерация кода ассемблера для конкрентного МК не самая сложная задача. На основе этого подхода был создан пакет программ: разузлование и вхождение. Это классические задачи того времени. Разузлование: из скольких деталей и в каком количестве состоит тот или иной узел, вхождение: в какие узлы и в каком количестве входит деталь. Этот пакет позволил ускорить выполнение этих задач для крупного изделия (например авто) раз в 20. Не трое суток, что было невозможно для ЭВМ того времени из-за их ненадежности, а 2-3 часа
VitGo Автор
00.00.0000 00:00для ассемблера AVR как то тоже не нашел удобного редактора.. писал в WinAVR в свое время.. чуть удобнее блокнота конечно, но все равно не то...
сам реализовывал в первую очередь те функции которых не хватало лично мне...
получилось примерно так:
ska9306
00.00.0000 00:00+1Что-то у меня не открывается. Мне кажется надо упростить. Сделать препроцессор, который на основе текста на ассемблере конкретного МК с логикой на основе структурных операторов генерирует текст на ассемблере. Этот сгенерированный текст можно использовать в ATM Studio. Пример исходного текста:
add op1,op2
inc R1
if (R1.GT.op1)
mov r2, op3
mov r3, op2
while ((r1.EQ.r3).OR. (op3.LT.r2))
mov ...
add ...
inc ...
endwhile
endif
и т.д.
Замечание: смысла в приведенных операторах нет. Это как пример оформления.
EQ - =
GT - >
LT - <
А делать новый язык -- смысла нет. Мне кажется для ассемблировщиков этого достаточно. И логика программы видна и каждый оператор и написанный и сгенерированный на виду, доступен в отладке. Затем уже если есть желание можно реализовать и препроцессор, и транслятор в одной среде.
VitGo Автор
00.00.0000 00:00не открывается ссылка на ютуб ? гм...
ska9306
00.00.0000 00:00+2еще одно замечание и предложение.
Мне как программисту на ассемблере нетрудно написать MOV R1, 5 ,более того это естественнее, чем R1 = 5 . В отладчике я увижу MOV , зачем мне еще помнить, что он относится к R1 = 5. Но если вы создаете IDE для ассемблера, было бы лучше реализовать след.возможность: при наведении курсора на команду всплывает окно с информацией об этой конкретной команде - сколько байт она занимает, количество тактов, шестнадцатеричный формат. Когда я программировал на стене висел для i86 плакат, где для каждой команды была эта информации. Это помогало. И при программировании систем реального времени кол-то тактов очень значимо для оптимизации работы программы. при обработке текущего прерывания, происходит еще прерывание. Необходимо и обработать текущее и не потерять новое. Вот здесь и важен анализ скорости выполнения команд. Весьма возможно, что это уже реализовано.
Refridgerator
00.00.0000 00:00Я как-то делал плагин для вижуал студии, где можно было ещё и привязать комментарий к регистру, типа
mov ecx,0;=индекс
и ниже по тексту при наведении мышкой этот комментарий появлялся во всплывающей подсказке.Ну и фолдинг (сворачивание кусков кода в одну строчку) тоже полезная вещь для асма.
VitGo Автор
00.00.0000 00:00ну вот как раз представление инструкций в виде некоего псевдокода и позволит реализовать сворачивание асм кода...
запланировано что в редакторе всегда будет возможность увидеть сгенерированный асм код.. то есть это нечто недоступное, только в листингах, а наоборот - редактируемый код при необходимости
то есть от асма я отходить не хочу...
VitGo Автор
00.00.0000 00:00ну это пока вы программируете в рамках одной архитектуры.. и ваши инструкции не слишком сложны (посмотрите арм-ассемблер, а потом risc-v ассемблер - они как антиподы :-) у одного много различных сложных инструкций, а у второго - вроде все инструкции простые - но тоже свой синктаксис и мнемоники....)
смысл в том чтобы создать одинаковые мнемоники плюс минус для разных архитектур...
ну и насколько возможно сделать суррогатный микрокод для эмуляции тех инструкций которых нет на одной из архитектур..
про размер инструкции - в арме это зачастую так просто не работает (есть тумб2 формат - а это 16 бит вместо 32ух.. и есть еще выравнивание.)...
тоже самое и про число тактов - для этого есть DWT и там все бывает очень интересно в зависимости от того какое выравнивание у инструкции, и проще по DWT определять реальные цифры чем пытаться высчитать..
да и сейчас наверное все новые архитектуры умеют работать с вложенными приоритетными прерываниями ..
ska9306
00.00.0000 00:00"смысл в том чтобы создать одинаковые мнемоники плюс минус для разных архитектур... "
Есть "Искусство программирования"(автор Кнут по моему). в ней представлен некий ассемблер. По сути уровень абстракции, но в пределах ассемблера. Если для RISC процессоров один оператор этого ассемблера требует генерации нескольких команд, то для классических (Intel, Motorola и т.п.) - один в один. Но в случае скажем так предельных MIPS архитектур (DEC), в команде которого может "содержаться" несколько команд процессора например Intel -- cделать на основе псевдокода генерацию команд для такого процессора -- непростая задача в рамках ассемблера, может даже невыполнимая. Для транслятора с Си это решаемо. Но мне кажется время таких процессоров ушло.
Современными процессорами я начал заниматься недавно и пока не в курсе о DWT и о вложенных приоритетных прерываниях и как их программно отрабатывать. Посмотрю.
tmxx
00.00.0000 00:00+1...потом появится желание обеспечить повторное использование программ для различных ядер, чтобы по два раза не переписывать
...для этого понадобится привести архитектуры к одному общему виду
...называется это Форт
CrashLogger
00.00.0000 00:00Который дергает стек при любой операции, сводя к нулю преимущества современных процессоров с кучей регистров.
VitGo Автор
00.00.0000 00:00да, плюс к этому программу на асме когда идет активная работа по сохранению всего подряд на стек очень тяжко отлаживать именно как асм программу...
tmxx
00.00.0000 00:00переносимый язык позволяет кроссплатформенную отладку
я не фанат Форта, просто ваши комментарии противоречат целям заявленным в статье
magiavr
00.00.0000 00:00Форт не такой уж и плохой язык, но он эффективен на стековых машинах, которые медленее регистровых. Это заметно даже на виртуальных машинах. Так каноническая виртуальная машина Java - 8-разрядная стековая машина. Однако виртуальная машина Dalvik для Java, используемая на смартфонах андроид, представляет собой 16-разрядную машину с виртуальным регистром - выбор сделан из соображений эффективности. Но в целом идея автора напоминает, что-то типо форта или C--.
tmxx
00.00.0000 00:00Вы абсолютно правы.
Продолжу: в статье предложено свести оптимизированные к архитектуре синтаксисы ассемблеров к некоему обобщенному.
Как вы считаете, этот подход позволит использовать "преимущества современных процессоров с кучей регистров"?
VitGo Автор
00.00.0000 00:00а что за преимущества в куче регистров вы выделяете ? не дергать постоянно память если данные можно хранить в регистрах ?
так вроде нет препятствий
ef_end_y
00.00.0000 00:00+1Я осилил (надеюсь) только манипуляции с виртуальными регистрами. У меня 2 вопроса:
1) зачем введено такое понятие, почему нельзя иметь сквозную нумерацию регистров, а компилятор сам распределит где виртуальные, а где нет?
2) вы уверены, что итоговый код, когда значения виртуальных регистров будут летать туда-сюда в память (у нас ситуация что физических регистров меньше виртуальных, значит мы должны их хранить в кеше) будет оптимальней скомпилированного сишного кода, где компилятор оптимизирован под реальное количество регистров. Я когда-то смотрел скомпилированный код под MSP процессор и реально офигел, что он был довольно нетривиальным, т.е. не такой линейный как я ожидалVitGo Автор
00.00.0000 00:001) зачем введено такое понятие, почему нельзя иметь сквозную нумерацию регистров, а компилятор сам распределит где виртуальные, а где нет?
ну просто подразумевается что виртуальный регистр это некоторая именованная ячейка в памяти.. значение которой м.б. использовано в выражениях...
для ассемблера гонять регистры на стек\со стека - реально не всегда удобно при отладке :-( да и с точки зрения быстродействия выгоды не столь очевидны (а иногда и просто нет)
2) вы уверены, что итоговый код, когда значения виртуальных регистров будут летать туда-сюда в память (у нас ситуация что физических регистров меньше виртуальных, значит мы должны их хранить в кеше) будет оптимальней скомпилированного сишного кода, где компилятор оптимизирован под реальное количество регистров. Я когда-то смотрел скомпилированный код под MSP процессор и реально офигел, что он был довольно нетривиальным, т.е. не такой линейный как я ожидал
ну уверен может быть только Господь, а над нашими планами он потом посмеется.. но попробовать считаю возможным....
fpinger
00.00.0000 00:00А решение будет сделано на chat gpt. Причем код никто не поймет, но он будет работать для нужного процессора )))
Refridgerator
00.00.0000 00:00+2Желание унифицировать вариации mov понятно и это легко. А что действительно сложно, так это:
1) на одних платформах есть флаги, на других нет. Как унифицировать не только циклы, но и длинную арифметику?
2) на одних платформах есть векторные инструкции, на других нет. Как унифицировать MMX, SSE, AVX и прочие? Даже ведущие программисты из Microsoft и Intel не справились с этим, размерность векторных инструкций в интринсиках задаётся всё ещё явным образом.
3) на одних платформах есть произвольный доступ к регистрам, на других — нет (FPU как пример). Даже ведущие компиляторы от ведущих уже названных компаний не умеют по максимуму использовать весь стек FPU, ограничиваясь стандартными шаблонами и верхними двумя регистрами.
4) на одних платформах двух-операндный синтаксис, на других трёх-, на третьих только и исключительно четырёх-. Вопрос тот же самый — как их унифицировать?ef_end_y
00.00.0000 00:00+1унифицировать можно, несуществующие конструкции будут разворачиваться в последовательности команд, актуальных для данного процессора. Эффективность этого будет низкая, хуже чем у сишного компилятора, который оптимизирует не команду, а высокоуровневый фрагмент
VitGo Автор
00.00.0000 00:00ну все немного не так как вы пишите.. поверьте, у себя в группе мы дизассемблировали сишные программы... оверкода там дофига
но на каких то алгоритмических фрагментах - си компилирует так как это сделал бы человек на асме, это действительно так...
например, неоднократно видели когда си применяет при работе с битовыми полями and\or хотя есть например BFI... возможно это из за того что на cortex-m0 просто нет bfi в системе команд... но в cortex-m3 \ cortex-m4 все равно используется and\or...
COKPOWEHEU
00.00.0000 00:00четырехоперандный синтаксис? Как такая платформа называется? И, если не затруднит, пример кода где это используется.
Refridgerator
00.00.0000 00:00FMA4 например. Примеры кода наверняка найдутся в официальной документации.
COKPOWEHEU
00.00.0000 00:00ну, это расширение, а не платформа. Отдельные четырехоперандные инструкции есть и в каком-нибудь RISC-V (fmadd rd, rs1, rs2, rs3)
Refridgerator
00.00.0000 00:00Ну, я не могу знать про все платформы в настоящем и тем более в будущем. Слышал, что у Эльбруса именно такой подход. Сам сталкивался с DSP-процессором, у которого все команды 3-операндные. В наше время вообще каждый может сделать свой собственный процессор на базе FPGA.
COKPOWEHEU
00.00.0000 00:00Так-то трехоперандных архитектур полно, те же ARM или RISC-V
Двухоперандные это например AVR.
1.5-операндные это например PIC (пол-операнда это один бит, с равным успехом можно добавить еще десяток мнемоник и счесть однооперандным).
Вот и интересно существуют ли в природе честные однооперандные, безоперандные и те, в которых операндов больше трех.
datacompboy
00.00.0000 00:00Вот и интересно существуют ли в природе честные однооперандные
Форт-машины, пожалуй, так как там второй операнд стек неявно.
Dovgaluk
00.00.0000 00:00Я тоже стал придумывать микроязык для своего релейного компьютера.
Основной фичей должна быть удобная работа с флагом переноса. Например, чтобы можно было сдвигать переменные по цепочке. Или складывать, используя дальше получившийся бит переноса для проверки условия.
Правда синтаксис ещё не доточил, потому что компилятор не готов пока что.
VitGo Автор
00.00.0000 00:00приходите в гости, первые наметки языка уже начали вырисовываться.. может быть вам будет интересно
emusic
00.00.0000 00:00я не желаю создавать очередной си‑подобный язык высокого уровня!
А зря. Я в начале 90-х тоже предпочитал ассемблер языкам высокого уровня, поскольку между ними был существенный разрыв - стоило перейти хотя бы на C, чтобы потерять контроль над рядом аспектов размещения и выполнения кода/данных, которые могли быть важны для задачи. То, что большинство тогда писало на C, C++ и Pascal, я писал на ассемблере, и был вполне доволен. :)
А потом оказалось, что есть реализации и C, и даже Pascal, очень сильно приближенные к машинному уровню, где можно произвольно манипулировать размещением кода/данных в памяти, непосредственно использовать регистры в виде псевдопеременных, где ряд встроенных функций напрямую раскрывается в соответствующие команды процессора и т.п. Мне не приходилось писать для контроллеров ARM, но после перехода на VC++ в 90-х я совершенно потерял интерес к ассемблеру, поскольку практически все, что я привык контролировать на уровне команд и ячеек, можно было делать и в программе на C/C++, произвольно меняя уровень абстракции в любом месте. И это при том, что VC++ сильно уступал в этом тому же BC++.
Так что опускать уровень ЯВУ - занятие гораздо более перспективное, нежели поднимать уровень ассемблера. Используя ЯВУ с богатыми возможностями доступа к целевой архитектуре, Вы в любом месте можете детализировать программу сколь угодно близко к железу, но, если этого не требуется, Вы можете использовать все преимущества абстракции, и переносимость обеспечивается автоматически. Используя же высокоуровневый ассемблер, Вы всегда остаетесь в рамках архитектуры (или семейства архитектур), ибо невозможно сколько-нибудь органично соединить ассемблерную детальность с достаточной степенью абстракции.
progchip666
00.00.0000 00:00Безумству смелых, поём мы песню. А я всё больше влезаю в HAL, хотя всё моё естество этому противится. Но так проще заработать, чем писать проги в машинных кодах, как в счастливые студенческие времена!
Sergey_zx
00.00.0000 00:00Когда я понял, что оптимизирующий компилятор С генерирует ассемблерный код который я не могу улучшить я перестал писать на asm. Конечно, можно сделать код более понятным для, человека. А если потрачу несколько часов то сэкономлю десяток байт. Но нахрена оно нужно то?
Так что спускаюсь на уровень команд процессора лишь в очень экзотических случаях.
Ну и, как я уже писал, почему то каждый начинающий программист первым пытается создать свой "удобный и понятный" язык программирования. Причем, исключительно в тех областях где и так имеется множество вполне успешных языков.
aamonster
00.00.0000 00:00Да и пусть создаёт, кому мешает? Зато "на сдачу" получаем человека, который гораздо глубже разобрался в архитектуре.
VitGo Автор
00.00.0000 00:00ну если вы улучшить не можете - возможно вы просто не знаете ассемблера... вот и все... и компилятор си тут не при чем :-)
если в коде выше вы не можете ничего улучшить - то без комментариев...
потому что кто хоть немного знает - он бы из 4 инструкций оставил 2, если хорошо знает ОДНУ инструкцию !!!!
и это на каких то 4х строчках кода.... 4 байта как минимум экономии и минимум 2 такта исполнения
p.s. это из под куба
Sergey_zx
00.00.0000 00:00Я видел и более убогие компиляторы. Такого же результата можно добиться отключением оптимизации. Но какое отношение они имеют к программировании на ассемблере?
В тексте выше есть слово "оптимизирующие". Вам оно о чем то говорит?
VitGo Автор
00.00.0000 00:00я отвечал на ваш вопрос про то какой код генерит компилятор си...
и поверьте - оптимизации включены
VitGo Автор
00.00.0000 00:00и вопрос про ваше знание ассемблера остался - так на что заменить этот говнокод ?
datacompboy
Так и появился си, вроде, не? :)