Assignment 1: Input/Output library in assembly
Лабораторная работа 1: библиотека ввода-вывода на Assembler
Реализуйте библиотеку процедур, которые будут выполнять простые действия со строками, числами и их текстовыми представлениями.
Подготовка
-
Прочитайте первые две главы "Low-level programming: C, assembly and program execution".
-
Ознакомьтесь с документацией на следующие инструкции и Документацией по Linux ABI.
xor
-
jmp
,ja
и другими командами условного перехода cmp
mov
-
inc
,dec
-
add
,imul
,mul
,sub
,idiv
,div
neg
-
call
,ret
-
push
,pop
Документация — огромный документ. В просмотрщике PDF файлов найдите панель с оглавлением документа; там ищите второй том "Instruction Set Reference", где для каждой инструкции есть отдельная страничка.
- Прочитайте документацию на системный вызов
read
с помощьюman
. Его номер (который кладётся вrax
) 0. Информацию о регистрах, используемых для передачи параметров в системные вызовы можно найти в таблице.
Написание
- Впишите в
lib.asm
код вместо заглушек функций. По возможности переиспользуйте уже реализованные функции. - Используйте
test.py
чтобы протестировать работу.
Скрипт test.py
будет генерировать набор исполняемых файлов с тестами для каждой функции, вы можете отладить их по-отделенности; также см. Appendix A в "Low-level programming: C, assembly and program execution". При выполнении тестов проверяется соответствие кода соглашениям о вызовах и выравнивание стека кратно 16 перед всеми вызовами call
.
Список распространённых ошибок
- Для строки размером
n
байт необходимыn+1
байт из-за нуль-терминатора. - Метки функций должны быть глобальными, остальные — локальными.
- Регистры не хранят ноль "по умолчанию".
- Если вы используете callee-saved регистры, вы должны сохранить их значения.
- Если вы используете caller-saved регистры, вы должны сохранить их значения перед
call
и затем восстанавливать. - Не используйте буферы в секции
.data
. Вместо этого аллоцируйте место в стеке, уменьшая значениеrsp
. - Функции принимают аргументы в
rdi
,rsi
,rdx
,rcx
,r8
иr9
. - Не выводите числа символ за символом. Сформируйте строку в памяти и вызовите
print_string
. - Проверьте, что
parse_int
иparse_uint
корректно устанавливаютrdx
(очень важно для следующего задания) - Проверьте, что функции
parse_int
,parse_uint
иread_word
правильно работают когда ввод завершается с помощьюCtrl-D
. - При использовании стека надо не забывать уменшать
rsp
. - Перед каждым вызовом
call
необходимо выравнивать стек кратно 16. - Вызовы
syscall
могут изменить значения регистровrax
,rcx
иr11
. - Обратные кавычки позволяют использовать специальные символы в С-стиле (
\n
,\t
).
Код решения занимает порядка 250 строк.