Баловался, значит, всякими непотребствами на STM32F103, непотребствами, потому что на ассемблере. И возникла такая ситуация, что понадобились мне динамические массивы. На C понятное дело есть malloc, но у меня же ассемблер… там нет. Нет, для ассемблера в принципе это не является особой проблемой, т.к. память с такого уровня это в принципе один большой массив, но как-то внести больший в порядок по их использованию и облегчить себе жизнь в плане выделения/удаления потребовалось. Не долго горюя на тему "что делать", решил просто делать менеджер памяти. Поскольку оперативки у меня было не много (20кБ) менеджер не должен быть сильно сложным и тяжеловесным.
Для начала определился для себя с интерфейсом вызова подпрограмм и структурой массива. Результат выполнения всегда находится в регистре R5, передача параметров в функции через регистры R0-R4. Так как мне не очень нравится тема в С для стандартного массива постоянно таскать всюду еще отдельно его размер - решил, что пожертвую частью памяти и у каждого массива будет 4байтный префикс, в котором будет указано количество элементов и степень двойки, определяющая размер элемента (в дальнейшем пришлось переделать все и сделать массивы кратными по размеру четырем, чтобы проще было ими манипулировать через DMA).
Для собственно выделения использовались две функции: просто создания и возврата адреса массива со смещением на 4 (первый адрес после дескриптора массива) и создания с заполнением каким-либо значением (необходимо было для заливки дисплея).
Для контроля за свободной памятью и в целом избегания такой премерзкой штуки как дефрагментация памяти была заведена также глобальная переменная, указывающая на начальный адрес свободного участка. При выделении массива этот адрес сдвигался на его размер (с учетом размера дескриптора) инициировался же первым адресом за BSS (блок неинициированных переменных, забитый нулями). Удалялся массив смещением указателя на свободную память.
Так же осуществлялся контроль за вершиной стека + буфер.
Получился своеобразный стековый менеджер памяти. Дефрагментация отсутствовала, выделение без инициации и удаление за O(1), красота.
Красота длилась не долго т.к. для такого менеджера жизненно необходимо, чтобы удаление происходило с вершины и никак иначе, иное может привести к утечкам памяти или неопределенному поведению. А в дальнейшем при играх со свёрточными ядрами и масштабирование изображений потребовалось наличие возможности удаления массивов не только с вершины.
Код будет в другой статье, так как это ассемблер и портянка может получиться с пояснениями довольно приличная.