Friday, May 20, 2022

Статьи Криса Касперски

Архив Крис Касперски. Статьи: доредактурные тексты

RISK vs. CISC [К#314/36`99]HTML
Мясной рулет: CISC+RISC+EPIC=MERCED [К#314/36`99]HTML
Хакеры выбирают CISC [К#314/36`99]HTML
Свет в конце туннеля [К#314/36`99]HTML
Кибер-воры не дремлют [К#___/__`00]HTML
Над проблемой соединения ноутбука и десктопа [К#398/21`01]HTML
Wi-Fi своими руками. Долой провода! [M#___/__`05]HTML
Защита беспроводных сетей. Гражданская оборона [M#___/__`05]HTML
Аккумуляторы для мобильных устройств. Питание, которое всегда с тобой [M#___/__`06]HTML
Принципы сжатия видео: "тонкая" настройка MPEG [M#___/__`07]HTML
Фильмы на DVD: оптимизация разрешения и качества. Как распознать подделку? [M#___/__`07]HTML
Глубоководное погружение в чипсет Intel 875P [СА#7/6`03]HTML
Неявный самоконтроль как средство создания неломаемых защит [СА#8/7`03]HTML
Восстановление данных с лазерных дисков [СА#9/8`03]HTML
Рецепты правильного трудоустройства [СА#10/9`03]HTML
Информация, воскресшая из пепла
…Могущество кодов Рида-Соломона [СА#9/8`03]HTML
…Полиномиальная арифметика и поля Галуа [СА#11/10`03]HTML
…Коды Рида-Соломона в практических реализациях [СА#12/11`03]HTML
Искажение TOC как средство борьбы с несанкционированным копированием диска [СА#10/9`03]HTML
Борьба с вирусами. Опыт контртеррористических операций [СА#11/10`03]HTML
Практические советы по восстановлению системы в боевых условиях [СА#13/12`03]HTML
Вирусы в UNIX, или Гибель «Титаника» II [СА#14/1`04]HTML
Жизненный цикл червей [СА#15/2`04]HTML
Ошибки переполнения буфера извне и изнутри как обобщенный опыт реальных атак [СА#16/3`04]HTML [СА#17/4`04]HTML
Побег через брандмауэр плюс терминализация всей NT [СА#18/5`04]HTML
Путь воина – внедрение в PE/COFF-файлы [СА#19/6`04]HTML
Техника внедрения кода в РЕ-файлы и методы его удаления [СА#20/7`04]HTML
Разгон и торможение Windows NT [СА#21/8`04]HTML
Восстановление данных на NTFS-разделах [СА#22/9`04]HTML [СА#23/10`04]HTML
Файловая система NTFS извне и изнутри ([СА#24/11`04]HTML [СА#25/12`04]HTML).preprint
Восстановление NTFS – undelete своими руками [СА#26/1`05]HTML.preprint
Как защищают программное обеспечение [СА#26/1`05]HTML
Unformat для NTFS [СА#27/2`05]HTML.preprint
Восстановление удаленных файлов под Linux [СА#28/3`05]HTML
Техника оптимизации под Linux [СА#27/2`05]HTML [СА#28/3`05]HTML [СА#29/4`05]HTML
Восстанавливаем удаленные файлы под BSD [СА#30/5`05]HTML
Насколько неуязвима ваша беспроводная сеть? [СА#31/6`05]HTML
Модифицируем BIOS [СА#31/6`05]HTML.preprint
Удаленно управляем BIOS Setup [СА#31/6`05]HTML.preprint
CD, не подвластный копированию [СА#33/8`05]HTML.preprint
Как спасти данные, если отказал жесткий диск [СА#34/9`05]HTML
Linux/BSD как бастион на пути вирусов [СА#35/10`05]HTML
Антиотладка: старые приемы на новый лад [СА#35/10`05]HTML.preprint
Судьба shell-кода на системах с неисполняемым стеком [СА#38/1`06]HTML
Можно ли защититься от переполнения буферов? [СА#39/2`06]HTML
Генная инженерия на службе распаковки PE-файлов [СА#42/5`06]HTML
Техника снятия дампа с защищенных приложений [СА#43/6`06]HTML
Волшебство с паяльником в руках [СА#43/6`06]HTML
Аудит и дизассемблирование эксплоитов [СА#45/8`06]HTML
Упаковщики исполняемых файлов в Linux/BSD [СА#46/9`06]HTML
Как обнаружить malware-программы? Универсальный метод [СА#46/9`06]HTML
Как зарабатывают на Open Source [СА#47/10`06]HTML
Многоядерные процессоры и проблемы, ими порождаемые, в ОС семейства NT [СА#47/10`06]HTML
Ошибки синхронизации открывают большие возможности для хакеров [СА#48/11`06]HTML
Как надо и как не надо защищать веб-контент от кражи [СА#49/12`06]HTML
Чего ждать от удаленной работы? [СА#50/1`07]HTML
Потоковое аудио/видеовещание с VideoLAN [СА#63/2`08]HTML
Поиск malware на Server 2003/XP своими руками [СА#64/3`08]HTML
Жучки в электронных письмах [СА#65/4`08]HTML
Бессистемные заметки о поиске работы за рубежом [СА#66/5`08]HTML
Дефекты проектирования Intel Core 2 Duo. Аналитический обзор с точки зрения безопасности [СА#67/6`08]HTML.preprint
Вечно жить не запретишь. Взлом компьютерных игр своими руками [Х#87/3`06]
Побег из VM Ware. Проникновение на основную систему из виртуальной машины [Х#87/3`06]
Системный шпионаж в *NIX. Часть 1. Системно-независимый перехват библиотечных функций [Х#87/3`06]
Компилируем невозможное. Делаем из непойми какого asm-сорца рабочий код [Х#88/4`06]
Жизнь и смерть беспозвоночных в системе. Выживание в системах с жестоким квотированием [Х#89/5`06]
Ловушки для капризных программ. Скрытый потенциал ручных сборок [Х#89/5`06]
Универсальный распаковщик. Разработка универсального распковщика: алгоритм [Х#89/5`06]
IE: всё по-старому [Х#90/6`06]
Посади ELF-файлы на диету! [Х#90/6`06]
Изменяем запретное. Как хакеры CRC16/32 подделывают [Х#90/6`06].preprint
сишные трюки от мыщъх'а .preprints: 01 02 __ 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
Трюки от крыса. Программисткие трюки и фичи на C\C++ от Криса Касперски: [Х#90/6`06] [Х#91/7`06] [Х#93/9`06] [Х#94/10`06] [Х#95/11`06] [Х#96/12`06] [Х#97/1`07] [Х#98/2`07] [Х#99/3`07] [Х#101/5`07] [Х#102/6`07] [Х#103/7`07] [Х#104/8`07] [Х#105/9`07] [Х#106/10`07] [Х#107/11`07] [Х#108/12`07] [Х#109/1`08] [Х#110/2`08] [Х#111/3`08] [Х#112/4`08] [Х#113/5`08] [Х#114/6`08] [Х#116/8`08] [Х#117/9`08] [Х#118/10`08] [Х#119/11`08] [Х#120/12`08] [Х#121/1`08] [Х#122/2`09]
Exploits review. Исследование и взлом закодированных скриптов [Х#91/7`06]
Обзор эксплоитов: [Х#92/8`06] [Х#93/9`06] [Х#94/10`06] [Х#95/11`06] [Х#96/12`06] [Х#97/1`07] [Х#98/2`07] [Х#99/3`07] [Х#101/5`07] [Х#102/6`07] [Х#103/7`07] [Х#104/8`07] [Х#105/9`07] [Х#106/10`07] [Х#107/11`07] [Х#108/12`07] [Х#109/1`08] [Х#110/2`08] [Х#111/3`08] [Х#112/4`08] [Х#113/5`08] [Х#114/6`08] [Х#115/7`08] [Х#116/8`08] [Х#117/9`08] [Х#118/10`08] [Х#119/11`08] [Х#120/12`08] [Х#121/1`09]
Пультом по телеку [Х#91/7`06]
Ядерные шалости. Хак ядра NT [Х#91/7`06]
Мастерская бравого хакера. Заточи эксплоит под себя! [Х#91/7`06]
Экстремальная оптимизация. Хитрости низкоуровневого программинга для самых маленьких [Х#91/7`06].preprint
Защищенная ось без антивирусов и тормозов [Х#92/8`06].preprint
Техника промышленного шпионажа [Х#92/8`06]
Как сокрушают протекторы [Х#92/8`06]
Битва трансляторов [Х#92/8`06].preprint
Недетский трюк от Криса [Х#92/8`06]
Антивирус на помойку [Х#92/8`06]
Подъем рухнувшей NT [Х#93/9`06]
Online patching в секретах и советах. Побеждаем упакованный код [Х#93/9`06]
Погружение в технику и философию gdb. Взлом программ с помощью gdb [Х#93/9`06]
Жесткий кодинг. Программирование компьютерного железа [Х#93/9`06]
Чемоданчик хакера. Какие программы и когда нужно использовать [Х#94/10`06]
Файрвол тебя не спасет [Х#94/10`06]
Голая правда о Webmoney. Чем опасен WM-клиент [Х#94/10`06]
Сношения с Идой [Х#94/10`06]
Прощай, тормоза! Как запустить виртуальную машину без тормозов [Х#95/11`06]
Зверский взлом Windows Vista. Совершенные руткиты готовы атаковать новую винду [Х#95/11`06]
Покорение вершин отладки [Х#95/11`06]
Жажда скорости. Экстремальный разгон процессора [Х#95/11`06].preprint
На службе у капитана Флинта. Правильный DVD-Rip своими руками [Х#96/12`06]
Безопасный web-серфинг. Горькая правда о популярных браузерах [Х#96/12`06]
Пиратские забавы. Как правильно создать DVD-Rip своими руками [Х#97/1`07]
Обманчивый антивирус. Любовь с эвристикой в непристойных позах [Х#97/1`07].preprint
Обман IDS. Обход интеллектуальных систем защиты [Х#97/1`07]
Хардкорная отладка с Lince. Учимся работать в консольном отладчике ядра, аналоге SoftICE [Х#97/1`07]
OBJ'ектный пазл. Линковка дизассемблерных файлов [Х#97/1`07]
Английский с турбонаддувом. Хакерский подход к изучению иностранного языка [Х#98/2`07]
Жизнь после Soft-Ice. Отладчик WinDbg как API- и RPC-шпион [Х#98/2`07]
Призраки ядра, или модулиневидимки. Создание LKM-модулей, которые невозможно обнаружить [Х#98/2`07]
Королевство кривых RAID-зеркал. Все, что ты хотел знать о RAID-массивах, но боялся спросить [Х#98/2`07]
Колем дрова без помощи топора. Как найти и обезвредить в системе глючные девайсы и драйверы [Х#99/3`07]
Вскрываем DVD. Как сломать DVD-диск без помощи топора [Х#99/3`07]
Параллельные миры: война на выживание. Вторжение в чужое адресное пространство и защита от него [Х#99/3`07]
Держи все под контролем! Неограниченные возможности удаленного администрирования по доступной цене [Х#99/3`07]
Суперклей от «Хакера». Новый способ склеить два исполняемых файла [Х#101/5`07]
У Google под колпаком! Шпионская вкладка XXI век [Х#101/5`07]
Трепанация закрытых программ. Реверсинг бинарных модулей без сорцов [Х#101/5`07]
Чудеса селекционной работы. Стратегия выбора материнской платы и жестких дисков для сервера [Х#101/5`07]
Руткитам — бой! Поиск вирусов своими руками [Х#102/6`07]
Активируй ее! Хакерская активация Висты [Х#102/6`07]
Top 10 ошибок конфигурации *nix. 10 самых распространенных ошибок конфигураций Linux и xBSD [Х#102/6`07]
Хакерские приемы на службе у админа. Накладывание обновлений на серверы windows и *nix без перезагрузки [Х#102/6`07]
Бесшумный сервер своими руками. Решаем проблему снижения шума на домашнем сервере [Х#102/6`07]
Противостояние с малварью продолжается. Боремся с продвинутыми руткитами вручную [Х#103/7`07]
Беспредельный спам. NDR-атаки — проблемы и решения [Х#103/7`07]
Бескомпромиссный разбор дампов памяти. Поиск и добыча коры в заповедном лесу Linux и xBSD [Х#103/7`07].preprint
Рецепты правильного питания. Советы по доработке дешевых блоков питания [Х#103/7`07]
Одна голова хорошо, а две лучше. Грамотное использование двух компьютеров дома [Х#104/8`07]
Хроника внедрений в автозагрузку. Скрытые ключи автозапуска в системном реестре [Х#104/8`07]
Предательский антивирус. Тыбрим данные с flash-модулей и CD/DVD [Х#104/8`07]
NTFS: учимся читать и писать. Обеспечиваем полный доступ к NTFS-разделам под Linux/BSD [Х#104/8`07].preprint
Секреты турбореактивного полета. Тонкая настройка параметров TCP/IP под толстые каналы [Х#104/8`07]
Взлом без хакера. Автоматический пен-тестинг на пальцах [Х#105/9`07]
Почему не файрволят файрволы. Ошибки конфигурации персональных брандмауэров [Х#105/9`07]
Мобильное укрощение. Основы взлома мобильных игр [Х#105/9`07]
Прячем трафик от админов. Техника сокрытия IP-трафика с помощью секретных пассивных каналов [Х#105/9`07]
Тайные рычаги подсознания. Методы психовизуальной атаки [Х#105/9`07]
Операция по освобождению. Борьба с утечками ресурсов в реальном времени без перекомпиляции серверных приложений [Х#105/9`07]
Злорадства DNS-сервера. Хитрый способ перехвата паролей в локальных сетях [Х#106/10`07]
Компиляция на форсаже с турбонаддувом. Изучаем ключи оптимизации компилятора GCC [Х#106/10`07]
Охота за 25‑м кадром. Исследуем миф, воплощенный в реальность [Х#106/10`07].preprint
Win2k3: армированная установка на стероидах. Поднимаем капитальный сервер на базе Windows Server 2003 за 7 шагов [Х#106/10`07]
Реставрируем окна. Восстановление Windows Server 2003 после тяжелых ранений [Х#106/10`07]
Чего ждать от Windows 2008. Обзор новой серверной операционной системы от Microsoft [Х#107/11`07]
Покоряем games.mail.ru. Взлом всех игрушек за 3 минуты [Х#107/11`07]
Вторжение в ядро Висты. Все о внутренних атаках в модной OS [Х#107/11`07]
Ядерная физика для начинающих. Обзор никсовых отладчиков ядерного уровня [Х#107/11`07]
Возможные невозможные фигуры. Ломаем иллюзорные диагонали психологии зрительного восприятия «Рисовать — значит обманывать» (Морис Корнелис Эшер) [Х#107/11`07]
Поставь сервер на счетчик. Изучаем приборную панель производительности Windows Server 2003 [Х#107/11`07]
Вся правда о динамических дисках. Рассматриваем одну из ключевых возможностей системы управления дисками в Windows Server 2003 [Х#107/11`07]
Кряк без дизассемблера. Универсальный взлом триальных программ [Х#108/12`07]
Взлом Борландии. Изящная декомпиляция Delphi [Х#108/12`07].preprint
Атакуем кучу в xBSD. Техника переполнения кучи в Free/Net/OpenBSD [Х#108/12`07].preprint
Путешествие в зачарованный мир. Греческий сон hypnos: правда, мифы и разоблачения [Х#108/12`07]
Палим руткиты в никсах и Винде. Ручной поиск руткитов в Linux/xBSD и NT [Х#108/12`07]
Как позаботиться о реестре. Ускоряем работу системы за счет дефрагментации реестра [Х#109/1`08]
Бронежилет для файрвола. Как защитить свой файрвол и антивирус от набега малвари [Х#109/1`08]
Кража со взломом. Как скопировать установленную программу [Х#109/1`08]
Сырость не радость. Реализация сырых сокетов в WinNT [Х#109/1`08]
Вооружаем и разоружаем DVD-плееры [Х#109/1`08]
Реклама в сумеречной зоне подсознания. Как не попасть на рекламный крючок [Х#109/1`08]
Пен-тестинг по обе стороны сервера. Тесты на проникновение: советы практикующим админам и хакерам [Х#109/1`08]
HexRays — декомпилятор нового поколения. Превращаем любой бинарник в C-код [Х#110/2`08]
Пять козырных трюков спамеров. Уловки спамеров и методы борьбы с ними [Х#110/2`08]
Бунт машин и восстание червей. Парад багов в популярных браузерах [Х#110/2`08].preprint
Битва за улучшение видеоряда. Повышаем качество проблемных видеофайлов в реалтайме с помощью mplayer [Х#110/2`08]
На облаках RAID-массива. Подъем RAID’ов с аппаратно-программной глубины на операционную поверхность [Х#110/2`08]
Диски под замком. Как предотвратить непреднамеренный доступ к жестким дискам [Х#111/3`08]
Vista vs несовместимость. Новая жизнь старого софта [Х#111/3`08]
Энциклопедия антиотладочных приемов:
…Все антиотлаочные приемы для NT- и UNIX-подобных систем на х86 [Х#111/3`08].preprint
…Трассировка или игры в прятки [Х#112/4`08].preprint
…Трассировка — в погоне на TF или SEH на виражах [Х#114/6`08].preprint
…Обработка необрабатываемых исключений [Х#115/7`08].preprint
…Самотрассировка и прочие головоломки [Х#116/8`08].preprint
…Исчерпывающее руководство по приготовлению и взлому TLS [Х#118/10`08].preprint
…Кто сломал мой бряк?! [Х#119/11`08].preprint
…Скрытая установка SEH-обработчиков [Х#120/12`08].preprint
…Сокрытие кода в хвостах секций [Х#121/1`09]
Мажорный тукс на мобильных просторах. Хачим сотовые телефоны с LINUX на борту [Х#111/3`08]
Охота на сетевых партизан. Методы обнаружения (ре)трансляторов сетевых адресов и их клиентов [Х#111/3`08]
Нам не страшен синий BSOD. Новые способы борьбы с голубым экраном смерти [Х#112/4`08]
Рецепты недетского похудания. Как урезать дистрибутивы и сделать приложения портируемыми [Х#112/4`08]
Архитектурный взлом. MSR-регистры на службе хакера [Х#112/4`08]
Погружение в файловые дыры. Захватываем чужие данные через дыры в файловых системах [Х#112/4`08]
Китовый набор для админа. Изучаем возможности miсrosoft windows Server 2003 resource kit tools [Х#112/4`08]
Большие проблемы маленьих серверов. Из личного опыта администрирования домашнего сервера [Х#112/4`08]
Азартные игры (под)сознания. Разрываем цепи спекулятивных заключений сознания [Х#112/4`08]
Тотальный антивирус. Универсальный антивирусный центр своими руками [Х#113/5`08]
Раскрываем код. Дизассемблирование C# программ от A до Z [Х#113/5`08].preprint
Жизнь сервера без BSOD. Скрытые рычаги управления ядром WINDOWS SERVER 2003 [Х#113/5`08]
Депривация: над пропастью сновидений. Филигранная техника трансформации сна [Х#113/5`08]
Новые приключения Olly’ки. Обзор неофициальных сборок отладчика OllyDbg [Х#114/6`08]
Наведение порядка в хаосе атак. Ноу-хау в ошибках переполнения [Х#114/6`08]
Битва за видео-престол. Сравнительный анализ качества драйверов от ATI, Matrox и NVIDIA [Х#114/6`08]
Десять линий обороны. Топ-10 ошибок администрирования Windows SERVER 2003/2008 [Х#114/6`08]
Снифинг в боевых условиях. Intercepter — разнюхает все! [Х#115/7`08]
В поисках шапки-невидимки. Обнаружение компрометации ядер Linux и xBSD, или Руткиты тоже оставляют следы… [Х#115/7`08]
Охота за призраками бутылочного горлышка. Сеанс термоядерной отладки для админов [Х#115/7`08]
Обучение сну, обучение во сне. Познаем секреты оптимизации нейросетей [Х#115/7`08]
Новая ветвь обороны. Активная защита против вирусов [Х#116/8`08]
Добрый скальпель хакера. Чем нас порадовал свежий релиз дизассемблера IDA Pro [Х#116/8`08]
Хакерим за бугром. Прикладные аспекты коммерческого взлома [Х#116/8`08]
Серые кардиналы магистральных каналов. Преодолеваем аппаратные антивирусы [Х#116/8`08]
Бескомпромиссный тюнинг NTFS Скрытые рычаги управления файловой системой семейства ОС Windows NT [Х#116/8`08]
Прерванный полет сознания. Дежавю — там, где причина и следствие меняются местами [Х#116/8`08]
Rustock.C — секретные техники анализа. Мировой руткит под микроскопом [Х#117/9`08]
Положи DNS на лопатки. Новый вектор атаки на никсовые DNS-сервера [Х#117/9`08]
Моем файлы чисто-чисто. Поднимаем идеальный файловый сервер [Х#117/9`08]
Обмани себя сам — иллюзии в океане безумия. Нить ариадны в лабиринте оптических иллюзий [Х#117/9`08]
Осенний сбор дыр в IE. Неинициализированные указатели под прицелом [Х#118/10`08]
Властелин виртуальных машин. Практические советы по развертыванию виртуальной инфраструктуры [Х#118/10`08]
Малварь нового поколения. Исследование совершенной заразы [Х#119/11`08]
DR-руткит: хороший заложник плохой идеи [Х#119/11`08]
Psycho: На рекламной игле. Репрессированные жертвы рекламы, или как нас разводят на бабки [Х#120/12`08]

два компьютера – один монитор, два монитора – один компьютер .prereprint
три истории из жизни пен-тестера: проникновение внутрь охраняемого периметра корпоративных сетей .prereprint
подсчет совокупной стоимости перехода на Висту в рамкой мелкой компании и крупной корпорации .prereprint
ядерно-нуклонная смесь или чем отличается XP от 9х .prereprint
жизнь после BSOD .prereprint
весь крис касперски .prereprint
ночь живых мертвецов — активная защита против малвари .prereprint
помоги себе сам или обзор Anti-Spy.info .prereprint
ремонт, обслуживание и эксплуатация APC UPS .prereprint
как хакнуть азиатку .prereprint
кардинг по новому .prereprint
Экстремальный разгон XP .prereprint
ручная троянизация приложений под windows .prereprint
MBR своими руками .prereprint
захват и освобождение заложников в исполняемых файлов .prereprint
ассемблерные головоломки или может ли машина понимать естественный язык? .prereprint
ассемблирование без секретов .prereprint
ассемблерные извращения — натягиваем стек (черновик) .prereprint
война миров: ассемблер против си .prereprint
антивирусы в корпоративной среде .prereprint
как обмануть антивирус? .prereprint
армирование антивирусов и брандмауэров .prereprint
экономика резервирования данных .prereprint
выбор носителей для резервирования .prereprint
сидя на голом железе .prereprint
легенды и мифы прошивки BIOS .prereprint
BIOS-моддинг .prereprint
алхимия прошивки видео-BIOS .prereprint
blue pill/red pill — the matrix has windows longhorn .prereprint
охота за Голубым Зубом .prereprint
захват чужих ботнетов .prereprint
особенности печати в Linux принтерами фирмы Brother .prereprint
управление печатающими устройствами программным обеспечением фирмы brother .prereprint
переполнение буферов как средство борьбы с мега корпорациями .prereprint
войны юрского периода II – черви возвращаются .prereprint
спецификаторы под арестом или дерни printf за хвост .prereprint
техника написания переносимого shell-кода .prereprint
SEH на службе контрреволюции .prereprint
ultimate adventure или поиск дыр в двоичном коде .prereprint
защита от копирования, основанная на физических дефектах .prereprint
ремонт CD/DVD приводов в домашних условиях .prereprint
завоевание Интернета или кто сказал "мяу" .prereprint
знакомство с багами или ошибки клиентских приложений .prereprint
малоизвестные способы взлома клиент. программ или stealth-patching своими руками .prereprint
секреты командного интерпретатора .prereprint
работа в команде — пособие по выживанию .prereprint
взлом через покрытие .prereprint
crackme, прячущий код на API-функциях .prereprint
проблемы создания CRM-систем: взгляд изнутри .prereprint
как избежать катастрофы? .prereprint

Tuesday, April 9, 2019

flat assembler g. Введение и обзор


ENtoRU перевод flat assembler g. Introduction and Overview (update 08 Apr 2019)
(неоконченная версия) последняя правка 30.04.2019

Введение в flat assembler g, которое объясняет назначение этого программного механизма и демонстрирует, как создать ассемблер для конкретной архитектуры ЦП с помощью макроинструкций.

Что такое flat assembler g?

Это программный механизм для сборки программ, разработанный как преемник используемого в flat assembler 1, одном из признанных ассемблеров для процессоров x86. Это голый "движок", который сам по себе не способен распознавать и кодировать инструкции какого-либо процессора, однако он способен стать ассемблером для архитектуры любого ЦП. Он имеет язык макроинструкций, который значительно улучшен по сравнению с языком, предоставляемым flat assembler 1, и позволяет легко реализовывать кодировщики инструкций в форме настраиваемых макроинструкций. Этот подход имеет большую гибкостью за счёт уменьшения производительности.
Если бы случилось так, что требовалась бы очень быстрая сборка, сопоставимая с flat assembler 1, и недостаток макроинструкций в производительности был бы неприемлем, то можно было бы решить эту проблему путем создания пользовательского ассемблера на основе этого механизма, и полный исходный код был бы доступен для любой, кто хотел бы попробовать это. Но основное внимание в этом пакете уделяется использованию плоского ассемблера g в чистом виде.

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

Макроинструкции, которые обрабатывают синтаксис инструкций x86, сложны и требуют много времени для сборки, но, между прочим, время, которое требуется плоскому ассемблеру g для компиляции на обычной современной машине, сопоставимо со временем, когда ранняя версия плоского ассемблера 1 Нужно было собрать полтора десятилетия назад на компьютере, который тогда был таким же посредственным. Это можно рассматривать как интересную демонстрацию того, как программное обеспечение может работать медленнее с той же скоростью, с какой аппаратное обеспечение становится быстрее.

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

Чтобы продемонстрировать, как могут быть реализованы наборы команд разных архитектур, есть несколько примеров программ для микроконтроллеров, 8051 и AVR. Они были простыми и, следовательно, они не обеспечивают полную основу для программирования таких процессоров, хотя они могут обеспечить прочную основу для создания таких сред.

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

Как это работает?
Основная функция плоского ассемблера g - генерировать выходные данные, определенные инструкциями в исходном коде. Учитывая одну строку текста, как показано ниже, ассемблер сгенерирует один байт с указанным значением:
db 90h
Макроинструкции могут быть определены для генерации некоторых конкретных последовательностей данных в зависимости от предоставленных параметров. Они могут соответствовать инструкциям выбранного машинного языка, как в следующем примере, но они также могут быть определены для генерирования других видов данных для различных целей.
macro int number
  if number = 3
    db 0CCh
  else
    db 0CDh, number
  end if
end macro

int 20h         ; generates two bytes
Сборка, рассматриваемая таким образом, может рассматриваться как некий интерпретируемый язык, и ассемблер, безусловно, обладает многими характеристиками интерпретатора. Однако он также разделяет некоторые аспекты с компилятором. Для инструкции возможно использовать значение, которое определено позже в источнике и может зависеть от инструкций, предшествующих этому определению, как показано в следующем примере.
macro jmpi target
  if target-($+2) < 80h & target-($+2) >= -80h                    
    db 0EBh
    db target-($+1)
  else
    db 0E9h
    dw target-($+2)
  end if 
end macro

  jmpi start  
  db 'some data'  
start:
Определенный выше «jmpi» создает код инструкции перехода, как в архитектуре 8086. Такой код содержит относительное смещение цели перехода, хранящееся либо в однобайтовом, либо в 16-битном слове. Относительное смещение вычисляется как разница между адресом цели и адресом следующей инструкции. Специальный символ «$» предоставляет адрес текущей инструкции, и он используется для вычисления относительного смещения и определения, может ли оно поместиться в один байт.

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

Поиск решения для таких круговых зависимостей может напоминать решение уравнения, и даже возможно построить пример, где плоский ассемблер g действительно способен решить одну:
x = (x-1)*(x+2)/2-2*(x+1)
db x
Циркулярная ссылка здесь сведена к единственному определению, которое ссылается на себя для построения значения. Плоский ассемблер g может найти решение в этом случае, хотя во многих других он может потерпеть неудачу. Метод, используемый этим ассемблером, состоит в том, чтобы выполнить несколько проходов по исходному тексту, а затем попытаться предсказать все значения с помощью знаний, собранных таким образом. Этот подход в большинстве случаев достаточно хорош для сборки машинных кодов, но редко бывает достаточно для решения сложных уравнений, и приведенный выше пример является одним из исключений.

Каковы средства анализа аргументов инструкции?
Не все инструкции имеют простой синтаксис, как в предыдущих примерах. Чтобы помочь в обработке аргументов, которые могут содержать специальные конструкции, плоский ассемблер g предоставляет несколько способных инструментов, продемонстрированных ниже на примерах, которые реализуют несколько отдельных инструкций процессора Z80. Правила использования представленных функций приведены в руководстве.

Когда инструкция имеет очень небольшой набор разрешенных аргументов, каждый из них может обрабатываться отдельно с помощью конструкции «match»:
macro EX? first,second
  match (=SP?), first
    match =HL?, second
      db 0E3h
    else match =IX?, second
      db 0DDh,0E3h
    else match =IY?, second
      db 0FDh,0E3h
    else
      err "incorrect second argument"
    end match
  else match =AF?, first
    match =AF'?, second
      db 08h
    else
      err "incorrect second argument"
    end match
  else match =DE?, first
    match =HL?, second
      db 0EBh
    else
      err "incorrect second argument"
    end match
  else
    err "incorrect first argument"
  end match
end macro

EX (SP),HL
EX (SP),IX
EX AF,AF'
EX DE,HL
"?" символ появляется во многих местах, чтобы пометить имена как нечувствительные к регистру, и все эти вхождения могут быть удалены, чтобы еще больше упростить пример.

Когда набор возможных значений аргумента больше, но имеет некоторые закономерности, можно определить текстовые замены, чтобы заменить некоторые символы тщательно подобранными конструкциями, которые затем могут быть распознаны и проанализированы:
A? equ [:111b:]
B? equ [:000b:]
C? equ [:001b:]
D? equ [:010b:]
E? equ [:011b:]
H? equ [:100b:]
L? equ [:101b:]

macro INC? argument
  match [:r:], argument
    db 100b + r shl 3
  else match (=HL?), argument
    db 34h
  else match (=IX?+d), argument
    db 0DDh,34h,d
  else match (=IY?+d), argument
    db 0FDh,34h,d
  else
    err "incorrect argument"
  end match
end macro

INC A
INC B
INC (HL)
INC (IX+2)
Этот подход имеет черту, которая не всегда может быть желательной: он позволяет использовать выражение типа «[: 0:]» непосредственно в аргументе. Но можно предотвратить использование синтаксиса таким образом, используя префикс в конструкции «match»:
REG.A? equ [:111b:]
REG.B? equ [:000b:]
REG.C? equ [:001b:]
REG.D? equ [:010b:]
REG.E? equ [:011b:]
REG.H? equ [:100b:]
REG.L? equ [:101b:]

macro INC? argument
  match [:r:], REG.argument
    db 100b + r shl 3
  else match (=HL?), argument
    db 34h
  else match (=IX?+d), argument
    db 0DDh,34h,d
  else match (=IY?+d), argument
    db 0FDh,34h,d
  else
    err "incorrect argument"
  end match
end macro
В случае аргумента, структурированного как «(IX + d)», иногда может потребоваться разрешить другие алгебраически эквивалентные формы выражения, например «(d + IX)» или «(c + IX + d)». Вместо того, чтобы анализировать каждый возможный вариант по отдельности, можно позволить ассемблеру оценивать выражение, одновременно обрабатывая выбранный символ. Когда символ объявляется как «элемент», он не имеет значения, а когда он используется в выражении, он рассматривается алгебраически как переменный член в полиноме.
элемент HL?
element HL?
element IX? 
element IY? 

macro INC? argument
  match [:r:], argument
    db 100b + r shl 3
  else match (a), argument
    if a eq HL
      db 34h
    else if a relativeto IX
      db 0DDh,34h,a-IX
    else if a relativeto IY
      db 0FDh,34h,a-IY
    else
      err "incorrect argument"
    end if
  else
    err "incorrect argument"
  end match
end macro

INC (3*8+IX+1)

virtual at IX
  x db ?
  y db ?
end virtual        

INC (y)
Существует небольшая проблема с вышеуказанной макроинструкцией. Параметр может содержать любой текст, и когда такое значение помещается в выражение, оно может вызвать ошибочное поведение. Например, если обработать «INC (1 | 0)», выражение «a eq HL» будет преобразовано в «1 | 0 eq HL», и это логическое выражение будет правильным и истинным, даже если аргумент был искажен. Чтобы этого не происходило, в качестве прокси-сервера может использоваться локальная переменная, содержащая значение аргумента:
macro INC? argument
  match [:r:], argument
    db 100b + r shl 3
  else match (a), argument
    local value
    value = a
    if value eq HL
      db 34h
    else if value relativeto IX
      db 0DDh,34h,a-IX
    else if value relativeto IY
      db 0FDh,34h,a-IY
    else
      err "incorrect argument"
    end if
  else
    err "incorrect argument"
  end match
end macro
У такой прокси-переменной есть дополнительное преимущество благодаря тому, что ее значение вычисляется до того, как макроинструкция начнет генерировать какой-либо вывод. Когда выражение содержит символ, такой как «$», оно может давать разные значения в зависимости от того, где оно вычисляется, и использование прокси-переменной гарантирует, что полученное значение будет тем, которое получено путем оценки аргумента перед генерацией кода инструкции.

Когда набор символов, разрешенных в выражениях, больше, лучше иметь единую конструкцию для обработки всего их семейства. Объявление «элемента» может ассоциировать дополнительное значение с символом, и эта информация затем может быть получена с помощью оператора «метаданных», примененного к линейному полиному, который содержит данный символ в качестве переменной. Следующий пример - еще один вариант предыдущей макроинструкции, демонстрирующий использование этой функции:
element register
element A? : register + 111b
element B? : register + 000b
element C? : register + 001b
element D? : register + 010b
element E? : register + 011b
element H? : register + 100b
element L? : register + 101b

element HL?
element IX? 
element IY? 

macro INC? argument
  local value
  match (a), argument
    value = a
    if value eq HL
      db 34h
    else if value relativeto IX
      db 0DDh,34h,a-IX
    else if value relativeto IY
      db 0FDh,34h,a-IY
    else
      err "incorrect argument"
    end if
  else match any more, argument
    err "incorrect argument"
  else
    value = argument
    if value eq value element 1 & value metadata 1 relativeto register
      db 100b + (value metadata 1 - register) shl 3
    else
      err "incorrect argument"
    end if
  end match
end macro
Паттерн «any more» предназначен для перехвата любого аргумента, который содержит сложные выражения, состоящие из более чем одного токена. Это предотвращает использование синтаксиса, такого как «INC A + 0» или «INC A + B-A». Но в случае некоторых наборов инструкций включение такого ограничения может зависеть от личных предпочтений.
Условие «value eq value element 1» гарантирует, что значение не содержит никаких терминов, кроме имени регистра. Даже если аргумент вынужден содержать не более одного токена, все же возможно, что он имеет комплексное значение, например, если были такие определения, как «X = A + B» или «Y = 2 * A». И «INC X», и «INC Y» затем заставят оператор «элемент 1» возвращать значение «A», которое отличается от значения, проверенного в любом случае.

Если инструкция принимает переменное число аргументов, простой способ распознать ее различные формы - объявить аргумент с модификатором «&» для передачи полного содержимого аргументов в «match»:
element CC
        
NZ? := CC + 000b
Z?  := CC + 001b
NC? := CC + 010b
C?  := CC + 011b
PO  := CC + 100b
PE  := CC + 101b
P   := CC + 110b
M   := CC + 111b   

macro CALL? arguments&
  local cc,nn
  match condition =, target, arguments
    cc = condition - CC
    nn = target
    db 0C4h + cc shl 3
  else
    nn = arguments
    db 0CDh                     
  end match
  dw nn
end macro

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

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

В некоторых вариантах ассемблера может быть желательно разрешить метке предшествовать инструкции без дополнительного символа ":" между ними. Затем необходимо создать помеченную макроинструкцию, которая после определения метки передает обработку исходной макроинструкции с тем же именем:
struc INC? argument
  .:
  INC argument
end struc

start   INC A
        INC B

iterate instruction, EX,INC,CALL
  struc instruction? argument
    .: instruction argument
  end struc
end iterate
Это должно быть сделано для каждой инструкции, которая должна разрешить такой синтаксис. Достаточно простого цикла, подобного следующему:
struc ? tail&
  match :, tail 
    .: 
  else match : instruction, tail
    .: instruction
  else match == value, tail
    . = value
  else 
    .: tail
  end match 
end struc
Каждая встроенная инструкция, которая определяет данные, уже имеет помеченный вариант.

Определяя помеченную инструкцию, которая имеет "?" вместо имени можно перехватить каждую строку, которая начинается с идентификатора, который не является известной инструкцией и поэтому считается меткой. Следующий позволяет метке без «:» начинать любую строку в исходном тексте (он также обрабатывает особые случаи, чтобы после меток следовали «:» или «=» и значение все равно работало):
struc ? tail&
  match :, tail 
    label . at $ shr 1
  else match : instruction, tail
    label . at $ shr 1
    instruction
  else
    . tail
  end match
end struc
Очевидно, что больше не требуется определять какие-либо конкретные помеченные макроинструкции, когда применяется глобальный эффект такого рода. Вариант должен быть выбран в зависимости от типа синтаксиса, который должен быть разрешен.

Перехват даже меток, определенных с помощью «:», может стать полезным, когда значение текущего адреса требует некоторой дополнительной обработки перед назначением метке - например, когда процессор использует адреса с единицей больше, чем байт. Перехватывающая макроинструкция может выглядеть так:
element CODEBASE
org CODEBASE + 0

macro CALL? argument
  local value
  value = argument
  if value relativeto CODEBASE
    db 0CDh
    dw value - CODEBASE
  else
    err "incorrect argument"
  end if 
end macro
Значение текущего адреса, которое используется для определения меток, может быть изменено с помощью «org». Если метки необходимо отличать от абсолютных значений, символ, определенный с помощью «элемента», может использоваться для формирования адреса:
element DATA
DATA_OFFSET = 2000h
element CODE
CODE_OFFSET = 1000h

macro DATA?
  _END
  virtual at DATA + DATA_OFFSET
end macro

macro CODE?
  _END
  org CODE + CODE_OFFSET
end macro

macro _END?
  if $ relativeto DATA
    DATA_OFFSET = $ - DATA
    end virtual
  else if $ relativeto CODE
    CODE_OFFSET = $ - CODE
  end if
end macro

postpone
  _END
end postpone

CODE
Чтобы определить метки в адресном пространстве, которое не будет отражено в выводе, должен быть объявлен «виртуальный» блок. Следующий пример подготавливает макроинструкции «ДАННЫЕ» и «КОД» для переключения между генерацией программных инструкций и меток данных. Только коды команд будут отправлены на выход:
macro CALL? argument
  local value
  value = argument
  if value relativeto CODE
    db 0CDh
    dw value - CODE
  else if value relativeto 0
    db 0CDh
    dw value
  else
    err "incorrect argument"
  end if 
end macro

DATA

variable db ?

CODE

routine:
Блок «отложить» используется здесь, чтобы гарантировать, что «виртуальный» блок всегда закрывается правильно, даже если исходный текст заканчивается определениями данных.
В среде, подготовленной вышеупомянутым образцом, любая инструкция сможет отличить метки данных от меток, определенных в программе. Например, можно выполнить инструкцию ветвления, чтобы принять аргумент, являющийся либо меткой в ​​программе, либо абсолютным значением, но запретить любую метку данных:
virtual at 0
  Relocations::
  rw RELOCATION_COUNT
end virtual

RELOCATION_INDEX = 0

postpone
  RELOCATION_COUNT := RELOCATION_INDEX                
end postpone

macro WORD? value
  if value relativeto CODE
    store $ - CODE : 2 at Relocations : RELOCATION_INDEX shl 1
    RELOCATION_INDEX = RELOCATION_INDEX + 1
    dw value - CODE
  else
    dw value
  end if
end macro 

macro CALL? argument
  local value
  value = argument
  if value relativeto CODE | value relativeto 0
    db 0CDh
    word value
  else
    err "incorrect argument"
  end if 
end macro
В этом контексте «CALL рутина» или «CALL 1000h» будет разрешено, а «CALL variable» не будет.

Когда метки имеют значения, которые не являются абсолютными числами, можно генерировать перемещения для инструкций, которые их используют. Специальный «виртуальный» блок может использоваться для хранения смещений значений внутри программы, которые необходимо переместить при изменении ее базы:
load RELOCATIONS : RELOCATION_COUNT shl 1 from Relocations : 0
dw RELOCATIONS
Таблица перемещений, созданная таким образом, может быть доступна с помощью «load». Следующие две строки могут быть использованы для размещения таблицы целиком где-то в выводе:
element MOD.HIGH
element MOD.LOW

HIGH? equ MOD.HIGH +
LOW? equ MOD.LOW +

macro BYTE? value
  if value relativeto MOD.HIGH + CODE
    ; register HIGH relocation
    db (value - MOD.HIGH - CODE) shr 8
  else if value relativeto MOD.LOW + CODE
    ; register LOW relocation
    db (value - MOD.LOW - CODE) and 0FFh
  else if value relativeto MOD.HIGH
    db (value - MOD.HIGH) shr 8
  else if value relativeto MOD.LOW
    db (value - MOD.LOW) and 0FFh
  else
    db value
  end if
end macro
«Load» считывает всю таблицу в одну строку, а затем «dw» записывает ее в вывод (дополняемый несколькими словами, но в этом случае строка никогда не требует такого дополнения).

Для более сложных типов перемещений может потребоваться дополнительный модификатор. Например, если верхнюю и нижнюю части адреса необходимо хранить в отдельных местах (например, в двух инструкциях) и перемещать отдельно, необходимые модификаторы могут быть реализованы следующим образом:
BYTE HIGH address
BYTE LOW address
Команды, которые регистрировали бы перемещение, были опущены для ясности, в этом случае не только смещение в коде, но и некоторая дополнительная информация должна была бы быть зарегистрирована в соответствующих структурах. С такой подготовкой перемещаемые блоки в коде могут быть сгенерированы как:
include '8086.inc'
org     100h
jmp     CodeSection

DataSection:

  virtual
    Data::
  end virtual

  postpone
    virtual Data
      load Data.OctetString : $ - $$ from $$
    end virtual
  end postpone

  db Data.OctetString

CodeSection:

  virtual Data
    Hello db "Hello!",24h
  end virtual

  mov     ah,9
  mov     dx,Hello
  int     21h

  virtual Data
    ExitCode db 37h
  end virtual

  mov     ah,4Ch
  mov     al,[ExitCode]
  int     21h
Такой подход позволяет легко включить синтаксис с модификаторами в любой инструкции, которая внутренне использует «байтовую» макроинструкцию при генерации кода.

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

Естественный подход заключается в определении содержимого вспомогательного раздела в «виртуальном» блоке и копировании его в соответствующую позицию в выводе с помощью одной операции. Когда «виртуальный» блок помечен, его можно повторно открыть несколько раз, чтобы добавить к нему больше данных.
macro ? line&
  match .=CODE?, line
    CODE
  else match .=DATA?, line
    DATA
  else
    line
  end match
end macro
Это приводит к относительно простому синтаксису даже без помощи каких-либо дополнительных макросов.

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

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

Какие есть варианты для синтаксического анализа других типов синтаксиса?
В некоторых случаях команда, которую ассемблер должен проанализировать, может начинаться с чего-то отличного от имени инструкции или метки. Может случиться так, что имени предшествует специальный символ, такой как «.» или "!", или что это совершенно другой вид конструкции. Тогда нужно использовать «макрос?» перехватывать целые строки исходного текста и обрабатывать любой специальный синтаксис такого рода.

Например, если бы требовалось разрешить команду, написанную как «.CODE», было бы невозможно реализовать ее непосредственно как макроинструкцию, потому что начальная точка вызывает интерпретацию символа как локальной, а глобально определенная инструкция никогда не сможет быть исполненным таким образом. Перехватывающая макроинструкция обеспечивает решение:
macro concise
  macro ? line&
    match =end =concise, line
      purge ?
    else match dest+==src, line
      ADD dest,src
    else match dest-==src, line
      SUB dest,src
    else match dest==src, line
      LD dest,src
    else match dest++, line
      INC dest
    else match dest--, line
      DEC dest
    else match any, line
      err "syntax error"
    end match
  end macro
end macro

concise
  C=0
  B++
  A+=2
end concise
Строки, содержащие текст «.CODE» или «.DATA», обрабатываются здесь таким образом, что они вызывают глобальную макроинструкцию с соответствующим именем, тогда как все остальные перехваченные строки выполняются без изменений. Этот метод позволяет отфильтровать любой специальный синтаксис и позволить ассемблеру обрабатывать обычные инструкции как обычно.
Иногда нетрадиционный синтаксис ожидается только в определенной области исходного текста, например, внутри блока с определенными границами. Макроинструкция синтаксического анализа должна затем применяться только в этом месте и удаляться с помощью «продувки», когда заканчивается блок:
struc (head) ? tail&
  match .=CODE?, head
    CODE tail
  else
    head tail
  end match
end struc
Макроинструкция, определенная таким образом, не перехватывает строки, которые содержат директивы, управляющие потоком сборки, такие как «if» или «repeat», и они все еще могут свободно использоваться внутри такого блока. Это изменится, если объявление будет в форме "macro?! Line &". Такой вариант будет перехватывать каждую строку без исключения.

Другим вариантом для отлова специальных команд может быть использование "struc?" перехватывать только те строки, которые не начинаются с известной инструкции (исходный символ затем обрабатывается как метка). Так как этот тест проверяет только неизвестные команды, он должен вызывать меньше затрат на сборку:
struc (head) ? tail&
  local invoker
  match .=CODE?, head
    macro invoker
      CODE tail
    end macro
  else
    macro invoker
      head tail
    end macro
  end match
  invoker
end struc
Все эти подходы скрывают тонкую ловушку. За меткой, определенной с помощью «:», может следовать другая инструкция в той же строке. Если эта следующая инструкция (которая здесь становится скрытой в параметре tail) является директивой управления, такой как «if», то помещение ее в предложение «else» приведет к нарушению вложенности блоков управления. Решение состоит в том, чтобы каким-то образом вызывать содержимое «tail» вне блока «match». Одним из способов может быть вызов специального макроса:
struc (head) ? tail&
  match .=CODE?, head
    CODE tail
    macro ? line&
      purge ?
    end macro
  end match
  head tail
end struc
Но более простой вариант - вызвать исходную строку напрямую и, когда необходимо переопределение, заставить ее игнорироваться с помощью другого перехватчика строки (избавиться от него сразу после):
macro definitions end?
  namespace embedded
  struc LABEL? size
    match , size
      .:
    else
      label . : size
    end match
  end struc
  macro E#ND? name
    end namespace
    match any, name
      ENTRYPOINT := name
    end match
    macro ?! line&
    end macro
  end macro
end macro

definitions end

start LABEL
END start
Можно добавить еще один макрос с целью игнорирования следующей строки, чтобы сделать это решение более компактным.

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

Но есть еще одна хитрость, связанная с тем, как тексты макропараметров или символических переменных сохраняют контекст, в котором следует интерпретировать символы внутри них (это включает в себя базовое пространство имен и родительскую метку для символов, начинающихся с точки).
В отличие от двух упомянутых случаев, текст макроса обычно не несет такой дополнительной информации, но если макрос сконструирован таким образом, что он содержит текст, который когда-то переносился в параметре в другой макрос или в символьную переменную, тогда это текст сохраняет информацию о контексте, даже когда он становится частью вновь определенного макроса. Например:
Параметр, данный макросу «определения», может показаться, что он ничего не делает, так как он заменяет каждый экземпляр «конца» одним и тем же словом - но текст, который приходит из параметра, снабжен дополнительной информацией о контексте, и этот атрибут затем сохраняется, когда текст становится частью нового макроса. Благодаря этому макрос «LABEL» может использоваться в пространстве имен, где инструкция «end» приняла другое значение, но экземпляры «end» в его теле все еще ссылаются на символ во внешнем пространстве имен.

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

Тот же эффект может быть достигнут за счет использования символических переменных вместо макропараметров с помощью «соответствия» для извлечения текста символической переменной:
define link end
match end, link
  namespace embedded
  struc LABEL? size
    match , size
      .:
    else
      label . : size
    end match
  end struc
  macro END? name
    end namespace
    match any, name
      ENTRYPOINT := name
    end match
    macro ?! line&
    end macro
  end macro
end match

start LABEL
END start
Это не будет работать без передачи текста через символьную переменную, поскольку параметры, определенные управляющими директивами, такими как «match», не добавляют контекстную информацию к тексту, если он уже не был там.

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