Выделение места в сборке (функция вставки)
Я работаю над сборкой, эквивалентной функции вставки, и мне было интересно, как именно я бы разместил элементы списка, чтобы я мог разместить там свои данные. Я нашел правильный адрес для того, где моя информация должна быть вставлена, но я немного сбит с толку относительно того, как записать мои данные без перезаписи того, что там есть. Моя идея
set givespace, %l1
!Next part is at the bottom in data section
.section ".data"
givespace:
.align 48
где 48 размер моего элемента. Это дает мне ошибку неверного выравнивания границы. Есть идеи?
1 ответ
Если я правильно понимаю вопрос, и вам нужно статически выделить место для некоторой структуры данных с заранее заданным размером, вы должны заменить строку
.align 48
к следующему
times 48 db 0
Это верный путь, по крайней мере, для NASM. В любом случае я бы порекомендовал вам взглянуть на руководство по сборке, чтобы убедиться, что эта конструкция поддерживается вашим компилятором сборки. Весьма возможно, что ваш компилятор может поддерживать не совсем те же записи, что и в приведенном выше примере, но в любом случае он будет поддерживать некоторый аналог. Команда 'times' имеет следующий синтаксис:
times <number of repeats> <body>
где указывает, сколько раз тело будет вставлено в результирующий код и содержит некоторую стандартную инструкцию по сборке. В приведенном выше примере это выделение байта памяти с инициализацией на ноль. Так, например, следующие две секции кода равны
times 5 dd 012345678h
а также
dd 012345678h
dd 012345678h
dd 012345678h
dd 012345678h
dd 012345678h
Директива.align не подходит для выделения памяти. У него есть другая цель - выравнивание следующего фрагмента кода или данных по некоторому предопределенному значению. Например, в этом случае
VAR1 db 0
.align 48
VAR2 db 0
если адрес VAR1 будет 0x1234, то компилятор вставит 44 неиспользуемых байта только для того, чтобы гарантировать, что адрес VAR2 будет выровнен по границе 48 байтов. В нашем случае это будет адрес - 0x1260 (0x1260 = 0x62 * 30 + 0). Если честно, компиляторы обычно допускают выравнивание только по значению, которое является степенью двойки, и весьма вероятно, что при компиляции вышеприведенного примера ассемблер вызовет ошибку, потому что 48 не является степенью двойки. Поэтому трудно контролировать, сколько неиспользуемых байтов будет выделено директивой.align. Это может быть любое значение от 0 до параметра директивы. И это значение будет меняться в ответ на изменения в исходном коде вашей программы.
Но ВНИМАНИЕ! Это подход для статического выделения памяти во время компиляции! Если вам нужно динамическое распределение памяти во время выполнения, вам нужно написать свой собственный или найти и принять какой-либо сторонний распределитель памяти. Если ваша программа будет работать в среде ОС, вы можете запросить динамическое выделение памяти с помощью ОС API. (например VirtualAlloc в WinAPI).