Директивы в ассемблере что это

Расширенный ассемблер: NASM

Глава 5: Директивы ассемблера

Хотя NASM и пытается избежать бюрократизм ассемблеров наподобие MASM и TASM, он вынужден поддерживать несколько директив. Все они описаны в этой главе.

Существует два типа директив NASM: пользовательские и примитивные. Обычно каждая директива имеет как пользовательскую, так и примитивную форму. В большинстве случаев рекомендуется использовать пользовательскую форму директив, которая реализована как макрос, вызывающий примитивные формы. Примитивные директивы заключаются в квадратные скобки; для пользовательских директив этого не требуется.

В дополнение к описанным в этой главе универсальным директивам каждый объектный формат может опционально предоставлять дополнительные директивы, служащие для управления особенностями этого формата. Такие дополнительные директивы описываются далее в главе, посвященной выходным форматам файлов (глава 6).

5.1 BITS : Указание разрядности выполняемого кода

Не нужно задавать BITS 32 для использования 32-битных инструкций в 16-битных DOS-программах; если вы это сделаете, ассемблер сгенерирует некорректный код, так как он получится 32-битным и на 16-битных платформах будет не работоспособен.

5.2 SECTION или SEGMENT : Описание и изменение секций

Директива SECTION ( SEGMENT — это абсолютно эквивалентный синоним) указывает, в какую секцию выходного файла будет ассемблирован код, который вы пишете. В некоторых объектных форматах количество и имена секций фиксированы; в других пользователь может сделать их столько, сколько захочет. Поэтому если вы захотите переключиться на секцию, которая в данный момент не существует, директива SECTION может либо вызвать сообщение об ошибке, либо создать новую секцию.

5.2.1 Макрос __SECT__

развернется в две строки:

5.3 ABSOLUTE : Определение абсолютных меток

ABSOLUTE используется следующим образом:

ABSOLUTE в качестве аргумента принимает не только абсолютные константы: это может быть выражение (на самом деле критическое выражение: см. параграф 3.7), а также какое-то значение в сегменте. Например, TSR может реутилизировать свой настроечный код в качестве run-time BSS следующим образом:

Здесь определяется несколько переменных «на верхушке» setup-кода, так что после завершения его работы это пространство может быть реутилизировано как хранилище данных для работающей TSR. Символ ‘ tsr_end ‘ может быть использован для расчета общего размера резидентной части TSR.

5.4 EXTERN : Импорт символов из других модулей

Директива EXTERN подобна директиве MASM EXTRN и ключевому слову extern в С: она используется для объявления символа, который определен в некотором другом модуле. Не все объектные форматы поддерживают внешние переменные: формат bin этого не может.

Директива EXTERN принимает столько аргументов, сколько вам необходимо. Каждый аргумент является именем символа:

Примитивная форма EXTERN отличается от пользовательской тем, что одновременно может принять только один аргумент: поддержка списка аргументов реализуется на уровне препроцессора.

Вы можете объявить одну и ту же переменную как EXTERN более одного раза: NASM спокойно проигнорирует второе и последующие переопределения.

5.5 GLOBAL : Экспорт символов в другие модули

5.6 COMMON : Определение общих данных

Директива COMMON используется для объявления общих переменных. Общая переменная — это глобальная переменная, объявленная в секции неинициализированных данных, поэтому

работает так же, как и

Отличие состоит в том, что если одна и та же переменная определена в разных модулях, во время связывания (сборки) эти переменные будут объединены и ссылки на intvar во всех модулях будут указывать на одно и то же место в памяти.

Источник

Директивы Ассемблера

Группа директив для указания типа процессора

Директивы указания типа процессора задают набор используемых инструкций.

Директивы для указания сегментов

Директива SEGMENT

Определяет сегмент с заданным именем name. Если сегмент с таким именем уже был определен ранее, то данный сегмент интерпретируется как продолжение предыдущего.

BYTEвыравнивание не выполняется. Сегмент может начинаться с любого адреса памяти
WORDвыравнивание на границу слова (2 байта)
DWORDвыравнивание на границу двойного слова (4 байта)
PARAвыравнивание по границе параграфа (16 байт). Используется по-умолчанию.
PAGEвыравнивание на границу в 256 байт
USE16сегмент с 16-разрядной адресацией. Максимальный размер сегмента 64 Кб
USE32сегмент с 32-разрядной адресацией. Максимальный размер сегмента 4 Гб. В модели памяти FLAT используется по-умолчанию

Директива ENDS

Определяет конец сегмента.

Директива ASSUME

Задает сегментный регистр, который будет использоваться для вычисления действующего адреса для всех меток и переменных, определенных для сегмента или группы сегментов с указанным именем.

Директивы для упрощенного указания сегментов

Директива .MODEL

Задает модель памяти для упрощенных директив определения сегментов.

CАргументы передаются через стек, справа налево. Стек очищает вызывающая программа.
PASCAL, BASICАргументы передаются через стек, слева направо. Стек очищает вызываемая подпрограмма.
STDCALLАргументы передаются через стек, справа налево. Стек очищает вызываемая подпрограмма.

Директива .CODE или CODESEG

Определяет начало сегмента кода. Если задали среднюю или большую модель памяти, то за директивой может следовать необязательное имя, которое указывает имя сегмента. По-умолчанию имя сегмента _TEXT.

Директива .DATA или DATASEG

Определяет начало инициализированного сегмента данных.

Директива .DATA?

Определяет в модуле начало неинициализированного сегмента данных.

Директива .CONST

Определяет начало сегмента данных-констант.

Сегменты .DATA, .DATA?, .CONST помещаются в одну группу с именем DGROUP

Директива .STACK или STACK

Определяет начало сегмента стека, выделяя количество байт, заданное параметром. Если размер не указывается, выделяется 1024 байт.

Группа директив для резервирования памяти

Резервирует область памяти, заданного директивой размера, с указанным именем, и инициализирует значением выражения. Выражение может быть числом, строкой символов, специальным символом «?«, а также выражением с использованием директивы DUP.

Повторяет операцию выделения памяти для указанных данных столько раз, сколько задано значением счетчика

Директива STRUC (STRUCT)

Определяет структуру данных с заданным именем, содержащую поля. В каждом поле для определения его размера используются обычные директивы выделения данных (DB, DW и т.д.). Поля структуры могут быть именованными или нет.

Директива ENDS

Определяет конец структуры.

Директива UNION

Группа директив модификации размера указателей

Используются когда возникает неоднозначность в размере операнда команды. Например когда в ячейку памяти записывается число, то компилятор не может определить число какого размера требуется записать, и в этом случае требуется укзать директиву модификации размера.

Директивы определения процедур

Директива PROC

Определяет начало процедуры с указанным именем.

Директива ENDP

Определяет окончание процедуры

Директива USES

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

Директива LOCAL

В процедуре директива LOCAL определяет имена, которые доступны в стеке через отрицательные смещения относительно регистра BP. Если указан идентификатор, то ему присваивается количество байт, выделенных на локальные переменные (размер всего блока локальных переменных в байтах).

Директивы для макроопределений

Директива MACRO

Определяет начало макроопределения с указанным именем. У макроопредения могут быть заданы необязательные параметры, которые будут использоваться при подстановке тела макроопределения в текст программы.

Директива ENDM

Определяет окончание макроопределения

Директива REPT

Повторяет блок операторов, заданный между директивами REPT и ENDM столько раз, сколько задается выражением. Блок операторов должен заканчиваться директивой ENDM.

Директива IRP

Повторяет блок операторов, заданный между директивой IRP и ENDM со строковой подстановкой. Аргументами может быть любой текст: символы, строки, числа и т.д. Для каждого указанного аргумента ассемблирование блока операторов выполняется только один раз. При каждом ассемблировании блока для каждого вхождения «параметра» в операторах подставляется следующий аргумент в списке.

Другие директивы

Директива COMMENT

Позволяет задать многострочный комментарий, ограниченный с начала и с конца заданным символом-ограничителем.

Директива EQU

Определяет имя как строку, псевдоним или число, содержащие результат вычисления выражения.

Директива END

Отмечает конец исполняемого модуля и задает начальный адрес, с которого будет исполняться программа.

Директива EVEN

Округляет счетчик адреса до следующего четного адреса

Директива SEG

Возвращается адрес сегмента выражения со ссылкой на память

Директива OFFSET

Возвращает смещение выражения в текущем сегменте (или в группе, которой принадлежит сегмент, если используются упрощенные директивы определения сегментов).

Директива ORG

Устанавливает счетчик инструкций в текущем сегменте в соответствии с адресом, задаваемым выражением.

Директива RADIX

Задает основание системы счисления для целочисленных констант (2, 8, 10 или 16)

Директива SIZE

Возвращает размер элемента данных, выделенного для переменной

Источник

Директивы в ассемблере что это

Компилятор поддерживает ряд директив. Директивы не транслируются непосредственно в код. Вместо этого они используются для указания положения в программной памяти, определения макросов, инициализации памяти и т.д. Список директив приведён в таблице 3.5

Таблица 3.5 Список директив ассемблера

ДирективаОписание
BYTEЗарезервировать байты в ОЗУ
CSEGПрограммный сегмент
DBОпределить байты во флэш или EEPROM
DEFНазначить регистру символическое имя
DEVICEОпределить устройство для которого компилируется программа
DSEGСегмент данных
DWОпределить слова во флэш или EEPROM
ENDMКонец макроса
EQUУстановить постоянное выражение
ESEGСегмент EEPROM
EXITВыйти из файла
INCLUDEВложить другой файл
LISTВключить генерацию листинга
LISTMACВключить разворачивание макросов в листинге
MACROНачало макроса
NOLISTВыключить генерацию листинга
ORGУстановить положение в сегменте
SETУстановить переменный символический эквивалент выражения

Все директивы предваряются точкой.

Директива BYTE резервирует байты в ОЗУ. Если Вы хотите иметь возможность ссылаться на выделенную область памяти, то директива BYTE должна быть предварена меткой. Директива принимает один обязательный параметр, который указывает количество выделяемых байт. Эта директива может использоваться только в сегменте данных(смотреть директивы CSEG и DSEG). Выделенные байты не инициализируются.

Директива CSEG определяет начало программного сегмента. Исходный файл может состоять из нескольких программных сегментов, которые объединяются в один программный сегмент при компиляции. Программный сегмент является сегментом по умолчанию. Программные сегменты имеют свои собственные счётчики положения, которые считают не побайтно, а пословно. Директива ORG может быть использована для размещения кода и констант в необходимом месте сегмента. Директива CSEG не имеет параметров.

Директива DB резервирует необходимое количество байт в памяти программ или в EEPROM. Если Вы хотите иметь возможность ссылаться на выделенную область памяти, то директива DB должна быть предварена меткой. Директива DB должна иметь хотя бы один параметр. Данная директива может быть размещена только в сегменте программ (CSEG) или в сегменте EEPROM (ESEG).

Директива DEF позволяет ссылаться на регистр через некоторое символическое имя. Назначенное имя может использоваться во всей нижеследующей части программы для обращений к данному регистру. Регистр может иметь несколько различных имен. Символическое имя может быть переназначено позднее в программе.

.DEF Символическое_имя = Регистр

Директива DEVICE позволяет указать для какого устройства компилируется программа. При использовании данной директивы компилятор выдаст предупреждение, если будет найдена инструкция, которую не поддерживает данный микроконтроллер. Также будет выдано предупреждение, если программный сегмент, либо сегмент EEPROM превысят размер допускаемый устройством. Если же директива не используется то все инструкции считаются допустимыми, и отсутствуют ограничения на размер сегментов.

.DEVICE AT90S1200 |AT90S2313 | AT90S2323 | AT90S2333 | AT90S2343 | AT90S4414 | AT90S4433 | AT90S4434 | AT90S8515 | AT90S8534 | AT90S8535 | ATtiny11 | ATtiny12 | ATtiny22 | ATmega603 | ATmega103

Директива DSEG определяет начало сегмента данных. Исходный файл может состоять из нескольких сегментов данных, которые объединяются в один сегмент при компиляции. Сегмент данных обычно состоит только из директив BYTE и меток. Сегменты данных имеют свои собственные побайтные счётчики положения. Директива ORG может быть использована для размещения переменных в необходимом месте ОЗУ. Директива не имеет параметров.

Директива определяет конец макроопределения, и не принимает никаких параметров. Для информации по определению макросов смотрите директиву MACRO.

Директива EQU присваивает метке значение. Эта метка может позднее использоваться в выражениях. Метка которой присвоено значение данной директивой не может быть переназначена и её значение не может быть изменено.

.EQU метка = выражение

Директива ESEG определяет начало сегмента EEPROM. Исходный файл может состоять из нескольких сегментов EEPROM, которые объединяются в один сегмент при компиляции. Сегмент EEPROM обычно состоит только из директив DB, DW и меток. Сегменты EEPROM имеют свои собственные побайтные счётчики положения. Директива ORG может быть использована для размещения переменных в необходимом месте EEPROM. Директива не имеет параметров.

Встретив директиву EXIT компилятор прекращает компиляцию данного файла. Если директива использована во вложенном файле (см. директиву INCLUDE), то компиляция продолжается со строки следующей после директивы INCLUDE. Если же файл не является вложенным, то компиляция прекращается.

Встретив директиву INCLUDE компилятор открывает указанный в ней файл, компилирует его пока файл не закончится или не встретится директива EXIT, после этого продолжает компиляцию начального файла со строки следующей за директивой INCLUDE. Вложенный файл может также содержать директивы INCLUDE.

Директива LIST указывает компилятору на необходимость создания листинга. Листинг представляет из себя комбинацию ассемблерного кода, адресов и кодов операций. По умолчанию генерация листинга включена, однако данная директива используется совместно с директивой NOLIST для получения листингов отдельных частей исходных файлов.

После директивы LISTMAC компилятор будет показывать в листинге содержимое макроса. По умолчанию в листинге показывается только вызов макроса и передаваемые параметры.

С директивы MACRO начинается определение макроса. В качестве параметра директиве передаётся имя макроса. При встрече имени макроса позднее в тексте программы, компилятор заменяет это имя на тело макроса. Макрос может иметь до 10 параметров, к которым в его теле обращаются через @0-@9. При вызове параметры перечисляются через запятые. Определение макроса заканчивается директивой ENDMACRO.

По умолчанию в листинг включается только вызов макроса, для разворачивания макроса необходимо использовать директиву LISTMAC. Макрос в листинге показывается знаком +.

Директива NOLIST указывает компилятору на необходимость прекращения генерации листинга. Листинг представляет из себя комбинацию ассемблерного кода, адресов и кодов операций. По умолчанию генерация листинга включена, однако может быть отключена данной директивой. Кроме того данная директива может быть использована совместно с директивой LIST для получения листингов отдельных частей исходных файлов

Директива SET присваивает имени некоторое значение. Это имя позднее может быть использовано в выражениях. Причем в отличии от директивы EQU значение имени может быть изменено другой директивой SET.

.SET имя = выражение

Выражения

Компилятор позволяет использовать в программе выражения которые могут состоять операндов, операторов и функций. Все выражения являются 32-битными.

Операнды

Могут быть использованы следующие операнды:

Источник

Ссылка ассемблера OS X

Ассемблерные директивы

В этой главе описываются ассемблерные директивы (также известный как псевдо операции или псевдооперация в секунду), которые позволяют управление действиями ассемблера.

Директивы для обозначения текущего раздела

Связанный с каждым разделом в каждом сегменте неявный счетчик адреса, начинающийся в нуле и постепенно увеличивающийся 1 для каждого байта, собранного в раздел. Нет никакого способа явно сослаться на определенный счетчик адреса, но директивы, описанные здесь, могут использоваться для «активирования» счетчика адреса для раздела, делая его текущим счетчиком адреса. В результате ассемблер начинает собираться в раздел, связанный с тем счетчиком адреса.

.section

.zerofill

Типы раздела и атрибуты

Довольный раздел имеет тип, сообщающий редактору связей о специальной обработке, необходимой для элементов в том разделе. Наиболее распространенная форма специальной обработки для разделов, содержащих литералы (строки, константы, и т.д.), где только одна копия литерала необходима в выходном файле, и тот же литерал может использоваться всеми ссылками во входных файлах.

Атрибуты раздела записывают дополнительную информацию о разделе, который редактор связей может использовать в обработке того раздела. Например, pure_instructions атрибут указывает, что раздел содержит только допустимые машинные команды.

Идентификаторы типов

Следующие разделы описывают идентификаторы типов раздела.

регулярный (S_REGULAR)
cstring_literals (S_CSTRING_LITERALS)

A cstring_literals раздел содержит завершенные нулем литеральные символьные строки языка C. Редактор связей помещает только одну копию каждого литерала в раздел выходного файла и перемещает ссылки на различные копии того же литерала к одной копии в выходном файле. Не может быть никаких записей перемещения для раздела этого типа, и все ссылки на литералы в этом разделе должны быть в диапазоне адресов для определенного ссылаемого литерала. Последний байт в разделе этого типа должен быть нулевым байтом, и строки не могут содержать нулевые байты в своих организациях. Пример a cstring_literals раздел один для литеральных строк, появляющихся в организации функции ANSI C, где компилятор принимает решение сделать такие строки только для чтения.

4byte_literals (S_4BYTE_LITERALS)
8byte_literals (S_8BYTE_LITERALS)
literal_pointers (S_LITERAL_POINTERS)
symbol_stubs (S_SYMBOL_STUBS)

A symbol_stubs раздел содержит тупики символа, которые являются последовательностями машинных команд (весь одинаковый размер) используемый для того, чтобы лениво связать неопределенные вызовы функции во время выполнения. Если вызов к неопределенной функции выполняется, выходы компилятора вызов к тупику символа вместо этого, и тегирует тупик с косвенным символом, указывающим, для какого символа тупик. На передаче в тупик символа программа выполняет инструкции, в конечном счете достигающие кода для косвенного символа, связанного с тем тупиком. Вот выборка ассемблерного кода на основе функции func() содержа только вызов к неопределенной функции foo() :

На IA-32 команда перехода указывает динамическому компоновщику. В первый раз, когда тупик вызывают, динамический компоновщик изменяет инструкцию так, чтобы это перешло к реальной функции в последующих вызовах.

Статический редактор связей помещает только одну копию каждого тупика в раздел выходного файла для определенного косвенного символа и перемещает все ссылки на тупики с тем же косвенным символом к тупику в выходном файле. Далее, статический редактор связей устраняет тупик, если он решает, что цель находится в том же модуле связи и не нуждается в перенаправлении во время выполнения. Никакие глобальные символы не могут быть определены в symbol_stubs разделы.

На PPC тупик может относиться только к себе, один ленивый указатель символа (именующий тот же косвенный символ как тупик), и dyld_stub_binding_helper() функция.

lazy_symbol_pointers (S_LAZY_SYMBOL_POINTERS)
non_lazy_symbol_pointers (S_NON_LAZY_SYMBOL_POINTERS)

A non_lazy_symbol_pointers раздел содержит 4-байтовые указатели символа, содержащие значение косвенного символа, связанного с указателем, который может быть установлен в любое время, прежде чем любой код делает ссылку на него. Эти указатели используются кодом для ссылки на неопределенные символы. Первоначально эти указатели не имеют никакого интересного значения, но перезаписываются редактором динамического канала со значением символа для связанного косвенного символа, прежде чем любой код сможет сделать ссылку на него.

Вот пример ассемблерного кода, ссылающегося на элемент в неопределенной структуре. Соответствующий код C был бы:

Ассемблерный код PowerPC мог бы быть похожим на это:

mod_init_funcs (S_MOD_INIT_FUNC_POINTERS)
mod_term_funcs (S_MOD_TERM_FUNC_POINTERS)
объединенный (S_COALESCED)

Идентификаторы атрибута

Следующие разделы описывают идентификаторы атрибута.

ни один (0)
S_ATTR_SOME_INSTRUCTIONS
no_dead_strip (S_ATTR_NO_DEAD_STRIP)

no_dead_strip атрибут раздела указывает, что определенный раздел не должен быть мертво разделен. См. Директивы для Невыполняемого кода, Разделяющего для получения дополнительной информации.

no_toc (S_ATTR_NO_TOC)
live_support (S_ATTR_LIVE_SUPPORT)

live_support атрибут раздела указывает, что блоки раздела не должны быть мертво разделены, если они код ссылки, который жив, но ссылка, необнаруживаемые. См. Директивы для Невыполняемого кода, Разделяющего для получения дополнительной информации.

pure_instructions (S_ATTR_PURE_INSTRUCTIONS)
strip_static_syms (S_ATTR_STRIP_STATIC_SYMS)

strip_static_syms разделите средние значения атрибута, что статические символы в этом разделе могут быть разделены от соединенных изображений, использующихся с динамическим компоновщиком, когда также разделяется отладочная информация. Это обычно используется с a coalesced раздел, имеющий частный extern символы, так, чтобы после соединения и частного экстерна символы были превращены в статические символы, они могут быть разделены для оставления свободного места в соединенном изображении.

self_modifying_code (S_ATTR_SELF_MODIFYING_CODE)

self_modifying_code атрибут раздела идентифицирует раздел с кодом, который может быть изменен динамическим компоновщиком. Например, тупики символа IA-32 реализованы как команды перехода, первоначально указывающие динамическому компоновщику, но изменяющиеся динамическим компоновщиком для указания на реальный символ.

Встроенные директивы

Обозначение разделов в __ сегмент текста

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *