Моно-но аварэ

Вчера нашёл в себе силы оторваться от вечернего сериальчика и сесть за ассемблер, в итоге моя неповторимая поделочка уже может почти всё, что и жалкий оригинал.

Пока писал, обнаружилась несколько занятных вещей. Ниже серьёзный тон и если вам не нравится программирование, можете смело пропустить этот пост, да и картиночек не будет, совсем печально.

В прошлой версии своей утилиты я сначала пытался файл открыть, если не получалось, то создать. Вообще, есть такой флаг O_CREAT, который можно указать в качестве режима открытия и если файл не существует, он создаётся. У меня не создавался. Я не понимал почему и понял лишь когда запустил strace. Оказалось, что константы, которые я взял откуда-то из недр своего Линукса, не соответствуют действительности. Скомпилировал небольшую программку на Сях и оттуда выдернул нужные значения, заработало как ожидается, минус один сисколл.

Вторая вещь — я очень давно не программирую на ассемблере и растерял большинство лучших практик. Вот например я не помню как лучше — когда подпрограмма сохраняет регистры, которая она портит или наоборот. Вроде первый вариант выглядит как-то универсальнее, но в моём случае придётся сохранять много регистров, которые я в реальности не занимаю. Так как программа у меня более чем обозримая (пара сотен строк) я остановился на втором варианте, в этом случае ничего лишнего я не делаю. Попутно ещё оказалось, что аналога команд PUSHA/POPA в 64-битном режиме нет (хаха), а это сохранение и восстановление всех регистров через стек одной командой, очень удобно, если мы не паримся над использованием памяти (всё-таки регистров уже немало и каждый по 8 байт).

Ну и последнее, самое интересное. Утилита работает с файлами, а файловые хендлеры надо где-то хранить. Файлов будет столько, сколько передаст пользователь через параметры. Тут две стратегии — ограничить количество входных параметров (пока я пошёл по этому пути) или более интересно — научиться динамически выделять память в системе. Я хочу второе. Из разной литературы я помнил, что есть некий mmap, которому можно скормить /dev/zero и получить область памяти, а есть куча, с которой тоже как-то можно работать.

Получаются всего несколько вызовов — мне нужен sys_mmap или sys_brk, первый работает с памятью от четырёх килобайт, второй и с менее значительными кусками. Хотя первый вызов мне интереснее, но выглядит он как попытка выстрелить из пушки по воробьям, попробую использовать второй.

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

Поделиться
Отправить
Популярное