1с рецепты кода на компьютере

Содержание

1с рецепты кода на компьютере

Краткое описание:
Изучение программирования

Доступные языки: Java, JavaScript, Python, C#, C++, Swift и Objective-C.

✓ Изучение синтаксиса языка на конкретных примерах кода. Как получить подстроку? Как объявить обобщенный метод? Как реализовать паттерн «Стратегия»? В приложении доступны эти и еще более 250 примеров кода по каждому языку.

✓ В программе отобраны лучшие примеры кода из книг и специализированных интернет ресурсов. Для поиска оптимального решения в интернет можно затратить часы рабочего времени. В приложении содержаться готовые и проверенные «рецепты» кода.

✓ Не знаете какой язык программирования выбрать? Приложение поможет сравнить синтаксис каждого из примеров на разных языках программирования и принять взвешенное решение при выборе языка.

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

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

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

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

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

✓ В приложении бесплатно доступны основные (базовые) примеры по всем языкам программирования. Примерно 45% примеров доступны за дополнительную плату.

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

Требуется Android: 4.1.x
Русский интерфейс: Да

Источник

1С рецепты кода на компьютер

Информация

Доступные языки: 1С 8.3

Изучение синтаксиса языка на конкретных примерах кода:
✓ Как получить подстроку?
✓ Как очистить регистр сведений?
✓ Как запустить фоновое задание?
✓ Как получить остатки из регистра накопления на заданную дату?
✓ В приложении доступны эти и еще более 350 примеров.

✓ В программе отобраны лучшие примеры кода из книг и специализированных интернет ресурсов. Для поиска оптимального решения в интернет можно затратить часы рабочего времени. В приложении содержаться готовые и проверенные «рецепты» кода.

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

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

✓ Я, как разработчик, сам использую данную программу, когда нужно быстро вспомнить как реализовать возникшую на 1С задачу.

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

[Есть версия этого приложения под вторую популярную мобильную платформу]

Инструкции по установке

Cкачать и установить 1С рецепты кода на компьютер бесплатно.

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

Если вы не любите маленькие экраны смартфона или планшета, то сделать это можно с помощью программы-эмулятора. С ее помощью можно создать на своем компьютере среду Android и через нее запустить приложение. На данный момент самыми популярными утилитами для этого являются: Bluestacks и NoxPlayer.

Установка 1С рецепты кода на компьютер с помощью Bluestacks

Bluestacks считается самым популярным эмулятором для компьютеров под управлением Windows. Кроме того, есть версия этой программы для Mac OS. Для того, чтобы установить этот эмулятор на ПК нужно, чтобы на нем была установлена Windows 7 (или выше) и имелось минимум 2 Гб оперативной памяти.

Установите и настройте Bluestacks. Если на компьютере нет Bluestacks, перейдите на страницу https://www.bluestacks.com/ru/index.html и нажмите зеленую кнопку «Скачать Bluestacks» посередине страницы. Щелкните по зеленой кнопке «Скачать» в верхней части следующей страницы, а затем установите эмулятор:

+ Windows: дважды щелкните по скачанному EXE-файлу, нажмите «Да», когда появится запрос, щелкните по «Установить», нажмите «Завершить», когда эта опция станет активной. Откройте Bluestacks, если он не запустился автоматически, а затем следуйте инструкциям на экране, чтобы войти в свою учетную запись Google.

+ Mac: дважды щелкните по скачанному файлу DMG, дважды щелкните по значку Bluestacks, нажмите «Установить», когда будет предложено, разрешите устанавливать программы сторонних разработчиков (если понадобится) и нажмите «Продолжить». Откройте Bluestacks, если он не запустился автоматически, и следуйте инструкциям на экране, чтобы войти в свою учетную запись Google.

Скачайте файл APK на компьютер. APK-файлы являются установщиками приложений. Вы можете скачать apk-файл с нашего сайта.

Щелкните по вкладке «Мои приложения». Она находится в верхней левой части окна Bluestacks.

Нажмите «Установить APK». Эта опция находится в нижнем правом углу окна. Откроется окно Проводника (Windows) или Finder (Mac).

Выберите скачанный файл APK. Перейдите в папку со скачанным файлом APK и щелкните по нему, чтобы выбрать.

Нажмите «Открыть». Эта опция находится в нижнем правом углу окна. Файл APK откроется в Bluestacks, то есть начнется установка приложения.

Запустите приложение. Когда значок приложения отобразится на вкладке «Мои приложения», щелкните по нему, чтобы открыть приложение.

Установка 1С рецепты кода на компьютер с помощью NoxPlayer

Nox App Player бесплатна и не имеет никакой навязчивой всплывающей рекламы. Работает на Андроиде версии 4.4.2, позволяя открывать множество игр, будь то большой симулятор, требовательный шутер или любое другое приложение.

+ Перейти на официальный сайт разработчика https://www.bignox.com/

+ Для того чтобы установить эмулятор Nox App Player, нажимаем на кнопку «СКАЧАТЬ».

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

Установка и запуск программы:

+ Для продолжения установки необходимо в открывшемся окне нажать на кнопку «Установить». Выберите дополнительные параметры инсталляции, нажав на кнопку «Настроить», если вам это необходимо. Не снимайте галочку с пункта «Принять «Соглашение»», иначе вы не сможете продолжить.

+ После того как эмулятор будет установлен на компьютер, вы увидите на экране окно запуска, где необходимо будет нажать на кнопку «Пуск».

+ Все, на этом этапе установка эмулятора Nox App Player завершена. Для полноценной работы программы вам необходимо будет зайти в свой аккаунт Play Market — нажмите на иконку приложения в папке Google, введите логин и пароль от вашей учетной записи.

Загрузка и установка приложений: Для этого вам необходимо скачать файл приложения в формате APK и просто перетащить его на рабочий стол Nox App Player. После этого сразу начнется установка, по окончании которой вы увидите значок этого приложения на главном экране.

Источник

👨‍💼 Освойте программирование в 1С за 60 минут: самоучитель для начинающих

В 1С подход иной. Сначала вы приобретаете платформу 1С: Предприятие у фирмы “1С” или ее партнера. Затем покупаете одно из прикладных решений – конфигурацию. Ее вы можете использовать “как есть”, вносить свои доработки, чтобы адаптировать под специфику бизнеса, либо разработать собственную конфигурацию с нуля. Это похоже на прослушивание пластинок с помощью проигрывателя. Достаточно иметь одну платформу (проигрыватель) “1С: Предприятие”, – и можно разрабатывать или использовать любые конфигурации (пластинки), будь то “1С: Бухгалтерия предприятия”, “1С: Управление торговлей” или собственное решение. И также, как пластинка без проигрывателя – всего лишь кусок пластика, так и конфигурацией вы никак не сможете воспользоваться, не имея платформы 1С.

Разработка начинается с конфигуратора

В этой статье я исхожу из того, что у вас уже есть 1С-ка и вы используете для работы конфигурацию “Бухгалтерия предприятия”. После запуска 1С: Предприятия всегда сначала открывается Окно запуска 1С.

Рис. 1. Окно запуска 1С: Предприятия.

Кнопка “Конфигуратор” перенесет вас в среду разработки – главное окно конфигуратора. И первое, что необходимо сделать, – это открыть конфигурацию. Зайдите в меню “Конфигурация – Открыть конфигурацию” или нажмите соответствующую кнопку в панели инструментов, и дождитесь открытия окна дерева метаданных.

Итак, мы находимся в главном окне конфигуратора – рабочей среде программиста 1С. Давайте осмотримся на местности.

Рис. 2. Главное окно конфигуратора.

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

Главный инструмент разработчика – это окно Конфигурация, открытое слева. Еще его называют дерево метаданных. Это описание всей структуры вашей базы, с указанием структуры каждого отдельного объекта, правил взаимодействий объектов между собой, настройками интерфейсов, прав доступа и много другого. Каждый элемент дерева имеет свою специфику использования и набор инструментов для работы с ним. Так, если дважды щелкнуть по любому справочнику или документу, то откроется окно редактирования объекта (рис. 3), а если выбрать в контекстном меню пункт Свойства, справа появится панель свойств текущего объекта. Это второй основной инструмент разработчика, с которым он взаимодействует чаще всего. На рисунке 4 представлен пример рабочей среды с открытой панелью свойств.

Рис. 3. Пример окна редактирования объекта метаданных. Рис. 4. Пример рабочей среды в процессе разработки.

Задача на разработку: создание реестра счетов-фактур

У вас уже есть платформа 1С: Предприятие и установленная на ней конфигурация “1С: Бухгалтерия предприятия”. И теперь руководитель ставит перед вами задачу выполнить разработку нового функционала. В реальной жизни происходит примерно то же самое: на предприятии установлено некое типовое решение, но со временем появляется потребность адаптировать функционал конфигурации под специфику учета конкретного предприятия. Этим и займемся.

Ваша задача – разработать реестр счетов-фактур – вывести список документов, отобранный и отсортированный по определенным правилам.

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

Создание внешнего отчета

Существует три фундаментальных подхода к внесению доработок в 1С:

Воспользуемся самым простым вариантом и создадим внешний отчет “Реестр счетов-фактур”. Для этого в меню “Файл” выбираем пункт “Новый” и создаем новый внешний отчет (рисунок 5).

В графе “Имя” напишите РеестрСчетовФактур, синоним будет присвоен автоматически, исправьте его на “Реестр счетов-фактур”. В поле “Форма отчета” нажмите кнопку открытия (с изображение лупы), откроется конструктор новой формы. Нажмите кнопку Готово, новая форма будет создана и открыта для редактирования.

Редактор формы

Обзор редактора формы

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

Рис. 7. Окно редактора формы.

Визуальный редактор формы состоит из нескольких областей:

Для формирования реестра нам понадобится:

Реквизиты формы

Основная компоновка формы завершена, но остался еще один важный элемент – кнопка, по нажатию на которую должно все произойти. Исправим этот недостаток.

Команды формы

Откройте вкладку Команды и создайте новый элемент. Задайте новой команде имя Сформировать, присвойте картинку СформироватьОтчет из библиотеки стандартных картинок, а свойству Отображение задайте значение “Картинка и текст”.

Рис. 11. Добавление команды “Сформировать отчет”.

Чтобы разместить кнопку на форме, перетащите ее на элемент “Командная панель” во вкладке Элементы и включите для созданного элемента “Кнопка” свойство КнопкаПоУмолчанию. Отображение кнопки на форме вы сразу не увидите, это связано с тем, что по умолчанию главная командная панель формы отключена. Зайдите в панель свойств самой формы (корневой элемент “Форма” во вкладке Элементы), и для свойства ОтображениеКоманднойПанели установите значение “Авто”.

Рис. 12. Размещение основной кнопки в командной панели формы.

В завершение конструирования формы создадим обработчик для нашей команды. Обработчик связывает элемент формы – или какое-либо действие над элементом – с кодом программы.

Рис. 13. Создание обработчика команды в модуле формы.

Проверка формы в режиме “1С: Предприятие”

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

Сохраните результаты своей работы (меню Файл – Сохранить). Файл внешнего отчета 1С имеет расширение .erf.

Запустите “Бухгалтерию предприятия” в пользовательском режиме, если она еще не запущена. Сделать это можно прямо из конфигуратора, через меню Сервис – 1С: Предприятие. В открывшемся окне информационной базы зайдите в главное меню, выберите пункт Файл – Открыть… и откройте ваш внешний отчет. Сейчас можно проверить, как работает выбор периода и организации.

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

Рис. 14. Пользовательский режим информационной базы.

Ваш первый код: собираем данные для отчета

Приступим к написанию кода на языке программирования 1С. Язык этот не сложный, в нем нет строгой типизации и он полностью русифицирован.

Редактирование кода формы происходит в модуле формы, которая находится на вкладке Модуль окна редактора формы. Здесь уже создана основа обработчика для кнопки “Сформировать”.

Клиент-серверное программирование логики

Первый код процедур

Напишите код клиентской процедуры Сформировать(), как показано ниже:

Если коротко, то здесь выполняется проверка на заполнение периода отчета на форме, и, если период не заполнен, то выводится предупреждение, и дальнейшее выполнение команды прекращается.

Теперь немного по конструкциям языка:

Код нашей серверной процедуры будет выглядеть следующим образом:

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

Синтакс-помощник – путеводитель по языку программирования

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

К счастью. в платформе 1С есть палочка-выручалочка программиста – синтакс-помощник, который открывается из меню Справка – Синтакс-помощник. А если интересует справка по конкретному методу, то встаньте на него в коде модуля и нажмите сочетание клавиш Ctrl+F1. Синтакс-помощник откроется на статье с описанием этого метода.

Рис. 16. Получение справки по функции Следующий() в синтакс-помощнике.

А как отчет будет выглядеть? Знакомимся с макетом

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

Рис. 20. Готовый макет реестра.

Выводим данные в табличный документ

Как я уже упоминал выше, для программного формирования отчета мы будем использовать специализированный объект языка программирования 1С ТабличныйДокумент. Объявим его создание в начале нашей процедуры и сохраним в отдельную переменную:

Для чтения данных из макета “Реестр” необходимо сначала получить программный объект этого макета:

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

Далее, в цикле выводим данные документа в строку, предварительно заполнив параметры через свойство области Параметры:

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

Полный текст процедуры:

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

Рис. 21 Готовый отчет

Итоги

Поздравляю! Ваш первый отчет на 1С готов. За этот час вы освоили довольно много материала:

И если вам интересно погрузитья в тонкости разработки, то вас ждет захватывающее путешествие в мир 1С. До новых встреч!

Онлайн-платформа гарантирует ваше трудоустройство после получения сертификата и сдачи экзамена.

Источник

1С: Ассемблер — пишем чистый байт-код для стековой машины 1С: Предприятие

Стековые машины используются в большом множестве современных языков программирования. Они просты для понимания и при этом достаточно эффективны. Хотите попробовать одну такую в действии?

Все вы, наверное, слышали, что 1С-ники жалуются на свою систему, считая язык 1С недостаточно низкоуровневым, скучным и т.п. Все они с тоской поглядывают в сторону «настоящих» языков программирования. Так вот, господа, они неправы. В системе 1С есть места, где можно размять программерский мозг и получить удовольствие от низкоуровневой техники. Предлагаю вам погрузиться в недра виртуальной машины 1С и понять, как она работает. Там есть свой «ассемблер» и сегодня мы будем писать на нем рабочий код для 1С. Заходите под кат, будет весело!

Стековые виртуальные машины

Мир все больше и больше захватывают динамические языки программирования. От «честных» нативных языков в строю остался, пожалуй, только Си (с плюсами и без). Это если брать промышленный мейнстрим. Все популярные языки так или иначе имеют прослойку в виде «исполняющей среды» или «виртуальной машины», которая обеспечивает выполнение кода на той или иной архитектуре железа. И подавляющее большинство этих «виртуальных машин» являются стековыми, т.е. реализуют обработку операций с помощью такой известной в компьютерном мире структуры, как «стек».

Ремарка для тех, кто забыл

Стек (Stack) в переводе с английского означает «стопка». Когда мы кладем в стопку (скажем, книг) какую-то новую книжку, то она оказывается сверху. Убирать из стопки книги мы можем только сверху вниз. Т.е. последняя добавленная книжка снимается из стопки самой первой. Это тот самый принцип «LIFO» — last in/first out. Обратной ситуацией является очередь (в магазине). Кто первый встал — того и тапки.

Java, Python, C# и 1С — все они используют стековые машины для выполнения своего кода. Рискну предположить, что node.js — тоже, но это неточно, а гуглить мне лень. 95% вероятности, что это так и есть. про JIT я скромно умолчу, это ведь опция, неправда ли? 🙂

Если совсем спускаться в академические точности, то есть язык, а есть исполняющая среда. Так вот, язык — это лишь спецификация и, вообще-то, текст. Он не выполняется, он в блокноте написан. А вот то, что выполняет написанное — это может быть как стековым, так и нет. Поэтому нельзя сказать что Java — это стековый язык. Стековым бывает то, что выполняет язык. Так, например, для Java есть общепринятая машина JVM — она стековая. А в Андроидах используется (или использовалась) регистровая машина Dalvik. Ходят слухи, что ее оттуда выпилили, но я не проверял. Язык — один, машин может быть несколько. Но, как правило, этим можно пренебречь, поскольку все равно у каждого упомянутого языка есть всего одна (реже несколько) реализующих машин и почти все они, скорее всего, будут стековыми.

У языка 1С тоже есть несколько реализаций. Первая — сама 1С, вторая — например, 1Script. Есть еще несколько, чуть менее известных.

Стековая машина

Устроена стековая машина невероятно просто. Я разбирал ее устройство на Хабре еще в 2014 году, поэтому здесь просто коротенько напомню.

Итак, вот есть у вас выражение А = 1 + 1; как оно выполняется стековой машиной?

Поместить в стек операнд-константу 1 (2 раза), затем выполнить операцию Add.

Операция Add извлекает свои аргументы из стека (2 штуки) и складывает. Результат кладет обратно на стек. Операция LoadVar берет переданную переменную А и загружает в нее то, что лежит на стеке (в данном случае — результат сложения).

Этот простой алгоритм позволяет эффективно вычислять цепочки выражений. Например, операция А = 1+1+2 будет выглядеть вот так:

Каждая машина имеет свой набор операций, не обязательно такой, как здесь, но принцип у всех общий: операции по очереди кладут что-то на стек или извлекают что-то из стека.

Операции, выполняемые виртуальной машиной, принято называть «байт-кодом». Это такой «ассемблер» для стековой машины.

Как увидеть байт-код машины 1С

По умолчанию, если вы в 1С сохраняете какой-либо модуль, он сохраняется в чистом виде, так, как вы его написали. Однако, если поставить на модуль пароль или удалить модуль из поставки, то системе потребуется как-то все-таки узнать — что выполнять. Поэтому, система при сохранении компилирует ваш код 1С в байт-код и сохраняет уже его. Например, если вы поставите пароль на модуль внешней обработки, то в файл epf ляжет скомпилированный байткод. Его можно посмотреть утилитами семейства v8unpack.

Какой же хакер без подходящих инструментов

Давайте посмотрим на байткод 1С. Права на описанные инструменты принадлежат их авторам, как и всяческие респекты от меня и сообщества.

Для начала нам потребуется распаковщик файлов epf. Самый простой способ, это установить его через chocolatey

Тем, у кого нет chocolatey (эй, чуваки, как вы без него живете?) можно скачать по прямой ссылке https://github.com/e8tools/v8unpack/releases/download/v.3.0.40/v8unpack.exe но не забудьте потом exe прописать в PATH, чтобы было удобнее запускать.

Итак, возьмем любую внешнюю обработку 1С, модуль которой не скрыт паролем, и посмотрим на нее изнутри.

Будет создан каталог content, а в нем размещено содержимое внутренних файлов контейнера 1С (кому интересно — формат контейнера описан вот здесь: https://infostart.ru/public/250142/)

Отлично, а что же на уровне внутренних файлов? Сохраним запароленную обработку, удалим каталог content от предыдущего запуска и повторим команду

посмотрим в каталог с GUID.0 ого, появился файлик image, а в файле text — какая-то абракадабра. Платформа зашифровала содержимое модуля, его действительно не видно, но ей же надо как-то выполнять алгоритмы, верно? Для этого она перед шифрованием скомпилировала код 1С в байт-код виртуальной машины и записала его в файл image. Посмотрим на него:

Это — ассемблер 1С. Именно его выполняет платформа, когда считает всем зарплату. И знаете, что самое интересное? Мы можем напрямую писать код на этом ассемблере, не прибегая к услугам компилятора! Слабо? Я же говорил, что будет весело!

А зачем это нужно?

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

Во-вторых, вы наверняка знаете, что байт-код 1С очень легко декомпилируется обратно в скриптовый код, вплоть до сохранения имен переменных и процедур. Существуют даже обфускаторы 1С-кода, которые портят код, так чтобы он плохо читался после декомпиляции. На «ассемблере 1С» можно написать код таким образом, что он вообще не будет декомпилироваться. Позже я покажу, как написать работоспособный код, который платформа будет выполнять, но для которого просто не существует соответствующих ему синтаксических конструкций в языке 1С. Декомпилятору будет просто нечего выдать на выходе. Здорово, правда?

Я против воровства результатов чужого труда. Если вы пользуетесь декомпилятором, то скорее всего, вы не хотите платить автору, т.е. просто хотите украсть его работу. Это некрасиво. Поэтому, я не буду приводить ссылки на декомпилятор 1С в сети. Более того, каждый раз, когда в сети (чаще на Мисте) вы видите вопрос про «как декомпилировать обработку», «как снять пароль с 1С» — обязательно напишите автору вопроса, что он говнюк и мелкий воришка.

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

И еще: я не буду рассказывать, как именно построить такой обфускатор (я против, помните), но дам пару намеков, которые могут сработать, если вы захотите создать таковой.

Ну че, поехали?

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

Создайте любую внешнюю обработку с зашифрованным модулем, распакуйте ее с помощью v8unpack и в «Ассемблере» откройте файл «image», который мы рассмотрели чуть раньше.

Тут пока все будет не очень понятно, поэтому, давайте разбираться, как работает виртуальная машина 1С.

Раздел «Операции»

Основной код модуля описан в виде потока операций (команд). Каждая команда имеет числовой номер — код операции. Сокращенно его называют ОпКод (OpCode), этот термин можно встретить в специальной литературе. Каждая команда, помимо опкода имеет один числовой аргумент. Трактовка аргумента зависит от опкода. Каждая команда, получая на вход свой аргумент сама принимает решение, что с ним делать. Некоторые команды не имеют аргумента (ничего не делают со своим аргументом). Итак, запомнили, каждая команда — это два числа: опкод и аргумент операции.

Какие же бывают ОпКоды? В машине 1С их 128, но большую часть составляют встроенные функции типа Лев, НачалоКвартала и им подобные. Низкоуровневых операций существенно меньше.

Раздел «Константы»

С константами вообще классно. Любая ЭВМ должна иметь где-то прошитый набор констант, чтобы понимать что один — это один, а ноль — это ноль. В моем военном прошлом я изучал и работал со старой советской ЭВМ и там был даже специальный блок «ЗУ Констант», хранивший побитовые представления основных констант. Т.е. чтобы прибавить к чему-либо единицу, машина должна понимать, а как вообще выглядит единица с точки зрения включенных/выключенных электронных регистров памяти. Помимо единицы и нуля там же хранилась Пи, таблица синусов/косинусов и всякое такое. Полагаю, современные устройства тоже имеют нечто подобное внутри ПЗУ.

Ну это было лирическое отступление. Наша машина хотя и работает поверх железной, тем не менее, тоже нуждается в термине «Константы». Когда вы в коде пишете «А = 2» компилятор 1С записывает эту двойку в специальный раздел модуля. Туда же попадают литералы дат и строк. При выполнении есть специальная команда «Взять константу за номером таким-то и поместить в стек».

Раздел «Переменные»

Операторы языка 1С (как и любого другого языка) оперируют переменными. В переменную можно положить какое-нибудь значение (например константу). Переменные бывают экспортными, локальными и глобальными. Информацию о переменных компилятор также складирует в специальный раздел. Глобальные переменные модуля хранятся в глобальном разделе «Переменные», Каждый метод (процедура или функция) имеет свой отдельный блок переменных, в котором хранятся переменные относящиеся к конкретному методу.

Как кодить-то?

Кодить в такой парадигме довольно увлекательно. По сути — очень похоже на настоящий ассемблер, только вместо регистров — один стек, на который складываютя и из которого вынимаются операнды. Давайте попробуем сложить 2 числа на байткоде 1С.

Запишем в раздел констант числовую константу 2. Она будет иметь номер 0 в списке констант.

Сложение чисел 2 и 2 будет выглядеть следующим образом:

Готово! Следите за руками: Все опкоды, которые кладут что-либо на стек, я по традиции обозначил префиксом Ld от слова «Load». Этой традиции много лет, даже Терминатор в своем будущем соблюдал канон и пользовался этим сокращением в своей прошивке.

Команда LdConst имеет аргумент, который указывает на номер константы в списке констант (мы помним, что там по адресу 0 лежит двойка). Команда смотрит в свой аргумент, достает двойку по заданному адресу и кладет ее в стек. В стеке один элемент — двойка.

Вторая команда делает то же самое, в стеке 2 элемента (и оба — двойки)

Третья команда — это операция сложения. Она не нуждается в аргументе, так как оба ее операнда должны лежать в стеке, но поскольку совсем без аргумента нельзя, то в байткоде у Add будет просто 0. Операция сложения извлекает 2 элемента из стека и складывает их по правилам языка 1С (с учетом типа значения самого левого аргумента).

Результат сложения кладется обратно на стек, таким образом получается как бы «возврат» из функции сложения.

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

Превед, Мир!

По традиции, изучение нового языка или технологии проще всего начать с демонстрационной программы «Hello World».

Откройте обработку «Ассемблер» и на закладке «Процедуры» введите строку следующего содержания:

В поле «Флаги процедуры» можно нажать на кнопку выбора с «калькулятором» и посмотреть, что означают флаги.

Далее, на закладке «Константы и переменные» заведите строку

А теперь, наберите в поле «Операции» следующий код:

и нажмите кнопку «Запустить». Моргнет, фыркнет-пшикнет и результат будет выведен в окно сообщений

А чо это было?

При нажатии кнопки «Запустить» за кадром ваш код был записан в «скобочном формате» и с помощью v8unpack упакован во временную внешнюю обработку. Эта обработка была запущена штатным 1С-овским образом и выдала результат. Полная спецификация байткода доступна по кнопке «Справка по командам» в обработке «Ассемблер». Далее будут рассмотрены основные моменты работы с байткодом.

Работа с переменными
Рассмотрим работу с переменными. Пока пусть будут только глобальные переменные. Вот такой фрагмент кода

При трансляции из него получится следующее: во-первых, в раздел констант попадут константы 8 и 2 в порядке их «встречи» компилятором. Восьмерка получит номер 0, а двойка — номер 1. Далее, в раздел переменных попадут переменные А, Б и М. Опять же номера будут присвоены по порядку попадания в поле зрения компилятора.

Константы

Переменные

Номер Имя Признаки
0 А Глобальная
1 Б Глобальная
2 М Глобальная

Для работы с глобальными переменными используется опкод LdVar. Он помещает на стек переменную с номером, переданным в аргументе команды. Вот код программы, выполняющий указанную логику:

Видите, все довольно просто, хотя, наверняка, возникли вопросы. Например, что делает оператор LineNum? Очень просто, он привязывает байткод к строкам исходного кода, чтобы при возникновении исключения можно было бы выдать номер строки, в которой произошла ошибка. Без этого оператора машина не узнает какой набор опкодов какой строке исходника принадлежит. Кстати, весьма вероятно, что народный способ «писать код в одну строку, чтобы было быстрее» происходит именно отсюда. Если весь код написать в одну строку, то мы сократим число вызовов LineNum. Однако, сопровождение такого кода превращается в ад, и я бы отрывал руки тем, кто так пишет для корпоративного продакшена.

Вызовы методов

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

ОпКод Пояснение
ArgNum Кладет на стек число, показывающее сколько параметров было положено в стек для вызова метода (число переданных параметров)
CallLoc Вызов локальной функции по номеру из таблицы методов
CallProc Вызов метода объекта, как процедуры
CallFunc Вызов метода объекта, как функции (с возвратом значения)
Ret Запоминание результата функции (не на стеке)
LdRet Положить результат последнего метода на стек

Давайте попробуем вызвать метод. Пусть в таблице методов существует запись про метод «МояФункция» с одним параметром. Пусть эта запись имеет номер 0.

Для краткости, я опущу операции LineNum. С помощью обработки «Ассемблер» вы всегда сможете посмотреть в каких местах 1С добавляет этот оператор.

При вызове метода машина снимает со стека число значений, заданное оператором ArgNum. Это число показывает — сколько значений надо снять со стека и распределить по параметрам метода. Эта механика необходима потому, что у нас могут быть необязательные параметры в методах. Тогда при вызове метода с неполным числом параметров машина должна знать, сколько реальных значений засунуто в стек при вызове.

Обработка возвратов

Мы можем вызвать любой метод, как процедуру (игнорируя возвращаемое значение), а можем вызвать, как функцию — присваивая куда-то результат. Вспомним оператор Assign, рассмотренный ранее. Он извлекает из стека 2 аргумента. Чтобы присваивание возвращаемого значения сработало требуется поместить результат функции на стек. Это делает оператор LdRet. При этом, сама функция не знает, будут использовать ее результат или нет. Поэтому компилятор всегда компилирует тело функции одинаково, вызывая оператор Ret, который кладет результат функции в некое временное хранилище. Если значение из этого хранилища извлекут методом LdRet — хорошо. А если нет, значит оно не понадобилось. Просто и элегантно. Я при разработке 1Script не додумался про временное хранилище и мне пришлось городить довольно муторную механику «отброса» неиспользованных результатов Возврата со стека.

Более сложные случаи

Код, выполняющийся линейно, мы разобрали. Давайте посмотрим на ветвления и циклы. Для начала изучим самый простой оператор, обеспечивающий ветвление. Это Jmp. Он просто переводит выполнение на команду, номер которой передан в Jmp аргументом. С помощью джампов можно строить очень запутанный код и декомпиляция его может превратиться в ад. Если вы пишете обфускатор, то не сможете выполнить такую обфускацию, портя код исключительно на уровне исходника 1С. А в байт-коде — сколько душе угодно, была бы фантазия.

Сокращенные вычисления логических выражений

Я думаю, вы знаете, что 1С использует сокращенные вычисления логических выражений. Этот термин означает, что при вычислении выражения «А и Б» выражение Б может вообще не выполняться, если результат А — ложь. Если А = Ложь, то и все «А и Б» равно ложь и нет смысла вычислять Б. Например:

имеются 2 части логического выражения: проверка типа И обращение к свойству. В 1С такая конструкция безопасна именно благодаря сокращенному вычислению. Если тип переменнной не структура, то левая часть И будет равна Ложь, а значит и все выражение будет равно Ложь. Правая часть И вообще не будет выполнена, а значит обращение к свойству «НЕ структуры» не произойдет.

Аналогично с ИЛИ, только наоборот. Если левая часть равна Истина, то правую часть вычислять нет смысла. Для реализации этой логики существуют 2 ОпКода — And и Or соответственно. Аргументом операции идет число, показывающее на какой адрес команды перейти, если сработает сокращенное вычисление.

Например, для «И» если операнд на вершине стека Ложь, то происходит переход по адресу, указанному в аргументе опкода, т.е. пропуск вычисления второго операнда, т.к. от него уже ничего не зависит. Из стека при этом значение не удаляется (результатом операции является Ложь). Иначе, если на вершине стека Истина, из стека удаляется значение и перехода не происходит, т.е. вычисляется второй операнд, результат которого полностью определяет результат всей операции).

Есть еще 2 команды условных переходов: JmpTrue и JmpFalse. Аргументом опкода идет адрес (номер команды), на который надо перейти, а переход выполняется только тогда, когда на стеке находится Истина или Ложь соответственно. Причем, оператор JmpTrue 1С никогда не использует при компиляции исходника. Т.е. декомпилировать байткод, использующий JmpTrue, будет намного сложнее, т.к. в синтаксисе языка 1С отсутствует соответствующая ему конструкция (trollface) Кстати, 1Script тоже никогда не использует JmpTrue и в его байткоде такая операция совсем не предусмотрена.

Условия

Как же выглядят условия? Пусть есть константа 0 со значением 1, пусть есть переменная А с номером 0 и значением 1

Если условие не выполнено — идет переход на конкретный адрес. Если выполнено — просто идет выполнение дальше и заходит в блок условия.

Циклы

Циклов у нас 3 вида: «Пока», «Для… По» и «Для Каждого… Из». Причем для «Пока» вообще не требуется дополнительных опкодов, он целиком реализуется на джампах.

Для цикла «Для… По» используется отдельный стек «временных переменных», который хранит значения, обеспечивающие работу цикла. Так, во временный стек кладется конечное значение итерации цикла, и при каждом проходе текущее значение инкрементируется и сравнивается с временным. Сравнение выполняется оператором Gte (больше-или-равно) и уже знакомым нам JmpFalse если счетчик цикла стал больше или равен конечному значению цикла. Приводить байткод не буду, это домашнее задание для тех кто захочет разобраться с обработкой «Ассемблер».

Цикл с итератором «Для Каждого Из»

С итератором все вообще интересно. Итератор — это такой объект, который отвечает за обход коллекции и выдает очередной ее элемент при вызове условного метода Next()

Для получения итератора используется опкоды Iter, Next и неявная служебная переменная, которую компилятор создает в блоке переменных. Плюс, используется стек временных переменных и… зачем так сложно, я так и не понял, цикл с итератором в 1Скрипт сделан, на мой взгляд, попроще.

Попробуем разобраться. Вот фрагмент кода Внимание, потребуется включить мозг, рекомендуется налить кофе:

Для начала, в блок переменных у нас попадет «Арг» с номером 0, и «Элемент» с номером 1. Потом, внезапно, у нас в блоке переменных появится переменная «0Элемент», которую добавит компилятор. Вам говорили, что имя переменной не может начинаться с цифры? Забудьте, это все вранье 🙂

А что же дальше? Дальше вот что, сначала на стеке временных переменных будет создана новая переменная и размещена в основном стеке:

затем на стек будет помещена итерируемая коллекция (она лежит в переменной 0)

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

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

Мы находимся на адресе 5. Оператор Assign, берет со стека 2 аргумента — временную переменную и объект итератор. Итератор попадает во временную переменную.

Дальше идет последовательность операций:

Следует подробнее остановиться на операторе Next. Он извлекает из итератора очередной элемент и записывает его в переменную, которая была на стеке в этот момент (0Элемент), эта переменная извлекается из стека, а на стек кладется значение Истина, если элемент был получен, или Ложь, если коллекция кончилась. Идущий следом JmpFalse съедает этот флаг и выполняет переход согласно логике цикла.

Наконец-то можно приступить к телу цикла. Адреса 19-23 это тело цикла. Адрес 25 — Jmp на верхушку цикла, адрес 26 и далее — выход из цикла и чистка всех временных сущностей.

Для сравнения, тот же самый код в 1Script выглядит следующим образом:

Имеем 15 операций байткода вместо 37. Такое сравнение нельзя считать корректным, т.к. не столько количество опкодов влияет на скорость, сколько время выполнение каждого конкретного опкода. И нельзя сказать, что циклы 1Script заведомо быстрее циклов 1С. Но байткод получился намного понятнее и прозрачнее.

Хардкор для сильных духом

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

Что такое исключение? Это, в первую очередь, прерывание текущего потока исполнения и переход либо вверх по стеку вызовов, либо в блок «Исключение» оператора «Попытка».

Во-первых стоит разобраться с тем, как 1С выполняет возврат из метода. Она применяет опкод BlckEnd сразу за которым идет Jmp на конец тела метода. По всей видимости, BlckEnd — это какой-то специализированный оператор очистки конца блока. При выходе из тела процедуры аргумент опкода BlckEnd всегда равен 0.

Чуть сложнее обстоит дело с Попыткой. При выходе из блока «Попытка» тоже исполняется операция BlckEnd, но в качестве аргумента передается номер вложенности блока Попытка относительно тела метода.

Разбор конструкции Попытка-Исключение

Блок обработки ошибок открывается опкодом BeginTry, аргументом которого идет адрес начала блока Исключение. Т.е. при возникновении ошибки будет переход на тело обработчика. Далее, идет собственно код тела Попытка, а в его конце будет стоять BlckEnd и Jmp за пределы оператора КонецПопытки;

Рассмотрим байткод для следующего модуля:

байткод

Здесь все довольно прозрачно. Блок Попытка открывается оператором BeginTry и указанием адреса, куда перейти, если вдруг что случится (начало блока Исключение).

Далее идет тело блока (здесь отсутствует), а в конце оператор очистки BlckEnd и прыжок за пределы обработчика ошибок (адреса 2-3). Блок Исключение завершается оператором EndTry.

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

Самая вкуснятина

Ну а как же все это применить на практике? Как создать работоспособную обработку, написанную на чистом байткоде? Для этого, в обработке «Ассемблер» есть кнопка «Сохранить». Она позволяет сохранить в файл image весь код и описания констант-процедур, который вы введете в обработке, а затем с помощью v8unpack собрать готовый epf.

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

Смотрите какая штука: у каждой коллекции есть итератор. Итератор это полноценный объект и размещается в том же самом стеке, что и другие переменные. Это значит, что с ним можно работать как с обычным (не-системным) значением, так ведь? Например, можно цикл «Для Каждого» переделать в примерно такой вариант:

Представьте, что написали обфускатор, который все циклы «Для Каждого» превращает в «Пока-Следующий()». Декомпилировать такой код обратно в синтаксис 1С будет затруднительно, поскольку в синтаксисе 1С в принципе нет конструкций, позволяющих работать с итераторами напрямую!

Давайте проверим эту гипотезу. Откройте обработку «Ассемблер» и в разделе «Переменные» заведите любую переменную. Далее, в разделе константы заведите строковую константу со значением «Массив» — это будет имя типа который нам нужен. А в коде введите следующее:

Код Пояснение Читает со стека Кладет на стек
LdVar 0 загрузили переменную-приемник Переменную
ArgNum 0 в конструктор не будем передавать аргументов (ноль)
New 0 Вызвали конструктор типа, имя которого указано в константе 0 Массив
Assign Присвоили массив в переменную на стеке Правую часть присваивания и левую часть присваивания Ничего
LdVar 0 Кладем на стек переменную с массивом Массив
Iter Получаем итератор Массив Итератор
ТипЗнч проверим тип того, что лежит на стеке аргумент ТипЗнч Тип
ArgNum 1 Число аргументов, которые будем передавать в Сообщить
CallLoc 0 Вызовем процедуру Сообщить Тип
End Корректный выход

А теперь сохранитесь на всякий случай и нажмите кнопку «Запустить». У меня выводится слово «Итератор». Поняли что мы сделали? Мы сделали, чтобы операция «Сообщить(ТипЗнч(М))» выдавало слово «Итератор». Поищите-ка такой тип в синтакс-помощнике. Нету? А он — есть!

Об этой фишке мне рассказал Сергей Батанов (dmpas), я просто пересказал ее здесь, а все респекты за этот трюк должны идти ему 🙂

Disclaimer

Следует отдавать себе отчет в том, что вы действительно работаете на низком уровне системы, в котором не предусматривается присутствие пользователя. Если вы ошибетесь при вводе команд, будете работать не с теми адресами или значениями стека, то клиент 1С у вас будет аварийно завершаться. Это нормально, здесь за вас никто ничего контролировать и перепроверять не будет. Сама обработка «Ассемблер» тоже поставляется в образовательных целях. Она не является универсальным удобным редактором, там довольно мало проверок и подсказок по заполнению таблиц. Мне важно показать саму возможность управления байткодом. Ровно по этой же причине, код внутри обработки «Ассемблер» написан с нарушением почти всех мыслимых стандартов кодирования, просьба это учитывать.

К чему я это все

1С — это сложная и многослойная система и изучать ее — крайне интересно. А чем лучше вы знаете работу своей системы — тем эффективнее можете ее использовать. Сегодня мы рассмотрели, как работает виртуальная машина языка 1С и, надеюсь, расширили наш технический кругозор. Ну и кроме того, получили в свои руки игрушку-конструктор, ведь играться с ассемблером довольно весело!

Источник

Поделиться с друзьями
Компьютеры и приложения