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