trol73 / the-rat-avr

The Rat language compiler for AVR
GNU General Public License v2.0
5 stars 0 forks source link

А как использовать?) #1

Open Vadimatorik opened 1 year ago

Vadimatorik commented 1 year ago

Добрый день. Прочел статью, перешел сюда, скачал. А как дальше? В статье сказано, что в архиве есть shell скрипт. А тут он где? Вообще хотелось бы в README.md увидеть полное описание того, как развернуть у себя из исходников под Ubuntu например. Ну и примеры сборки проекта из одного-двух файлов, как это делают для avr-gcc (в одну-две строки сборка из консоли, чтобы потом в свой makefile интегрировать).

Vadimatorik commented 1 year ago

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

Вот вообще не очевидно. Обычно всегда доставляют скобки, даже если их нет (на этапе парсинга всмысле). А потом подсчитывают количество ассемблерных операций. В GCC вроде так было. Но на пока что можно так. Рас уж оно работает. Но надо это отобразить лучше, да. Потому что это вообще сходу не очевидно.

Vadimatorik commented 1 year ago

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

Ахахахаха))) Ну как обычно, да) Никто не ожидал, но надо) Но все же хотелось бы, чтобы они были как-то по-проще. Уверен, тут есть ОГРОМНАЯ избыточность и от того читать очень тяжко(

Vadimatorik commented 1 year ago

Пока весь мир не начал массово кодить под AVR на Rat-е, буду отписываться об обновлениях, например, тут )

Ну я по завершении своего проекта под ATtiny13a хочу статейку таки выпустить. Люди из интереса хотя бы заглянуть посмотреть, что за зверь такой. И будет лучше, если будет к этому времени понятно, что откуда брать и как пользовать.

Vadimatorik commented 1 year ago

В целом уже начал ее писать по ходу. Чтобы не забыть))) "Язык программирования Rat (С-- для AVR): когда ASM больно, а С — жирно". В целом думаю, зайдет. Моим знакомым по предварительному отзыву вкатило) Там как раз детали, плата будут. Проект как раз влезет, отлажу и можно будет смело выводить с готовым примером от и до (туториал о том, как с нуля написать этот дивайс). За рекламу сойдет. Да и я самые главные тезисы неочевидные запишу. Чтобы использовать как методичку. Осталась малось: прекратить мечтать и сделать дело, ахахах)))

trol73 commented 1 year ago

Вот вообще не очевидно. Обычно всегда доставляют скобки, даже если их нет (на этапе парсинга всмысле). А потом подсчитывают количество ассемблерных операций. В GCC вроде так было. Но на пока что можно так. Рас уж оно работает. Но надо это отобразить лучше, да. Потому что это вообще сходу не очевидно.

Не очевидно - согласен. Но тут еще штука такая - философия Rat - это "человекоориентированный ассемблер". Т.е. он должен генерить конкретный предсказуемый машинный код, который должен быть однозначно понятен из листинга. Хотя бы по количеству инструкций. Т.е., не стоит от него ожидать, что он все максимально оптимизирует, и поэтому нужен разный синтаксис для if с одной командой внутри и if с блоком. В С-- для х86 для этого было сделано два разных if, и специальная команда IF для коротких блоков. Тут я попробовал вместо if / IF сделать вариант со скобками {} и без :)

В целом уже начал ее писать по ходу. Чтобы не забыть))) "Язык программирования Rat (С-- для AVR): когда ASM больно, а С — жирно". В целом думаю, зайдет. Моим знакомым по предварительному отзыву вкатило)

Вангую множество комментов в духе "ко-ко-ко, зачем этот ваш древний AVR с ассемблером, когда за те же деньги можно купить модный STM32 с кучей периферии и на кубе сделать то же за полчаса!" )) Многим сложно понять, что это делается скорее чисто по приколу )

Vadimatorik commented 1 year ago

Не очевидно - согласен. Но тут еще штука такая - философия Rat - это "человекоориентированный ассемблер". Т.е. он должен генерить конкретный предсказуемый машинный код, который должен быть однозначно понятен из листинга. Хотя бы по количеству инструкций. Т.е., не стоит от него ожидать, что он все максимально оптимизирует, и поэтому нужен разный синтаксис для if с одной командой внутри и if с блоком. В С-- для х86 для этого было сделано два разных if, и специальная команда IF для коротких блоков. Тут я попробовал вместо if / IF сделать вариант со скобками {} и без :)

Ну так-то да. Про С-- для x86 вообще не знал.

Вангую множество комментов в духе "ко-ко-ко, зачем этот ваш древний AVR с ассемблером, когда за те же деньги можно купить модный STM32 с кучей периферии и на кубе сделать то же за полчаса!" )) Многим сложно понять, что это делается скорее чисто по приколу )

А. Это норма. Я привык. Мне тоже самое писали под статьями по миландровскому чипу с Cortex-M3 ядром, когда были f1 и f4 уже в продаже))) Так что пофиг))) Яж это для себя и для таких же упоротых как я) Думаю те, кто на меня подписаны сейчас ожидают именно такой дичи)

Vadimatorik commented 1 year ago

Если интересно, то вот он я)))

Vadimatorik commented 1 year ago

Решил написать серию простеньких проектов, чтобы постепенно увеличивать сложность. Скачал реп, создал пустой файл. Создал пустой проект новый и... image

Вопрос: как принудительно заставить синтаксис подчеркивать? Расширение файла имеет значение? (art/rat)?

Vadimatorik commented 1 year ago

Создал уже на последней студии. Пробовал удалить в корне home .trolstudio. То есть на чистую такая же реакция. Пробовал сначала файлы добавить, потом проект настроить и наоборот. Не помогло.

Кроме того, указание чипа в конфигурации все еще ничего не дает( Приходится писать ручками.

Vadimatorik commented 1 year ago

Вот конфигурация на текущий проект:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE workspace SYSTEM "rtext-workspace.dtd">
<workspace>
  <projects>
    <project device="attiny13a" encoding="UTF-8" mainfile="/home/vadimatorik/proj/rat/demo_led_flasher/main.rat" name="demo_led_flasher" type="AVR_RAT">
      <file path="/home/vadimatorik/proj/rat/demo_led_flasher/main.rat"/>
    </project>
  </projects>
</workspace>
Vadimatorik commented 1 year ago

Edit -> Options выдает вот это: image Вот текстом:

java.io.IOException: XML error:  Error parsing file
    at org.fife.rtext.optionsdialog.LanguageOptionPanel.getLocalizations(LanguageOptionPanel.java:183)
    at org.fife.rtext.optionsdialog.LanguageOptionPanel.<init>(LanguageOptionPanel.java:107)
    at org.fife.rtext.optionsdialog.OptionsDialog.<init>(OptionsDialog.java:69)
    at org.fife.rtext.RText.getOptionsDialog(RText.java:489)
    at org.fife.ui.app.AbstractGUIApplication$OptionsAction.actionPerformed(AbstractGUIApplication.java:1494)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:374)
    at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1028)
    at java.desktop/javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1072)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
    at java.desktop/java.awt.Component.processEvent(Component.java:6391)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:746)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:744)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Vadimatorik commented 1 year ago

А в опциях так: image

Vadimatorik commented 1 year ago

А все, понял. Надо было art называть. Потом перезагрузить среду.

Vadimatorik commented 1 year ago

Вот еще один баг. Код из примере ошибки сыпет.

Vadimatorik commented 1 year ago

Еще один.

Vadimatorik commented 1 year ago

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

trol73 commented 1 year ago

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

trol73 commented 1 year ago

Исправил, обновил rat-ide.jar

Vadimatorik commented 1 year ago

А какие из проблем тут решены? Этот кусок все еще не работает:

proc delay_1_ms() {
    loop (X: 3200) {
    }
    ret
}
Vadimatorik commented 1 year ago

В таком виде работает:

proc delay_1_ms() {
    XL = low(3200)
    XH = high(3200)
    loop (X) {
    }
    ret
}
trol73 commented 1 year ago

Тут ошибка, правильно так:

proc delay_1_ms() {
    loop (X= 3200) {
    }
    ret
}

Но так оно тоже не работает, и это новый баг :)

trol73 commented 1 year ago

А еще можно так. Но баг с инициализацией в цикле все равно надо исправить

proc delay_1_ms() {
  X = 3200  
  loop (X) {
    }
    ret
}
Vadimatorik commented 1 year ago

Тут ошибка, правильно так:

А, да, точно. Криво скопировал.

Но так оно тоже не работает, и это новый баг :)

Был уверен, что поставил карточку, но нет. Вот сейчас поставил.

Vadimatorik commented 1 year ago

Так. Важный вопрос. А как заставить выкинуть неиспользуемые методы?))) Типа вот у меня есть файл с разными задержками. Я в проекте хочу использовать одну. Как мне выкинуть неиспользуемые?) Или тут в целом библиотечный подход не выйдет использовать? Вот пример. Я использую только самую нижнюю. А тянутся все оставшиеся) image

trol73 commented 1 year ago

А никак, тут все как в ассемблере ) В идеале надо хорошо подумать, как сделать поддержку библиотек, которые будут скачиваться из репозитория и поддерживать разные МК. И вот там имеет смысл импортировать только необходимое, Но пока до этого еще далеко (еще нет достаточной кодовой базы)

Vadimatorik commented 1 year ago

Ну вот я думал что для своего чипа напишу и буду радоваться жизни. С proc inline это отлично отрабатывает) Но Писать всё ими - ну как-то тяжко... Хотя можно делать вставками в обычные функции. Наверное, так и поступлю. Придумаю локальные правила именования и буду так называть.

Как я понимаю, после закрытия карточки - файл обновляется и тут записи об этом не будет? Чтобы мне IDE патчикть.

Vadimatorik commented 1 year ago

В ассемблере, к слову, можно) Я написал LD скрипт и кроме вектора прерываний все секции не обязательные. И компановщик выкидывает все методы, которые не используются. Вроде как)

Vadimatorik commented 1 year ago

Будет выходить (о библиотеке) что-то типа такого: image image

Vadimatorik commented 1 year ago

Все же с IDE тяжко. Пока жду железку - хотел открыть второй проект рядом (создать) и написать мигалку уже на таймере (увеличение сложности). Но вот что получил: изображение изображение Я скопировал те же файлы, что нормально собирались в первом проекте. Создал директорию, кинул их туда, одинаково настроил проект, только указал путь до main в другой директории. И вот. На фото 2 раза подряд нажимаю сборку. Ошибка разная при чем) После первого раза создается hex и map.

trol73 commented 1 year ago

С IDE все плохо, да, но при этом она более-менее юзабельна. Но всегда могу открыть доступ к исходникам, если вдруг имеется непреодолимое желание хочется ее фиксить ) А вот порнографию с длинными путями в Include точно пора исправлять. Добавлю работу с файлом конфигурации ".ratc", который будет искаться сначала в директории с файлом исходника, затем в директории с jar-кой. Там можно будет прописать параметры по умолчанию.

Кстати, на скринах выше странное - функция main - точка входа и должна быть объявлена самой первой.

По библиотекам - надо будет добавить атрибуты для процедур. Пока видится потребность в двух:

  1. чтобы ret добавлялся автоматом в конец
  2. чтобы процедура не включалась в генеримый код, если она не используется
Vadimatorik commented 1 year ago

Но всегда могу открыть доступ к исходникам, если вдруг имеется непреодолимое желание хочется ее фиксить )

Пока не стоит))) Там железо придет и буду по одному разбираться. Но то что нет возможности просто открывать проект - это конечно ад, да. Каждый раз настраивать вместо открытия...

А вот порнографию с длинными путями в Include точно пора исправлять.

Работаю с тем, что имею, ахахахах)))

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

Главное, чтобы пример был)

Кстати, на скринах выше странное - функция main - точка входа и должна быть объявлена самой первой.

В тех include, что выше - только inline proc методы. Так что все хорошо.

По библиотекам - надо будет добавить атрибуты для процедур. Пока видится потребность в двух:

Норм идея. inline есть уже.

чтобы ret добавлялся автоматом в конец

Тогда уж, чтобы был выбор с reti

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

Это было бы очень удобно, да. Причем надо учесть вложенность. Я мог бы вызвать delay_ms(500), а он внутри себя вызвать delay_1_ms() (пример просто вложенности). И это тоже учесть надо будет.

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

Vadimatorik commented 1 year ago

Так. И еще вопрос. Есть возможность как-то версию смотреть? Компилятора в составе IDE и отдельно. Я тут просто локальный "CI" поднимаю (просто shell скрипт, который будет обновлять библиотеку у всех проектов директории rat и пытаться их собрать. Выводить отчет. И я запутался, какая версия компилятора в среде, какая отдельно в архиве)))

Надо как-то может закрепить где-то актуальную версию? Можно в README на проект как вариант. А то реально непонятно) Да и ссылку каждый раз искать по треду тяжко...

trol73 commented 1 year ago

Оболочки для методов - это сложно. При том, что return в методе может быть где угодно (или даже его может не быть совсем). Кстати, "весь код в прерываниях" - выглядит как "не ок". По-хорошему, в прерываниях должно быть минимум кода, чтобы работали максимально быстро. А логика - в главном цикле. Типа, прерывания только устанавливают флаги запуска задач, а сами задачи запускаются из основного цикла. Хотя, для тини13 с его килобайтом памяти, возможно, будет слишком расточительно )

Конфиги сделал. Файл ".ratc" можно положить либо в директорию с the-rat.jar (будет глобальный конфиг), либо в ту же директорию, что и первый компилируемый исходник. Содержимое - простое, туда можно положить аргументы, аналогичные тем, что передаются в командной строке. Каждый аргумент - отдельная строка в конфиге. Например,

-I/home/user/dev/rat/libs
-DGLOBAL_MACRO
Vadimatorik commented 1 year ago

Кстати, "весь код в прерываниях" - выглядит как "не ок". По-хорошему, в прерываниях должно быть минимум кода, чтобы работали максимально быстро. А логика - в главном цикле. Типа, прерывания только устанавливают флаги запуска задач, а сами задачи запускаются из основного цикла.

Знаю. Это база) Всем именно это и советую. Но! У меня домашний проект на AVR, в котором я буквально считаю такты, смотрю загруз проца логическим анализатором + скриптом (в процессе отладки скрипта из CSV файла). Так что тут все более чем отлично. Но вообще да. Если у тебя есть ОС - то выдать симафор или уровня того. Если нет ОС и event-loop подход, то положить в очередь, обработать прерывание и выйти. А основном цикле работать с данными.

Хотя, для тини13 с его килобайтом памяти, возможно, будет слишком расточительно )

Ни сколько в нем дело. Просто сам проект такой) Это чисто для себя. А то на работе у меня лямбда передается в шаблонный метод, работающий с кортежем шаблонных типов... Короче С++17 во всей красе. И все это в карутине какой-то, которая крутится в каком-то потоке основной ОС)))

Конфиги сделал. Файл ".ratc" можно положить либо в директорию с the-rat.jar (будет глобальный конфиг), либо в ту же директорию, что и первый компилируемый исходник. Содержимое - простое, туда можно положить аргументы, аналогичные тем, что передаются в командной строке. Каждый аргумент - отдельная строка в конфиге.

О. Оно может в относительные пути? -Isrc?

trol73 commented 1 year ago

Так. И еще вопрос. Есть возможность как-то версию смотреть? Компилятора в составе IDE и отдельно. Я тут просто локальный "CI" поднимаю (просто shell скрипт, который будет обновлять библиотеку у всех проектов директории rat и пытаться их собрать. Выводить отчет. И я запутался, какая версия компилятора в среде, какая отдельно в архиве)))

Надо как-то может закрепить где-то актуальную версию? Можно в README на проект как вариант. А то реально непонятно) Да и ссылку каждый раз искать по треду тяжко...

Пока никак, версий сейчас всего две - 0.1.0 и "последняя" (которая всегда 0.1.1)

Можно скриптом выкачивать компилятор и, если файл изменился, сохранять его в директорию как новую версию )

trol73 commented 1 year ago

О. Оно может в относительные пути? -Isrc?

Скорее всего нет, но можно попробовать ) В IDE точно не должно взлететь. В консоли - может

Vadimatorik commented 1 year ago

Можно скриптом выкачивать компилятор и, если файл изменился, сохранять его в директорию как новую версию )

Блэд))) Костылизация... Ок.

Скорее всего нет, но можно попробовать ) В IDE точно не должно взлететь. В консоли - может

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

Vadimatorik commented 1 year ago

Кстати, а на сайте имеется где-то ссылки на IDE и компилятор актуальный в одном месте чтобы? Чтобы тред не листать каждый раз...

Vadimatorik commented 1 year ago

Плюс одна ошибка.

Vadimatorik commented 1 year ago

И по скрипту тоже нюанс возник.

trol73 commented 1 year ago

Кстати, а на сайте имеется где-то ссылки на IDE и компилятор актуальный в одном месте чтобы? Чтобы тред не листать каждый раз...

Про IDE на сайте вообще ничего нет, т.к. она официально не зарелижена ) Самый последний Rat всегда можно взять из репы https://github.com/trol73/avr-make точнее, тут https://github.com/trol73/avr-make/blob/master/tools/the-rat.jar (добавил в статью на сайте) Можно просто себе эти ссылки скопировать, чтобы каждый раз не искать )

Vadimatorik commented 1 year ago

Про IDE на сайте вообще ничего нет, т.к. она официально не зарелижена )

Ладно. Тогда пока держу ссылку в google docs)

Самый последний Rat всегда можно взять из репы https://github.com/trol73/avr-make точнее, тут https://github.com/trol73/avr-make/blob/master/tools/the-rat.jar (добавил в статью на сайте)

Ок) Тоже ссылку сохранил.

Можно просто себе эти ссылки скопировать, чтобы каждый раз не искать )

Ага. Ок.

Vadimatorik commented 1 year ago

Так. У меня наконец-то появилась плата для тестов. И вот прошить кнопкой из IDE я не смог. Потому что...: image Есть мысли, как решить этот вопрос? Я пока шьюсь снаружи.

trol73 commented 1 year ago

Ого, а я и не знал, что там команда прошивки вообще работает, думал, что не реализовал ее ) avrdude ругается на неизвестный ей микроконтроллер, надо найти avrdude.conf и добавить attiny13a (аналогично attiny13, но с другой сигнатурой)

trol73 commented 1 year ago

И, да, похоже, что avrdude старой версии. Новая должна ругаться на аргумент '-s'

Vadimatorik commented 1 year ago

avrdude ругается на неизвестный ей микроконтроллер, надо найти avrdude.conf и добавить attiny13a (аналогично attiny13, но с другой сигнатурой)

Скопировал просто конфиг от attiny13 и просто заменил id на attiny13a. Может это и не очень правильно. Но оно шьется теперь)))

И, да, похоже, что avrdude старой версии. Новая должна ругаться на аргумент '-s'

Про версию: avrdude version 6.3-20171130. Это то, что было в ubuntu 20.04 в стандартных репах. Вроде как. Давно ставил. Но сейчас из среды шьется. И это отлично.

Vadimatorik commented 1 year ago

Так. Ну прогресс пошел) Сейчас планирую за выходные 5 простеньких проектов. Эдакий хакатон (если время позволит). Все в открытый доступ как референсы для начинающих.

Вот первый из них))) Думаю, буду кидать сюда, чтобы их можно было потом в какую-то базу кидать для начинающих.

Кстати примерно такого описания бы хотелось у The Rat, как у проекта, что выше привел) Как освоюсь, планирую написать.

Vadimatorik commented 1 year ago

Так. Компилятор не переваривает такую запись:

use X as ms_counter

Но такую переваривает:

use XH.XL as ms_counter

И где-то в коде:

 ms_counter = 0 ;

Это так и подразумевается? Или баг?

Vadimatorik commented 1 year ago

Также компилятор в коде не может съесть такое:

if (ms_counter == 500) {

Когда не месте ms_counter - X. Я конечно сейчас распишу ручками, но хотелось бы, чтобы он сам это проверял.

Vadimatorik commented 1 year ago

Также вопрос возник к кодогенерации. Началось использование магии с отрицательным сложением. При том, что у меня по сути тут X регистр. Если напишу явно X, то все хорошо будет. image