# Assignment №2: Dictionary in assembly --- Лабораторная работа №2: словарь на assembler # Подготовка * Прочитайте первые главы 3,4,5 "Low-level programming: C, assembly and program execution". На защите мы можем обсуждать цикл компиляции, роль компоновщика, препроцессора, устройство виртуальной памяти и связь между секциями, сегментами, регионами памяти. Также можем поговорить про кольца защиты и привилегированный режим. ## Связный список Связный список — это структура данных. Пустой список это нулевой указатель; непустой список это указатель на первый элемент списка. Каждый элемент содержит данные и указатель на следующий элемент. Вот пример связного списка (100, 200, 300). Его начало можно найти по указателю `x1`: ```nasm section .data x1: dq x2 dq 100 x2: dq x3 dq 200 x3: dq 0 dq 300 ``` Часто есть необходимость хранить набор данных в каком-то контейнере. С контейнером мы производим операции доступа к его элементам, добавления элемента в начало или конец, или на произвольную позицию, сортировки. Разные контейнеры делают одни из этих операций лёгкими и быстрыми, а другие — медленными. Например, в массив неудобно добавлять элементы, но можно быстро обратиться к уже сущестующему по индексу. В связный список, наоборот, удобно добавлять элементы в любое место, но доступ по индексу сложнее — нужно просмотреть весь список с самого начала. ## Задание Необходимо реализовать на ассемблере словарь в виде связного списка. Каждое вхождение содержит адрес следующей пары в словаре, ключ и значение. Ключи и значения — адреса нуль-терминированых строк. Словарь задаётся статически, каждый новый элемент добавляется в его начало. С помощью макросов мы автоматизируем этот процесс так, что указав с помощью новой конструкции языка новый элемент он автоматически добавится в начало списка, и указатель на начало списка обновится. Таким образом нам не нужно будет вручную поддерживать правильность связей в списке. Создайте макрос `colon` с двумя аргументами: ключом и меткой, которая будет сопоставлена значению. Эта метка не может быть сгенерирована из самого значения, так как в строчке могут быть символы, которые не могут встречаться в метках, например, арифметические знаки, знаки пунктуации и т.д. После использования такого макроса можно напрямую указать значение, сопоставляемое ключу. Пример использования: ```nasm section .data colon "third word", third_word db "third word explanation", 0 colon "second word", second_word db "second word explanation", 0 colon "first word", first_word db "first word explanation", 0 ``` В реализации необходимо предоставить следующие файлы: - `lib.asm` - библиотека ввода-вывода из первого задания - `lib.inc` - заголовочный файл к библиотеке ввода-вывода - `colon.inc` - заголовочный файл с определением макроса `colon` - `dict.asm` - реализация функции `find_word` для поиска в словаре - `dict.inc` - заголовочный файл для функции поиска в словаре - `words.inc` - определене словаря, который будет использоваться в тестах - `main.asm` - реализация простейшего консольного интерфейса для поиска в словаре ### Указания - Оформите функции, которые вы реализовали в первой лабораторной работе, в виде отдельной библиотеки `lib.o`. Не забудьте все названия функций сделать глобальными метками и перечислить их в `lib.inc`. - - Что бы не копировать файлы между репозиториями можно добавить репозиторий с первой лабораторной работой в качестве [модуля git](https://git-scm.com/book/ru/v2/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-Git-%D0%9F%D0%BE%D0%B4%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D0%B8) - - По умолчанию, CI раннеры не загружают содержимое подмодулей, это нужно делать дополнительной командой `git submodule update --init --recursive` - Создайте файл `colon.inc` и определите в нём макрос для создания слов в словаре. Макрос принимает два параметра: - Ключ (в кавычках) - Имя метки, по которой будет находиться значение. - В файлах `dict.asm` и `dict.inc` создать функцию `find_word`. Она принимает два аргумента: - Указатель на нуль-терминированную строку. - Указатель на начало словаря. `find_word` пройдёт по всему словарю в поисках подходящего ключа. Если подходящее вхождение найдено, вернёт адрес *начала вхождения в словарь* (не значения), иначе вернёт 0. - Файл `words.inc` должен хранить слова, определённые с помощью макроса `colon`. Включите этот файл в `main.asm`. - В `main.asm` определите функцию `_start`, которая: - Читает строку размером не более 255 символов в буфер с `stdin`. - Пытается найти вхождение в словаре; если оно найдено, распечатывает в `stdout` значение по этому ключу. Иначе выдает сообщение об ошибке. Не забудьте, что сообщения об ошибках нужно выводить в `stderr`. - Обязательно предоставьте `Makefile`, который будет учитывать зависимости файлов для корректной сборки задания. Целью по-умолчанию должна быть сборка задания. - Напишите тесты для вашей реализации словаря. Тесты должны запускаться целью `test` мейкфайла.