Введение

Высокоуровневый ассемблер (англ. High Level Assembly, HLA) — язык, разработанный Рэндаллом Хайдом, который позволяет использовать конструкции языков высокого уровня, чтобы облегчить работу как начинающим, так и опытным разработчикам на ассемблере. Он обеспечивает полную поддержку современных типов данных и объектно-ориентированного программирования. Синтаксис HLA свободно основан на нескольких языках программирования высокого уровня (HLL), таких как Pascal, Ada, Modula 2 и C++, что позволяет создавать удобочитаемые программы на ассемблере и облегчает переход на HLA для программистов, знакомых с HLL.

Истоки и цели

HLA изначально задумывалась как инструмент для обучения программированию на языке ассемблера в колледжах и университетах. Цель состоит в том, чтобы использовать уже имеющиеся у студентов знания в области программирования при изучении языка ассемблера, чтобы они могли как можно быстрее освоиться с ним. Большинство студентов, посещающих курс программирования на языке ассемблера, уже знакомы с высокоуровневыми структурами управления потоком выполнения, такими как IF, WHILE, FOR и т.д. HLA позволяет студентам сразу же применять эти знания к написанию кода на языке ассемблера в начале курса, что позволяет им освоить другие необходимые для этого дисциплины, прежде чем изучать низкоуровневые реализации этих структур управления. Книга Рэндалла Хайда «Искусство программирования на языке ассемблера» использует HLA в этих целях.

Отличительные черты

Две особенности HLA выделяют его среди других x86-ассемблеров: мощная макросистема (язык времени компиляции) и стандартная библиотека HLA.

Макросистема

Язык HLA с компиляцией позволяет легко расширять сам язык, даже создавать небольшие специализированные языки для удобного решения типовых задач программирования. Макрос `stdout.put` – хороший пример сложного макроса, способного упростить процесс программирования. Рассмотрим следующий вызов этого макроса:

`stdout.put("I=", i, " s=", s, " u=", u, " r=", r:10:2, nl);`

Макрос `stdout.put` обрабатывает каждый аргумент, определяя его тип, а затем вызывает соответствующую процедуру из стандартной библиотеки HLA для обработки вывода каждого операнда. Большинство ассемблеров предоставляют некоторую поддержку макросов, но HLA отличается тем, что может обрабатывать аргументы макросов, такие как `r:10:2`, используя мощные строковые функции HLA, доступные во время компиляции. Кроме того, макросистема HLA способна определять типы переменных и использовать эту информацию для управления расширением макроса. Макроязык HLA предоставляет специальную возможность создания контекстно-независимых макросов. Эта функция позволяет легко создавать макросы, охватывающие различные участки кода, с помощью пары стартового и завершающего макросов (а также необязательных промежуточных вызовов макросов, доступных только между стартовым и завершающим макросами). Например, с помощью этой возможности можно реализовать полностью рекурсивный, вложенный оператор `SWITCH–CASE–DEFAULT–ENDSWITCH`. Благодаря контекстно-независимой природе макросов HLA, такие операторы `switch–case–default–endswitch` могут быть вложены друг в друга, и код, генерируемый вложенными операторами, не будет конфликтовать с кодом внешних операторов.

Язык компиляции

Макросистема HLA на самом деле является подмножеством более крупной возможности, известной как язык времени компиляции HLA (CTL). HLA CTL – это интерпретируемый язык, доступный в исходном файле программы HLA. Интерпретатор выполняет операторы HLA CTL во время компиляции исходного файла HLA, отсюда и название "язык времени компиляции". HLA CTL включает в себя множество управляющих операторов, таких как #IF, #WHILE, #FOR, #PRINT, оператор присваивания и так далее. Также можно создавать переменные и константы времени компиляции (включая структурированные типы данных, такие как записи и объединения). HLA CTL предоставляет сотни встроенных функций (включая очень богатый набор функций для работы со строками и сопоставления с образцом). HLA CTL позволяет программистам создавать программы CTL, которые сканируют и разбирают строки, что позволяет им создавать встроенные языки, специфичные для предметной области (EDSL, также называемые мини-языками). Макрос `stdout.put`, рассмотренный ранее, является примером такого EDSL. Макрос `put` (в пространстве имен `stdout`, отсюда и название `stdout.put`) разбирает свой список макропараметров и генерирует код, который будет выводить его операнды.

Дизайн

HLA v2.x – это языковая система, работающая из командной строки и состоящая из нескольких компонентов, включая программу-оболочку (например, hla.exe в Windows), компилятор языка HLA (например, hlaparse.exe), низкоуровневый транслятор (например, HLABE или HLA Back Engine), компоновщик (link.exe в Windows, ld в Linux) и другие инструменты, такие как компилятор ресурсов для Windows. Версии до 2.0 использовали внешний модуль ассемблирования; версии 2.x и более поздние версии HLA используют встроенный HLABE в качестве модуля форматирования объектного кода. Программа-оболочка HLA обрабатывает параметры командной строки и направляет соответствующие файлы в каждую из программ, составляющих систему HLA. Она принимает на вход файлы HLA (исходные файлы HLA), файлы ASM (исходные файлы для ассемблеров MASM, TASM, FASM, NASM или Gas), файлы OBJ для передачи компоновщику и файлы RC (для использования компилятором ресурсов).

Перевод исходного кода

Первоначально, инструмент HLA v1.x компилировал свой исходный код во временный исходный файл, который последующий ассемблер, такой как MASM, TASM, Flat Assembler (FASM), Netwide Assembler (NASM) или GNU Assembler (Gas), преобразовывал в объектный файл низкого уровня. Начиная с HLA v2.0, HLA включает в себя собственный HLA Back Engine (HLABE), который выполняет преобразование в объектный код низкого уровня. Однако, благодаря различным параметрам командной строки, HLA v2.x по-прежнему способна преобразовывать исходный файл HLA в исходный файл, совместимый с одним из этих других ассемблеров.

HLA Задний двигатель

HLA Back Engine (HLABE) — это компонент компилятора, преобразующий внутренний промежуточный язык в низкоуровневый Portable Executable (PE), Common Object File Format (COFF), Executable and Linkable Format (ELF) или объектный код Mach O. Программа HLABE в основном состоит из операторов вывода данных (байтов), 32-битных перемещаемых адресов, инструкций передачи управления x86 и различных директив. Помимо преобразования байтов и перемещаемых адресов в низкоуровневый формат объектного кода, HLABE также выполняет оптимизацию смещения переходов (выбор наиболее короткой формы инструкции перехода). Хотя HLABE интегрирован в компилятор HLA v2.x, фактически это отдельный продукт, распространяемый по лицензии общедоступного домена и с открытым исходным кодом (размещен на SourceForge.net).