Некоторое время я был занят написанием простенького редактора для языка ассемблер под 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)


  1. datacompboy
    00.00.0000 00:00
    +26

    Так и появился си, вроде, не? :)


  1. Jury_78
    00.00.0000 00:00
    +5

    я не желаю создавать очередной си-подобный язык высокого уровня !

    R0=5

    Но согласитесь - очень похоже. :) Хотя бы на препроцессор Си.


  1. netricks
    00.00.0000 00:00
    +1

    Действительно, ассемблерные инструкции часто неудобочитаемы и в целом, сделать человекочитаемый ассемблер не кажется плохой идеей. Я вижу проблемы с портированием специфик различных архитектур, скажем, что делать если инструкция есть на одной системе комманд, но отсутствует на другой. И, кроме того, не очень понятно, как лаконично изложить некоторые армовские инструкции, типа тех, что в состав команды включают условность и прочие подобные.


    1. olartamonov
      00.00.0000 00:00
      +6

      И в итоге это вырастет в некую упрощённую версию C.


      1. jobless
        00.00.0000 00:00
        +2

        Для x86 есть же C-- (Си минус минус) https://ru.wikipedia.org/wiki/C--


        1. olartamonov
          00.00.0000 00:00
          +5

          Кстати, да.

          А также, конечно,


          1. Arcanum7
            00.00.0000 00:00
            +1

            Пришёл чтобы увидеть этот комикс. Он на месте. Баланс соблюдён.


          1. perfect_genius
            00.00.0000 00:00

            Но ведь с USB-C почти получилось.


            1. datacompboy
              00.00.0000 00:00

              К тому что теперь есть 15 взаимоисключающих проводов которые выглядят одинаково а работают непонятно как? :)


              1. perfect_genius
                00.00.0000 00:00

                Поэтому "почти".
                Работают кое-как, но работают. А другие разъёмы не работали бы вообще :D


        1. aamonster
          00.00.0000 00:00
          +2

          А для 8080 – PL/M. На минуточку, на нём была написана ведущая операционка того времени.


        1. magiavr
          00.00.0000 00:00

          Тоже хотел про него напомнить.


    1. acc0unt
      00.00.0000 00:00
      +3

      Задачу "сделать человекочитаемый ассемблер" решали ещё в Analog Devices в нулевых. Ассемблер Blackfin как пример - восхитительное безумие.


      1. Ne345
        00.00.0000 00:00
        +7

        Я писал на ассемблере для ADSP-21xx. Это не безумие. Синтаксис этого ассемблера похож по идеологии, предложенной в этой статье. Синтаксис ассемблера был такой качественный, что написание программ мало отличалось от написания программ на C. Причина, по которой целесообразно было писать тогда на ассемблере - это очень малые ресурсы по памяти и требоваение учета архитектуры для эффективных проектов.
        Синтаксис ассеблера ARM имеет исторические корни и изменение его сейчас не очень целесообразно по разным причинам.
        Автору статьи - респект за способность мыслить нестандартно.


        1. acc0unt
          00.00.0000 00:00
          +3

          Ну и я про то же.

          Смотришь ты на этот синтаксис. Первая мысль - "что это за дичь вообще". Вторая - "а это прикольный синтаксис". И третья - "почему вообще все ассемблеры не сделаны вот так?"

          AD осознали необходимость в "ассемблере с человеческим лицом" для нужд DSP и выкатили своё решение. Жаль даже что эти идеи не получили распространения.


          1. byman
            00.00.0000 00:00
            +1

            очень даже получили. После знакомства с Си-подобным ассемблером AD, я для всех своих микропроцессоров использовал только подобный синтаксис. Запоминать тьму мнемоник очень сложно. Хотя ассемблер обычно намного богаче и со сложными командами приходится все равно приходится что-то придумывать не похожее на Си.


        1. aamonster
          00.00.0000 00:00

          Синтаксис не очень многое меняет, честно говоря... Если команды из одной вариации ассемблера в другую взаимно-однозначно переводятся – то это только вопрос относительно недолгого привыкания.


      1. emusic
        00.00.0000 00:00

        У Borland в свое время получился очень удачный ассемблер для x86 - синтаксис Ideal в TASM, в противовес традиционному синтаксису MASM. Я в 90-х даже всерьез взялся за написание книги по нему, а потом перешел на C++, и задача потеряла актуальность. В этом синтаксисе все очень логично и изящно, поддержка параметров и локальных переменных в процедурах сделана очень удобно. Я на нем плотно писал несколько лет, после него читать программы на MASM - сущая пытка.


  1. eugenk
    00.00.0000 00:00
    +3

    Асм для dsp-процессоров Analog Devices выглядит примерно так. Хотя облегчает ли это программирование по сравнению с другими процессорами - черт его знает... Когда пришлось под это дело писать, его всё равно надо было плотно осваивать... Может Вы скорее о стандартизации мнемоник различных ассемблеров ???

    Для меня вобщем-то примерно подобная задача сейчас тоже актуальна. Есть очень неплохой (на мой взгляд как автора разумеется) самопальный процессор, встраиваемый в FPGA (сейчас потихоньку готовлю серию публикаций о нём). Проблема - на чём его программировать. Усугубляется это в добавок тем, что он управляется микрокодом. Для того чтобы изменить под свою задачу систему команд (в разумных пределах конечно), не надо лезть в дебри верилога. Достаточно описать её на некоем простом языке(микроассемблере), получить микрокод и пересобрать проект(можно даже вообще без пересборки загрузить через аппаратный отладчик). Работы на час-полтора. А вот как менять средства разработки - черт его знает... Пока это у меня решается подробнейшим описанием на русском языке внутренностей ассемблера и симулятора. Чтобы пользователь без труда смог это переписать под свою систему команд. Но это уже ДНИ... Хотелось бы каких-то более фундаментальных решений.

    P.S. На всякий случай утащил в закладки. Надеюсь в отличии от сотен и тысяч других, идея не мертворожденная.

    P.P.S. Кстати можно подробнее о Вашем редакторе ??? Я сейчас тоже в качестве небольшого хобби и переключения задач пишу нечто, вдохновлённое вот этим https://github.com/rxi/lite , хотя и сильно по-своему.


  1. jobless
    00.00.0000 00:00
    +1

    История зациклилась как ей и предписано.

    "С машиной поставлялся автокод АРМУ (Автокод Ряда Машин Урал), который был единым автокодом ряда ЭВМ типа “Урал”. Он был составлен с учетом особенностей этих машин и обеспечивал полную совместимость от меньшей машины к большей. Каждая ЭВМ “Урал” имела собственный транслятор с языка АРМУ на свой машинный язык. Таким образом, совместимость ЭВМ типа “Урал” была ограниченной и существовала только на уровне автокода АРМУ. "

    https://computer-museum.ru/histussr/ural11.htm

    p.s. первая программа, которой кто то кроме меня пользовался была написана 40 лет назад как раз для Урал-11


    1. jobless
      00.00.0000 00:00

      Забыл добавить: Год окончания разработки: 1965.


    1. VitGo Автор
      00.00.0000 00:00

      эхх.. и где бы почитать продолжение ? :-)


      1. jobless
        00.00.0000 00:00
        +3

        Про Уралы Серия https://computer-museum.ru/histussr/ural.htm

        А вообще сайт кто то, к счастью, активно пополняет..

        У меня мечта для пенсии, сделать эмулятор Урала с ПУЛЬТОМ

        Кстати, я не только застал живым Урал-11 в 1983, но и в 1978 сдал первый зачёт по программированию на АЛГАМС

        https://standartgost.ru/g/ГОСТ_21551-76


        1. progchip666
          00.00.0000 00:00

          Господи, как же давно это было! я в 1883 только в МИЭТ поступил!


        1. progchip666
          00.00.0000 00:00

          Я так понял ваш музей чисто виртуальный?


  1. Tim0Ur
    00.00.0000 00:00

    Советую обратить внимание на fasmg: https://flatassembler.net/docs.php?article=fasmg


    1. VitGo Автор
      00.00.0000 00:00

      идея похожа в общих чертах...


  1. aamonster
    00.00.0000 00:00
    +4

    Почитайте про PL/M и C-- – вроде оба достаточно близки к задаче, которую вы себе поставили, возможно, почерпнёте идеи.

    Ну и, естественно, готовьтесь к тому, что проект вы создаёте в основном для себя и большая популярность ему не светит...


  1. VaalKIA
    00.00.0000 00:00

    Как вам уже написали, делая кроссплатформенный ассемблер, вы приходите к языку высокого уровня.

    Выглядит это примерно так: на одном процессоре есть какие-то инструкции, а на другом нет. Значит берём некое очень ограниченное подмножество инструкций, которые есть на всех рассматриваемых процессорах, а потом для каждого конкретного сворачиваем последовательность микрокодов в одну инструкцию с помощью хинтов (фактически - шаблонов), а там, где не свернулось, работает эта самая микропрограмма. пусть и не так эффективно (и даже может быть свёрнута в несколько операндов). Микрокоды, это некая стековая машина, PI код, или LLVM IR, поэтому, фактически, мы можем придти к тому. что сами микрокоды вообще не являются усечённым подмножеством любой из архитектур, а являются полностью виртуальными. На втором шаге, выделив типовые последовательности, микрокодов, для конкретных программ, даём им имена и получаем операторы ЯВУ и конкретный кроссплатформенный язык.


  1. CrashLogger
    00.00.0000 00:00
    +1

    Похоже большинство коментаторов не понимают, чем ассемблер (даже с макросами) отличается от языка высокого уровня. Когда мы пишем на ассемблере, мы сами определяем, какие инструкции и в каком порядке будут исполняться процессором. Когда мы пишем на ЯВУ - мы забываем про инструкции процессора и вообще не думаем о них. То, что делает автор статьи - это ассемблер, несмотря на то, что для разных процессоров одна и та же мнемоника транслируется в разные команды. Мы непосредственно оперируем регистрами и адресами в памяти, а не перекладываем это на компилятор. Мы можем сосчитать, сколько тактов процессора и сколько байт в памяти займет наша программа. Мне не приходилось писать на ассемблере одну программу под разные архитектуры, но, возможно, кому-то это будет полезно.


    1. iamkisly
      00.00.0000 00:00

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


      1. VitGo Автор
        00.00.0000 00:00

        ну это не коммерческий проект.. да и до вендоров сейчас даже дальше чем до китая :-)

        то что я пытаюсь сделать будет являться неким препроцессором результат которого будет скармливаться gnu as


    1. RTFM13
      00.00.0000 00:00

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

      Ничего, что у разных архитектур разные системы команд, которые не переводятся одна в другую 1:1 (а не которые вообще не похожи друг на друга) и реализация одних задач будет отличаться командами, количеством тактов и т.п.?


      1. VitGo Автор
        00.00.0000 00:00

        вот поэтому я и говорю о некотором подмножестве инструкций максимально приближенных к ассемблеру..

        на счет подсчета количества тактов (гм.. со времен AVR этим не занимался) - но задумка редакторе что генерируемый асм код доступен постоянно - так что посчитать можно еще на этапе редактирования программы, а не искать тот или иной фрагмент в листинге компилятора...


    1. lolikandr
      00.00.0000 00:00

      Порядок инструкций всё же зависит от процессора. Вот вам ассемблер для семейства TMS320C672x - предположите, что произойдёт раньше:

      1. прыжок по адресу B3 (строка 12) ?

      2. запись 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;
      }


    1. lamerok
      00.00.0000 00:00

      Вы и на C++ можете ими(адресами, регистр это тоже ячейка памяти) оперировать.


  1. DungeonLords
    00.00.0000 00:00
    +3

    Я думаю в первую очередь мир нуждается в свободном симуляторе цифро-аналоговых цепей, таком как Proteus или может Simics. Потому что очень хочется сначала прототипировать, а потом паять.


  1. 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 байт памяти съедает. (точно не помню, но суть в этом)

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

    ЗЫ - помимо всего этого, должна быть явная поддержка чистого ассемблера со стороны компилятора + препроцессор (чем мудрёнее тем лучше). Чтоб можно было ручками более чётко прописать что ты хочешь от кода. (И моё ИМХО - не дёргать регистры руками. Этим умеет заниматься компилятор и более эффективно. Если надо то как-то отдельно помечать переменную явно как "регистровую")


    1. VitGo Автор
      00.00.0000 00:00

      Во вторых - этот язык должен быть одновременно "не типизрованным" и уметь в "типизацию". Для большинства архитектур в целом не важно что есть байты в памяти, это может быть как адрес-указатель так и float. При этом нужно учитывать что A + B невалидная операция, ибо что вообще есть +? Это SIMD расширение, 4float или 2double?? Это что-то от FPU? Это число, знаковое число?

      Ну тут все таки я говорю об ассемблере, а у него типизация всегда ложилась на голову программиста...

      Опять таки, я занимаюсь программированием микроконтроллеров, и там далеко не все задачи требуют full hd сенсорного экрана с wifi... зачастую на микроконтроллерах реализуются намного более простые задачи, и часто вообще без float типов и вычислений !

      не считайте меня человеком который готов ассемблер приплетать к любой задаче !! но и поверьте очень очень очень далеко не везде нужен даже просто си... особенно когда нужно еще и уместить в недорогой чип всю функциональность....

      В третьих - Есть типовые задачи которые максимально по разному работают на разных процессорах. Такая базовая вещь как "установить бит в памяти" может работать у всех абсолютно по разному, а это значит надо продумывать "std" библиотеки. Без них ты не сможешь гарантировать "нормальную" кроссплатформенность.

      да, и об этом я говорю в видео.. конечно часть библиотеки будет транслироваться в блоки кода.. а не в одну инструкцию

      В четвёртых - Это всё будет нормально работать вплоть до того как не появится второе ядро. Тогда придётся вводить кучу абстракций чтоб победить все эти "страшные многоядерные проблемы".

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

      ЗЫ - помимо всего этого, должна быть явная поддержка чистого ассемблера со стороны компилятора + препроцессор (чем мудрёнее тем лучше). Чтоб можно было ручками более чётко прописать что ты хочешь от кода. (И моё ИМХО - не дёргать регистры руками. Этим умеет заниматься компилятор и более эффективно. Если надо то как-то отдельно помечать переменную явно как "регистровую")

      вы просто читаете мои мысли... !

      а вы свои размышления никак не формализовывали ? (чтобы я мог почитать) мне очень не хватает любого опыта (положительного, отрицательного, среднего) - просто чтобы примерно понять с тонкостями той или иной реализации...


      1. yatanai
        00.00.0000 00:00
        +1

         и там далеко не все задачи требуют full hd сенсорного экрана с wifi...

        И всё равно если в целях сделать "популярный" язык, он должен охватывать довольно много кейсов. Просто для "простого кода для мк" некоторые используют язык блок-схем, кто-то даже свои программы компиляторы под это пишут. Говорят очень быстро и легко можно накидать код для слабого мк. Другая проблема что если они захотят чего-то большего, этот подход работать не будет...

        второе ядро, 480 мгц - это все уже СИ 

        Этот "невероятно низкоуровневый" язык можно так же превратить в ООП мутанта. Я даже больше скажу, в теории если разработать гибкую систему метапрограммирования, то даже такую вещь как "класс" можно задавать своими руками. Тут другой вопрос - хватит ли времени на всё это и не забросится проект с такими амбициями. Потому-что "придумывать фичи" сложнее чем таскать их из других языков.
        (Некоторые ассемблеры позволяют на препроцессоре свой бейсик собрать, но до "фич" языков с метакодом ему далеко.)

        а вы свои размышления никак не формализовывали ?

        Увы но нет, это просто мои потные фантазии как бы я хотел что бы что-то работало. Мол, я писал и асм код и на JIT языках сидел и сейчас сижу на С++, и просто имея этот весь опыт, у меня сложилось понимание что и как можно сделать. Но время которое надо затратить чтоб придумать весь этот язык, отталкивает чтоб начать этим заниматься.

        Иначе... Если есть вопрос, я могу сообразить ответ, а тут как раз статья...


  1. lamerok
    00.00.0000 00:00
    +2

    Мое мнение, Вы пытаетесь изобрести ООП, и хотите сделать статический полиформиз для поддержки разных архитектур, дак уже всё придумано С++ и шаблоны. вот, например, конфигурация Pin хоть в что, на любой платформе.

    Pin<Config>::Set();

    хотите сделать конфигурацию пина в во вход на любой платформе:

    using PinToInput = Pin<ConfigToInput>:
    PinToInput::Set();

    останется только определить Configи для разных платформ и реализации Set(), ну или Set() тоже может быть одинаковыми, но тогда реализация должна быть в Configах

    Как то баловался таким.

    https://habr.com/ru/post/473612/

    https://disk.yandex.ru/i/ajCQtg1GEPPdRQ


    1. ChessMax
      00.00.0000 00:00

      Полиморфизм?


      1. lamerok
        00.00.0000 00:00

        Ага, ????


        1. ChessMax
          00.00.0000 00:00

          Самое смешное, что у меня тоже в первую очередь в голову приходит неправильный вариант. И потом я себя исправляю. Почему так происходит непонятно)


  1. ska9306
    00.00.0000 00:00
    +2

    Мне кажется надо несколько по иному решать эту проблему. Имея большой опыт разработки программ на Ассемблере (программировал на ассемблер IBM, DEC, Intel) могу сказать, что основная сложность при программировании на Ассемблере не в написании команд МОV, ADD и т.п., а в написании инструкций по управлению самой программы. Если программист занимается программированием МК, то вряд ли он программирует несколько разных МК одновременно. То есть он эти команды для конкретного МК запоминает в течении 2-3 недель. А вот отсутствие возможности иметь операторы if, while, do (простом цикл), until является основной трудностью. Мною в дипломной работе были реализованы эти инструками для ассемблера ЕС ЭВМ. Для чего использовал ся макрогенератор ассемблера. Программа получалась со сложной логикой управления гораздо меньше по размерам, намного читабельной и более надежной. Минусом было увеличение времени трансляции.


    1. VitGo Автор
      00.00.0000 00:00

      может быть присоединитесь к моей группе телеграмм ? ( https://t.me/ArmAsmEditor )

      мне нужен опыт (и желательно разный) от людей пишущих на асме...

      в своем первом редакторе попытался некоторые задумки реализовать (заодно можете оценить, правда он для arm cortex ассемблера)..

      может быть смогли бы предложить еще какие то идеи по функциональности....


      1. ska9306
        00.00.0000 00:00
        +1

        Может быть вопрос не ко мне. но могу мысль свою уточнить. Реализация структурного программирования для ассемблер была реализована в 1978 г. сейчас я осваиваю ассемблер AVR. Хочу освоить и научить внука. Так вот, основная идея - не создавать новый язык, а оставаясь в рамках ассемблера получить значительный рост производительности, читабельности и надежности, как я уже отмечал. Операторы if, do, while, until генерируют текст на ассемблере, реализующий эти операторы. Условные выражения в них имели вложенную скобочную структуру. Например:

        if ((оп1.AND.оп2).OR.(оп2.OR.оп3))

        где оп -- операнд

        Анализ логического выражения выполнялся средствами макрогенератора самого ассемблера - по сути это нулевой проход при трансляции программы. Реализован с помощью рекурсии. Для каждого МК конечно надо будет реализовывать свою реализацию, но если реализовать анализ лог.выражения, то генерация кода ассемблера для конкрентного МК не самая сложная задача. На основе этого подхода был создан пакет программ: разузлование и вхождение. Это классические задачи того времени. Разузлование: из скольких деталей и в каком количестве состоит тот или иной узел, вхождение: в какие узлы и в каком количестве входит деталь. Этот пакет позволил ускорить выполнение этих задач для крупного изделия (например авто) раз в 20. Не трое суток, что было невозможно для ЭВМ того времени из-за их ненадежности, а 2-3 часа


        1. VitGo Автор
          00.00.0000 00:00

          для ассемблера AVR как то тоже не нашел удобного редактора.. писал в WinAVR в свое время.. чуть удобнее блокнота конечно, но все равно не то...

          сам реализовывал в первую очередь те функции которых не хватало лично мне...

          получилось примерно так:

          https://youtu.be/UTGufdw_D4Y


          1. 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 - <

            А делать новый язык -- смысла нет. Мне кажется для ассемблировщиков этого достаточно. И логика программы видна и каждый оператор и написанный и сгенерированный на виду, доступен в отладке. Затем уже если есть желание можно реализовать и препроцессор, и транслятор в одной среде.


            1. VitGo Автор
              00.00.0000 00:00

              не открывается ссылка на ютуб ? гм...


              1. ska9306
                00.00.0000 00:00

                или я что-то не так делаюЖ


                1. VitGo Автор
                  00.00.0000 00:00

                  И? открывайте плейлист ! GNU ARM ASM EDITOR

                  можно просто в ютубе в поиске набрать ArmAsmEdit и там найти любое видео, и там в подсказках будет ссылка на весь плейлист и на следующее видео


              1. ska9306
                00.00.0000 00:00
                +2

                еще одно замечание и предложение.

                Мне как программисту на ассемблере нетрудно написать MOV R1, 5 ,более того это естественнее, чем R1 = 5 . В отладчике я увижу MOV , зачем мне еще помнить, что он относится к R1 = 5. Но если вы создаете IDE для ассемблера, было бы лучше реализовать след.возможность: при наведении курсора на команду всплывает окно с информацией об этой конкретной команде - сколько байт она занимает, количество тактов, шестнадцатеричный формат. Когда я программировал на стене висел для i86 плакат, где для каждой команды была эта информации. Это помогало. И при программировании систем реального времени кол-то тактов очень значимо для оптимизации работы программы. при обработке текущего прерывания, происходит еще прерывание. Необходимо и обработать текущее и не потерять новое. Вот здесь и важен анализ скорости выполнения команд. Весьма возможно, что это уже реализовано.


                1. Refridgerator
                  00.00.0000 00:00

                  Я как-то делал плагин для вижуал студии, где можно было ещё и привязать комментарий к регистру, типа
                  mov ecx,0;=индекс
                  и ниже по тексту при наведении мышкой этот комментарий появлялся во всплывающей подсказке.


                  Ну и фолдинг (сворачивание кусков кода в одну строчку) тоже полезная вещь для асма.


                  1. VitGo Автор
                    00.00.0000 00:00

                    ну вот как раз представление инструкций в виде некоего псевдокода и позволит реализовать сворачивание асм кода...

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

                    то есть от асма я отходить не хочу...


                    1. Refridgerator
                      00.00.0000 00:00

                      Ну так у меня это уже сделано… А у вас?


                      1. VitGo Автор
                        00.00.0000 00:00

                        у меня пока идет проработка языка..


                1. VitGo Автор
                  00.00.0000 00:00

                  ну это пока вы программируете в рамках одной архитектуры.. и ваши инструкции не слишком сложны (посмотрите арм-ассемблер, а потом risc-v ассемблер - они как антиподы :-) у одного много различных сложных инструкций, а у второго - вроде все инструкции простые - но тоже свой синктаксис и мнемоники....)

                  смысл в том чтобы создать одинаковые мнемоники плюс минус для разных архитектур...

                  ну и насколько возможно сделать суррогатный микрокод для эмуляции тех инструкций которых нет на одной из архитектур..

                  про размер инструкции - в арме это зачастую так просто не работает (есть тумб2 формат - а это 16 бит вместо 32ух.. и есть еще выравнивание.)...

                  тоже самое и про число тактов - для этого есть DWT и там все бывает очень интересно в зависимости от того какое выравнивание у инструкции, и проще по DWT определять реальные цифры чем пытаться высчитать..

                  да и сейчас наверное все новые архитектуры умеют работать с вложенными приоритетными прерываниями ..


                  1. ska9306
                    00.00.0000 00:00

                    "смысл в том чтобы создать одинаковые мнемоники плюс минус для разных архитектур... "

                    Есть "Искусство программирования"(автор Кнут по моему). в ней представлен некий ассемблер. По сути уровень абстракции, но в пределах ассемблера. Если для RISC процессоров один оператор этого ассемблера требует генерации нескольких команд, то для классических (Intel, Motorola и т.п.) - один в один. Но в случае скажем так предельных MIPS архитектур (DEC), в команде которого может "содержаться" несколько команд процессора например Intel -- cделать на основе псевдокода генерацию команд для такого процессора -- непростая задача в рамках ассемблера, может даже невыполнимая. Для транслятора с Си это решаемо. Но мне кажется время таких процессоров ушло.

                    Современными процессорами я начал заниматься недавно и пока не в курсе о DWT и о вложенных приоритетных прерываниях и как их программно отрабатывать. Посмотрю.


  1. tmxx
    00.00.0000 00:00
    +1

    ...потом появится желание обеспечить повторное использование программ для различных ядер, чтобы по два раза не переписывать

    ...для этого понадобится привести архитектуры к одному общему виду

    ...называется это Форт


    1. CrashLogger
      00.00.0000 00:00

      Который дергает стек при любой операции, сводя к нулю преимущества современных процессоров с кучей регистров.


      1. VitGo Автор
        00.00.0000 00:00

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


        1. tmxx
          00.00.0000 00:00

          переносимый язык позволяет кроссплатформенную отладку

          я не фанат Форта, просто ваши комментарии противоречат целям заявленным в статье


          1. magiavr
            00.00.0000 00:00

            Форт не такой уж и плохой язык, но он эффективен на стековых машинах, которые медленее регистровых. Это заметно даже на виртуальных машинах. Так каноническая виртуальная машина Java - 8-разрядная стековая машина. Однако виртуальная машина Dalvik для Java, используемая на смартфонах андроид, представляет собой 16-разрядную машину с виртуальным регистром - выбор сделан из соображений эффективности. Но в целом идея автора напоминает, что-то типо форта или C--.


            1. VitGo Автор
              00.00.0000 00:00

              а про С-- где посмотреть ? гугл только про си выдает результаты и си++.. :-(



              1. magiavr
                00.00.0000 00:00

                https://habr.com/ru/company/kolibrios/blog/303582/


      1. tmxx
        00.00.0000 00:00

        Вы абсолютно правы.

        Продолжу: в статье предложено свести оптимизированные к архитектуре синтаксисы ассемблеров к некоему обобщенному.

        Как вы считаете, этот подход позволит использовать "преимущества современных процессоров с кучей регистров"?


        1. VitGo Автор
          00.00.0000 00:00

          а что за преимущества в куче регистров вы выделяете ? не дергать постоянно память если данные можно хранить в регистрах ?

          так вроде нет препятствий


  1. ef_end_y
    00.00.0000 00:00
    +1

    Я осилил (надеюсь) только манипуляции с виртуальными регистрами. У меня 2 вопроса:
    1) зачем введено такое понятие, почему нельзя иметь сквозную нумерацию регистров, а компилятор сам распределит где виртуальные, а где нет?
    2) вы уверены, что итоговый код, когда значения виртуальных регистров будут летать туда-сюда в память (у нас ситуация что физических регистров меньше виртуальных, значит мы должны их хранить в кеше) будет оптимальней скомпилированного сишного кода, где компилятор оптимизирован под реальное количество регистров. Я когда-то смотрел скомпилированный код под MSP процессор и реально офигел, что он был довольно нетривиальным, т.е. не такой линейный как я ожидал


    1. VitGo Автор
      00.00.0000 00:00

      1) зачем введено такое понятие, почему нельзя иметь сквозную нумерацию регистров, а компилятор сам распределит где виртуальные, а где нет?

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

      для ассемблера гонять регистры на стек\со стека - реально не всегда удобно при отладке :-( да и с точки зрения быстродействия выгоды не столь очевидны (а иногда и просто нет)

      2) вы уверены, что итоговый код, когда значения виртуальных регистров будут летать туда-сюда в память (у нас ситуация что физических регистров меньше виртуальных, значит мы должны их хранить в кеше) будет оптимальней скомпилированного сишного кода, где компилятор оптимизирован под реальное количество регистров. Я когда-то смотрел скомпилированный код под MSP процессор и реально офигел, что он был довольно нетривиальным, т.е. не такой линейный как я ожидал

      ну уверен может быть только Господь, а над нашими планами он потом посмеется.. но попробовать считаю возможным....


  1. fpinger
    00.00.0000 00:00

    А решение будет сделано на chat gpt. Причем код никто не поймет, но он будет работать для нужного процессора )))


  1. Refridgerator
    00.00.0000 00:00
    +2

    Желание унифицировать вариации mov понятно и это легко. А что действительно сложно, так это:

    1) на одних платформах есть флаги, на других нет. Как унифицировать не только циклы, но и длинную арифметику?

    2) на одних платформах есть векторные инструкции, на других нет. Как унифицировать MMX, SSE, AVX и прочие? Даже ведущие программисты из Microsoft и Intel не справились с этим, размерность векторных инструкций в интринсиках задаётся всё ещё явным образом.

    3) на одних платформах есть произвольный доступ к регистрам, на других — нет (FPU как пример). Даже ведущие компиляторы от ведущих уже названных компаний не умеют по максимуму использовать весь стек FPU, ограничиваясь стандартными шаблонами и верхними двумя регистрами.

    4) на одних платформах двух-операндный синтаксис, на других трёх-, на третьих только и исключительно четырёх-. Вопрос тот же самый — как их унифицировать?


    1. ef_end_y
      00.00.0000 00:00
      +1

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


      1. VitGo Автор
        00.00.0000 00:00

        ну все немного не так как вы пишите.. поверьте, у себя в группе мы дизассемблировали сишные программы... оверкода там дофига

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

        например, неоднократно видели когда си применяет при работе с битовыми полями and\or хотя есть например BFI... возможно это из за того что на cortex-m0 просто нет bfi в системе команд... но в cortex-m3 \ cortex-m4 все равно используется and\or...


    1. COKPOWEHEU
      00.00.0000 00:00

      четырехоперандный синтаксис? Как такая платформа называется? И, если не затруднит, пример кода где это используется.


      1. Refridgerator
        00.00.0000 00:00

        FMA4 например. Примеры кода наверняка найдутся в официальной документации.


        1. COKPOWEHEU
          00.00.0000 00:00

          ну, это расширение, а не платформа. Отдельные четырехоперандные инструкции есть и в каком-нибудь RISC-V (fmadd rd, rs1, rs2, rs3)


          1. Refridgerator
            00.00.0000 00:00

            Ну, я не могу знать про все платформы в настоящем и тем более в будущем. Слышал, что у Эльбруса именно такой подход. Сам сталкивался с DSP-процессором, у которого все команды 3-операндные. В наше время вообще каждый может сделать свой собственный процессор на базе FPGA.


            1. COKPOWEHEU
              00.00.0000 00:00

              Так-то трехоперандных архитектур полно, те же ARM или RISC-V


              Двухоперандные это например AVR.


              1.5-операндные это например PIC (пол-операнда это один бит, с равным успехом можно добавить еще десяток мнемоник и счесть однооперандным).


              Вот и интересно существуют ли в природе честные однооперандные, безоперандные и те, в которых операндов больше трех.


              1. datacompboy
                00.00.0000 00:00

                Вот и интересно существуют ли в природе честные однооперандные

                Форт-машины, пожалуй, так как там второй операнд стек неявно.


  1. Arcanum7
    00.00.0000 00:00

    Плюс за старание и стремление к самосовершенству.


    1. VitGo Автор
      00.00.0000 00:00

      спасибо..


  1. Dovgaluk
    00.00.0000 00:00

    Я тоже стал придумывать микроязык для своего релейного компьютера.

    Основной фичей должна быть удобная работа с флагом переноса. Например, чтобы можно было сдвигать переменные по цепочке. Или складывать, используя дальше получившийся бит переноса для проверки условия.

    Правда синтаксис ещё не доточил, потому что компилятор не готов пока что.


    1. VitGo Автор
      00.00.0000 00:00

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


  1. emusic
    00.00.0000 00:00

    я не желаю создавать очередной си‑подобный язык высокого уровня!

    А зря. Я в начале 90-х тоже предпочитал ассемблер языкам высокого уровня, поскольку между ними был существенный разрыв - стоило перейти хотя бы на C, чтобы потерять контроль над рядом аспектов размещения и выполнения кода/данных, которые могли быть важны для задачи. То, что большинство тогда писало на C, C++ и Pascal, я писал на ассемблере, и был вполне доволен. :)

    А потом оказалось, что есть реализации и C, и даже Pascal, очень сильно приближенные к машинному уровню, где можно произвольно манипулировать размещением кода/данных в памяти, непосредственно использовать регистры в виде псевдопеременных, где ряд встроенных функций напрямую раскрывается в соответствующие команды процессора и т.п. Мне не приходилось писать для контроллеров ARM, но после перехода на VC++ в 90-х я совершенно потерял интерес к ассемблеру, поскольку практически все, что я привык контролировать на уровне команд и ячеек, можно было делать и в программе на C/C++, произвольно меняя уровень абстракции в любом месте. И это при том, что VC++ сильно уступал в этом тому же BC++.

    Так что опускать уровень ЯВУ - занятие гораздо более перспективное, нежели поднимать уровень ассемблера. Используя ЯВУ с богатыми возможностями доступа к целевой архитектуре, Вы в любом месте можете детализировать программу сколь угодно близко к железу, но, если этого не требуется, Вы можете использовать все преимущества абстракции, и переносимость обеспечивается автоматически. Используя же высокоуровневый ассемблер, Вы всегда остаетесь в рамках архитектуры (или семейства архитектур), ибо невозможно сколько-нибудь органично соединить ассемблерную детальность с достаточной степенью абстракции.


  1. progchip666
    00.00.0000 00:00

    Безумству смелых, поём мы песню. А я всё больше влезаю в HAL, хотя всё моё естество этому противится. Но так проще заработать, чем писать проги в машинных кодах, как в счастливые студенческие времена!


  1. Sergey_zx
    00.00.0000 00:00

    Когда я понял, что оптимизирующий компилятор С генерирует ассемблерный код который я не могу улучшить я перестал писать на asm. Конечно, можно сделать код более понятным для, человека. А если потрачу несколько часов то сэкономлю десяток байт. Но нахрена оно нужно то?

    Так что спускаюсь на уровень команд процессора лишь в очень экзотических случаях.

    Ну и, как я уже писал, почему то каждый начинающий программист первым пытается создать свой "удобный и понятный" язык программирования. Причем, исключительно в тех областях где и так имеется множество вполне успешных языков.


    1. aamonster
      00.00.0000 00:00

      Да и пусть создаёт, кому мешает? Зато "на сдачу" получаем человека, который гораздо глубже разобрался в архитектуре.


    1. VitGo Автор
      00.00.0000 00:00

      ну если вы улучшить не можете - возможно вы просто не знаете ассемблера... вот и все... и компилятор си тут не при чем :-)

      если в коде выше вы не можете ничего улучшить - то без комментариев...

      потому что кто хоть немного знает - он бы из 4 инструкций оставил 2, если хорошо знает ОДНУ инструкцию !!!!

      и это на каких то 4х строчках кода.... 4 байта как минимум экономии и минимум 2 такта исполнения

      p.s. это из под куба


      1. Sergey_zx
        00.00.0000 00:00

        Я видел и более убогие компиляторы. Такого же результата можно добиться отключением оптимизации. Но какое отношение они имеют к программировании на ассемблере?

        В тексте выше есть слово "оптимизирующие". Вам оно о чем то говорит?


        1. VitGo Автор
          00.00.0000 00:00

          я отвечал на ваш вопрос про то какой код генерит компилятор си...

          и поверьте - оптимизации включены


        1. VitGo Автор
          00.00.0000 00:00

          и вопрос про ваше знание ассемблера остался - так на что заменить этот говнокод ?