Что такое Extern в C?
Термин «extern» использовался для определения глобальных переменных в языке C. Слово «внешний» означает, что оно сокращено от слова «внешний», что означает «снаружи». Следовательно, эти переменные доступны во всем коде C. Эти переменные всегда инициализируются и определяются вне основного метода. Это руководство предназначено для пользователей, которые хотят изучить работу переменной extern с помощью языка C. Итак, вперед.
Содержание
- Пример 1:
- Пример 2:
- Пример 3:
- Заключение
Пример 1:
После запуска терминала по «Ctrl + Alt + T» вам необходимо создать C-файл. Команда «touch» широко используется для создания любого файла. Итак, мы создали файл «test.c» с инструкцией «touch», как показано ниже.
$ touch test.c
Откройте файл, чтобы добавить код C, используя инструкцию «nano». Слово «нано» используется для обозначения редактора GNU, используемого для обновления и редактирования файлов.
$ nano test.c
Внутри файла мы написали код, показанный на снимке. Включен файл заголовка потока ввода-вывода. После этого объявите внешнюю переменную «z». Мы не присвоили никакого значения переменной «z». В этом коде нет функции или основного метода. Оператор печати использовался для отображения значения внешней переменной «z».
Сохраните этот файл кода с помощью «Ctrl + S» и вернитесь в терминал с помощью «Ctrl + X». Компиляция этого файла C «test.c» была выполнена компилятором «gcc», поддерживаемым системой Ubuntu 20.04 Linux. Ошибка компиляции указывает на то, что внешняя переменная должна быть определена с некоторым значением.
$ gcc test.c
Пример 2:
Давайте снова откроем тот же файл, чтобы немного обновить его. На этот раз мы будем использовать в нашем коде «основной» метод. Мы объявили переменную «z» вне основного метода.
Компиляция файла «test.c» вызывает исключение, что переменная «z» не определена в основном методе. Это потому, что переменной «z» не было присвоено значение; следовательно, нет выделения памяти.
$ gcc test.c
Пожалуйста, откройте файл еще раз и обновите его, как показано на снимке. Мы объявили внешнюю переменную «z» вне основного метода, а затем изменили ее значение на «13» в основном методе. Оператор печати использовался для отображения значения.
После компиляции файла «test.c» мы получили ту же предыдущую ошибку и еще одну ошибку. Мы не присвоили значение внешней переменной «z»; следовательно, для «z» не выделена память. Кроме того, мы хотели изменить значение переменной «z» на «13», пока у нее еще нет выделенной памяти для сохранения значения.
$ gcc test.c
Пример 3:
Давайте еще раз немного обновим файл. На этот раз мы объявили и определили внешнюю переменную «z» вне основного метода со значением «13». В основном методе для печати и отображения значения внешней переменной «z» использовался оператор печати.
Как видно из выходных данных, компиляция файла «test.c» прошла успешно.
$ gcc test.c
При успешном выполнении файла отображается сообщение об успешном выполнении и значение переменной «z». Это потому, что переменная «z» была определена и объявлена одновременно.
$ ./a.out
Поскольку значение по умолчанию для внешней переменной всегда равно 0, вы можете использовать это для ее определения. Определив его как 0, вы можете легко изменить его значение любым методом, как показано ниже.
Компиляция будет успешной.
$ gcc test.c
Оператор печати также будет работать правильно после этого обновления.
$ ./a.out
Вы также можете присвоить значение переменной вне функции, а затем определить его в методе для тех же результатов.
Компиляция и исполнение показаны на изображении. В выходных данных было продемонстрировано внешнее значение.
$ gcc test.c
$ ./a.out
Заключение
Эта статья содержит ключевые слова extern на языке C, используя несколько простых и легких примеров. Реализация содержит объявление внешней переменной внутри и вне основного метода и поможет вам в лучшем случае.
c++ — c extern при множественном объявлении
Подскажите, как ведет себя extern в следующей ситуации:
extern int a, b, c;
Все три переменные a, b и c являются внешними, так ведь?
5Да, все 3 являются внешними.
Кстати, чтобы это проверить, достаточно их объявить и использовать с наблюдаемым поведением (это важно!). В таком случае линкер сообщит о попытках использовать несуществующие переменные: https://ideone.com/rgf40P
extern int a, b, c; int main() { return a + b + c; }
/home/CPCz1j/ccrst43X. o: In function `main': prog.cpp:(.text.startup+0x2): undefined reference to `b' prog.cpp:(.text.startup+0x8): undefined reference to `a' prog.cpp:(.text.startup+0xe): undefined reference to `c' collect2: error: ld returned 1 exit status
В синтаксисе объявления спецификатор класса хранения extern
входит в «общую» часть объявления (declaration-specifiers в С, decl-specifier-seq в С++), то есть относится ко всем деклараторам в объявлении, а не к какому-то одному. В вашем примере все три переменные объявлены с внешним связыванием.
Отдельный вопрос — что вы имеете в виду под «являются внешними». Спецификатор extern
просто придает идентификатору внешнее связывание. Но он совсем не говорит, что данная переменная определена где-то в другом месте.
Например, объявление
extern int a, b = 42, c;
говорит о том, что переменные a
и c
имеют внешнее связывание и определены где-то в другом месте, а вот переменная b
имеет внешнее связывание и определена здесь (и доступна из других мест).
Другими словами, спецификатор extern
может иметь как семантику «импорта», так и семантику «экспорта», в зависимости от того, является ли объявление переменной или функции еще и определением.
Зарегистрируйтесь или войдите
Регистрация через Google Регистрация через Facebook Регистрация через почтуОтправить без регистрации
ПочтаНеобходима, но никому не показывается
Отправить без регистрации
ПочтаНеобходима, но никому не показывается
С++ — Действительно ли необходимо ключевое слово extern?
спросил
Изменено 10 лет назад
Просмотрено 4к раз
... #include "test1.h" инт основной(..) { количество << ааа <
aaa
определяется вtest1.h
, и я не использовал ключевое слово extern, но все же могу сослаться наaaa
.Так что я сомневаюсь, что
extern
действительно необходим?1
- С++
- внешний
extern
имеет свои применения. Но в основном это касается «глобальных переменных», которые не одобряются. Основная идеяextern
состоит в том, чтобы объявить вещи с внешней связью. Таким образом, это своего рода противоположностьстатический
. Но внешняя связь во многих случаях является связью по умолчанию, поэтому в этих случаях вам не нуженextern
. Другое использованиеextern
: Он может превращать определения в объявления. Примеры:внешний интервал i; // Объявление i с внешней связью // (только сообщает компилятору о существовании i) инт я; // Определение i с внешней связью // (фактически резервирует память, не должно быть в заголовочном файле) константа int f = 3; // Определение f с внутренней связью (из-за константы) // (Это относится только к C++, а не к C. В C f имело бы // внешняя ссылка.) В C++ совершенно нормально поместить // что-то вроде этого в заголовочный файл. внешняя константа int g; // Объявление g с внешней связью // можно поместить в заголовочный файл extern const int g = 3; // Определение g с внешней связью // Не должно быть в заголовочном файле статический интервал т; // Определение t с внутренней связью.// может появиться где угодно. Каждая единица перевода, которая // у такой строки есть свой собственный объект t. Видите ли, это довольно сложно. Есть две ортогональные концепции: связь (внешняя и внутренняя) и вопрос объявления и определения. Ключевое слово
extern
может влиять на оба. Что касается связи, это противоположностьstatic
. Но значениеstatic
также перегружено и — в зависимости от контекста — управляет или не управляет связью. Еще одна вещь, которую он делает, - это контроль времени жизни объектов («статическое время жизни»). Но в глобальном масштабе все переменные уже имеют статическое время жизни, и некоторые люди подумали, что было бы неплохо переработать ключевое слово для управления связью (это я просто догадываюсь).Связывание в основном является свойством объекта или функции, объявленной/определенной в "пространстве имен". Если у него есть внутренняя связь, он не будет напрямую доступен по имени из других единиц перевода. Если он имеет внешнюю связь, должно быть только одно определение для всех единиц перевода (с исключениями, см. правило одного определения).
2 Я обнаружил, что лучший способ организовать ваши данные — это следовать двум простым правилам:
- Объявлять вещи только в заголовочных файлах.
- Определяйте вещи в файлах C (или cpp, но я буду использовать C здесь для простоты).
Под объявлением я подразумеваю уведомление компилятора о том, что вещи существуют, но не выделяет для них память. Сюда входят
typedef
,struct
,extern
и так далее.По определению, я обычно означает «выделить пространство для», например
int
и так далее.Если у вас есть строка вида:
инт ааа;в заголовочном файле, каждая единица компиляции (в основном определяемая как входной поток для компилятора - файл C вместе со всем, что он приносит с
Это вызовет проблемы, если вы свяжете вместе два объектных файла, для которых определен один и тот же символ (за исключением некоторых ограниченных обстоятельств, таких как#include
, рекурсивно) получит свою собственную копию.const
).Лучший способ сделать это — определить эту переменную
aaa
в одном из ваших файлов C, а затем поместить:внешний внутренний ааа;в вашем заголовочном файле.
Обратите внимание, что если ваш заголовочный файл включен только в один файл C, это не проблема. Но в этом случае у меня, вероятно, даже не было бы заголовочного файла. Заголовочные файлы, на мой взгляд, предназначены только для обмена вещами между модулями компиляции.
10Если ваш test1.h имеет определение aaa и вы хотите включить файл заголовка в более чем одну единицу перевода, вы столкнетесь с ошибкой множественного определения, если только aaa не является постоянным. Лучше определить aaa в файле cpp и добавить определение extern в файл заголовка, который можно добавить в другие файлы в качестве заголовка.
Правило большого пальца для наличия переменной и константы в заголовочном файле
extern int a ;//Объявления данных const float pi = 3.141593 ;//Определение константПоскольку константа имеет внутреннюю связь в С++, любая константа, определенная в единице перевода, не будет видна другой единице перевода, но это не относится к переменной, у которой есть внешняя связь, т. Е. Они видны для другой единицы перевода. Помещение определения переменной в заголовок, который используется в другой единице перевода, приведет к многократному определению переменной, что приведет к ошибке множественного определения.
В этом случае
внешний
не нужен. Extern необходим, когда символ объявлен в другой единице компиляции.При использовании директивы предварительной обработки
1#include
включаемый файл копируется вместо директивы. В этом случае вам не нуженextern
, потому что компилятор уже знаетaaa
.Если aaa не определен в другой единице компиляции, вам не нужен extern, в противном случае он вам нужен.
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google Зарегистрироваться через Facebook Зарегистрируйтесь, используя электронную почту и парольОпубликовать как гость
Электронная почтаОбязательно, но не отображается
Опубликовать как гость
Электронная почтаТребуется, но не отображается
Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.
Руководство по NASM
Руководство по NASMСледующая глава | Предыдущая глава | Содержание | Индекс
NASM, хотя он пытается избежать бюрократии ассемблеров, таких как MASM и TASM, тем не менее, вынуждены поддерживать и несколько директив. Они описаны в этой главе.
Директивы NASM бывают двух типов: директивы уровня пользователя и примитивных директив. Как правило, каждая директива имеет уровень пользователя. форма и примитивная форма. Почти во всех случаях мы рекомендуем пользователям использовать пользовательские формы директив, реализованные в виде макросов которые называют примитивными формами.
Примитивные директивы заключаются в квадратные скобки; уровень пользователя директивы нет.
В дополнение к универсальным директивам, описанным в этой главе, каждая Формат объектного файла может опционально содержать дополнительные директивы для контролировать определенные функции этого формата файла. Эти Директивы , специфичные для формата, задокументированы вместе с форматами которые их реализуют, в главе 7.
6.1
БИТЫ
: Указание режима целевого процессораДиректива
BITS
указывает, будет ли NASM должен генерировать код, предназначенный для работы на процессоре, работающем в 16-битном режим, 32-битный режим или 64-битный режим. СинтаксисБИТ XX
, где ХХ равно 16, 32 или 64.В большинстве случаев вам не нужно использовать
BITS
явно.из
,кофф
,эльф
,мачо
,win32
иформаты объектов win64
, предназначенные для использования в 32-разрядных или 64-разрядных операционных системах все заставляют NASM выбирать 32-разрядную или 64-битный режим соответственно по умолчанию.объект
Формат объекта позволяет указать каждый сегмент, который вы определяете, какUSE16
илиUSE32
и NASM соответствующим образом установит свой режим работы, поэтому использованиеBITS Директива
снова не нужна.Наиболее вероятная причина использования
BITS
директива заключается в написании 32-битного или 64-битного кода в плоском двоичном файле; Это потому что выходной форматbin
по умолчанию 16-битный режим в ожидании того, что он будет чаще всего использоваться для написания DOS. COM
программы, DOS.SYS
драйверы устройств и программное обеспечение загрузчика.Вы делаете не нужно указать
БИТ 32
просто для того, чтобы использовать 32-битные инструкции в 16-битной программе DOS; если вы сделать, ассемблер сгенерирует неправильный код, потому что он будет писать код, ориентированный на 32-битную платформу, для запуска на 16-битной.Когда NASM находится в режиме
BITS 16
, инструкции которые используют 32-битные данные, имеют префикс 0x66 байт, а те, которые ссылаются на 32-битные адреса имеют префикс 0x67. ВBITS 32
режим, верно обратное: 32-битный инструкции не требуют префиксов, тогда как инструкции, использующие 16-битные данные нужен 0x66, а тем, кто работает с 16-битными адресами, нужен 0x67.Когда NASM находится в режиме
BITS 64
, большинство инструкции работают так же, как и дляБИТ 32
режим. Однако есть еще 8 общих и регистры SSE, а 16-битная адресация больше не поддерживается.Размер адреса по умолчанию — 64 бита; можно выбрать 32-битную адресацию с префиксом 0x67. Однако размер операнда по умолчанию по-прежнему составляет 32 бита. а префикс 0x66 выбирает 16-битный размер операнда.
Префикс REX
используется как для выбора 64-битного операнда размера и для доступа к новым регистрам. NASM автоматически вставляет REX префиксы, когда это необходимо.При использовании префикса
REX
процессор не знает, как адресовать AH, BH, CH или DH (высокий 8-битный устаревший) регистры. Вместо этого можно получить доступ к младшим 8 битам SP, BP SI и DI регистрируются как SPL, BPL, SIL и DIL соответственно; но только когда используется префикс REX.
БИТ 9Директива 0014 имеет точно эквивалентную примитивная форма,
[БИТЫ 16]
,[БИТЫ 32]
и[БИТЫ 64]
. Форма уровня пользователя представляет собой макрос, который не имеет никакой функции, кроме вызова примитивной формы.Обратите внимание, что место необходимо, т. е.
БИТС32
будет ли работать , а не !6.1.1
USE16
иUSE32
: Псевдонимы для BITS"
USE16
" и `USE32
' директивы могут быть использованы вместо `БИТ 16
'и `BITS 32
', для совместимости с другими монтажники.6.2
ПО УМОЛЧАНИЮ
: изменить настройки ассемблера по умолчаниюДиректива
DEFAULT
изменяет ассемблер значения по умолчанию. Обычно NASM по умолчанию работает в режиме, в котором программист ожидается, что большинство функций будет явно указано напрямую. Однако это иногда неприятный, так как явная форма почти единственная человек хочет использовать.В настоящее время
ПО УМОЛЧАНИЮ
можно установитьREL
иАБС
иБНД
иНОБНД
.6.2.1
REL
иABS
: RIP-относительная адресацияУстанавливает, будут ли выполняться безрегистровые инструкции в 64-битном режиме.
RIP
- относительный или нет. По умолчанию они абсолютное значение, если оно не переопределено спецификаторомREL
. (см. раздел 3.3). Однако, еслиУСТАНОВЛЕН ОТНОСИТЕЛЬ ПО УМОЛЧАНИЮ
,REL
используется по умолчанию, если неСпецификатор ABS
, , за исключением случаев, когда используется с FS или Переопределение сегмента GS .Особое обращение с
FS
иКоррекция GS
связана с тем, что эти регистры обычно используются в качестве указателей потоков или других специальных функций. в 64-битном режиме и генерируетRIP
-относительный адреса будут очень запутанными.
СТАНДАРТ ПО УМОЛЧАНИЮ
отключен сАБС ПО УМОЛЧАНИЮ
.6.2.2
БНД
иНОБНД
:БНД
префиксЕсли установлено
DEFAULT BND
, все префиксы bnd доступные инструкции, следующие за этой директивой, имеют префикс bnd. К отменить его, можно использовать префиксNOBND
.ПО УМОЛЧАНИЮ BND вызовите Фу; BND будет иметь префикс вызов nobnd foo ; BND НЕ будет иметь префикс
ПО УМОЛЧАНИЮ NOBND
можно отключитьПО УМОЛЧАНИЮ BND
и затемПрефикс BND
будет добавлен только тогда, когда явно указано в коде.
ПО УМОЛЧАНИЮ BND
считается нормальным конфигурация для написания кода с поддержкой MPX.6.3
РАЗДЕЛ
илиСЕГМЕНТ
: изменение и определение разделовДиректива
РАЗДЕЛ
(СЕГМЕНТ
является точно эквивалентным синонимом) изменяет, в каком разделе выходного файла будет код, который вы пишете собран в. В некоторых форматах объектных файлов количество и имена секции фиксируются; в других пользователь может составить столько, сколько пожелает. ОтсюдаРАЗДЕЛ
иногда может выдавать ошибку сообщение или может определить новый раздел, если вы попытаетесь переключиться на раздел которого (пока) нет.Форматы объектов Unix и объект
bin
формат (но см. раздел 7.1.3), все поддерживают стандартизированные имена разделов.text
,.data
и.bss
для разделы кода, данных и неинициализированных данных. Форматobj
, напротив, не распознает эти имена разделов как специальные, и действительно удалит начальные период любого имени раздела, в котором он есть.6.3.1 Макрос
__SECT__
Директива
SECTION
необычна тем, что ее форма пользовательского уровня функционирует иначе, чем его примитивная форма. примитивная форма,[РАЗДЕЛ xyz]
, просто переключает текущий целевой раздел на заданный. Форма уровня пользователя,SECTION xyz
, однако, сначала определяет однострочный макрос__SECT__
в качестве примитива[РАЗДЕЛ]
директива, которую он собирается издать, а потом выдает. Таким образом, директива уровня пользователяРАЗДЕЛ . textрасширяется до двух строк
%define __SECT__ [РАЗДЕЛ .текст] [РАЗДЕЛ .текст]Пользователи могут счесть полезным использовать это в своих макросах. Для Например, макрос
writefile
, определенный в раздел 4.3.3 может быть полезен переписан в следующей более сложной форме:%макрос записи в файл 2+ [раздел .данные] %%стр: дб %2 %%endstr: __SECT__ мов дх,%%стр mov cx,%%endstr-%%str мов бх,%1 мов ах, 0x40 интервал 0x21 %endmacroЭта форма макроса, после передачи строки на вывод, сначала переключается временно в раздел данных файла, используя примитивную форму директиву
SECTION
, чтобы не изменять__SECT__
. Затем он объявляет свою строку в данных раздел, а затем вызывает__SECT__
для обратного переключения на в зависимости от того, в каком разделе ранее работал пользователь. позволяет избежать необходимости в предыдущей версии макроса включатьJMP
инструкция для перехода по данным, а также не выходит из строя, если в сложномФормат OBJ
модуль, пользователь потенциально может собирать код в любом из нескольких отдельные разделы кода.6.4
ABSOLUTE
: Определение абсолютных метокДирективу
ABSOLUTE
можно рассматривать как альтернативная формаРАЗДЕЛ
: вызывает последующий код должен быть направлен не на физический раздел, а на гипотетический раздел, начинающийся с заданного абсолютного адреса. Единственный инструкции, которые вы можете использовать в этом режиме,Семейство РЭСБ
.
АБСОЛЮТ
используется следующим образом:абсолютный 0x1A kbuf_chr resw 1 kbuf_free resw 1 кбуф резв 16В этом примере описывается раздел области данных BIOS ПК в сегменте адрес 0x40: приведенный выше код определяет
kbuf_chr
как быть 0x1A,kbuf_free
быть 0x1C иkbuf
на 0x1E.Пользовательская форма
ABSOLUTE
, как и уРАЗДЕЛ
, переопределяет__SECT__
макрос при его вызове.
STRUC
иENDSTRUC
определяются как макросы, использующиеABSOLUTE
(и также__SECT__
).
АБСОЛЮТНЫЙ
не обязательно должен быть абсолютным константа в качестве аргумента: она может принимать выражение (на самом деле критическое выражение: см. раздел 3.8), и оно может быть значением в сегменте. Например, TSR может повторно использовать свой код установки. как BSS во время выполнения, например:орг 100ч ; это программа .COM установка джмп; код установки идет последним ; здесь проходит жилая часть ТСР настраивать: ; теперь напишите код, который устанавливает TSR здесь абсолютная установка runtimevar1 resw 1 runtimevar2 резд 20 tsr_end:Это определяет некоторые переменные «поверх» кода установки, так что после установка завершена, пространство, которое она заняла, может быть повторно использовано в качестве данных хранилище для работающего TSR. Символ `tsr_end' можно использовать для вычисления общий размер части ТСР, которую необходимо сделать резидентной.
6.5
ВНЕШНИЙ
: Импорт символов из других модулей
EXTERN
аналогичен директиве MASMEXTRN
и ключевое слово Cextern
: используется для объявления символа, который нигде в собираемом модуле не определено, но предполагается определен в каком-то другом модуле, и на него должен ссылаться этот модуль. Нет каждый формат объектного файла может поддерживать внешние переменные:бин
формат не может.
EXTERN
директива принимает столько аргументов как вам нравится. Каждый аргумент является именем символа:внешний _printf внешний _sscanf,_fscanfНекоторые форматы объектных файлов предоставляют дополнительные возможности для
ВНЕШНЯЯ директива
. Во всех случаях доп. функции используются путем добавления двоеточия к имени символа, за которым следует объектно-форматный текст. Например,obj
формат позволяет объявить, что база сегментов по умолчанию внешнего должна быть группаdgroup
с помощью директиваextern _variable:wrt dgroupПримитивная форма
EXTERN
отличается от пользовательского уровня только тем, что может принимать только один аргумент за раз: поддержка нескольких аргументов реализована на уровне препроцессора.Вы можете объявить ту же переменную, что и
EXTERN
более одного раза: NASM спокойно проигнорирует второй и последующие передекларации. Вы не можете объявить переменную какВНЕШНИЙ
, а также что-то еще.6.6
GLOBAL
: Экспорт символов в другие модули
ГЛОБАЛЬНЫЙ
это другой конецEXTERN
: если один модуль объявляет символ какEXTERN
и ссылается на него, то во избежание ошибки компоновщика, какой-то другой модуль должен на самом деле определять символ и объявите его какGLOBAL
. Некоторые ассемблеры используют имяPUBLIC
для этой цели.
ГЛОБАЛЬНЫЙ 9Директива 0014, применяемая к символу, должна появляются до определения символа.
GLOBAL
использует тот же синтаксис, что иEXTERN
, за исключением того, что он должен относиться к символам которые являются определенными в том же модуле, что иГЛОБАЛЬНАЯ директива
. Например:глобальный _main _основной: ; какой-то код
ГЛОБАЛЬНЫЙ
, какВНЕШНИЙ
, позволяет форматам объектов определять частные расширения с помощью двоеточия. 9Например, формат объекта 0013 elf позволяет указать являются ли глобальные элементы данных функциями или данными:глобальный хэш-поиск:функция, хеш-таблица:данныеКак и
EXTERN
, примитивная формаGLOBAL
отличается от пользовательской формы только тем, что что он может принимать только один аргумент за раз.6.7
ОБЩИЙ
: Определение областей общих данныхДиректива
COMMON
используется для объявления общих переменных . Общая переменная очень похожа на глобальную переменную объявлен в секции неинициализированных данных, так чтообщий инвар 4аналогичен по функциям
глобальная переменная раздел .bss интвар резд 1Разница в том, что если несколько модулей определяют один и тот же общий переменная, то во время компоновки эти переменные будут объединены и ссылки на
intvar
во всех модулях будут указывать на тот же кусок памяти.Аналогично
ГЛОБАЛЬНЫЙ
иВНЕШНИЙ
,ОБЩИЙ
поддерживает расширения, специфичные для формата объекта. Например, Форматobj
позволяет использовать общие переменные NEAR или FAR, а форматelf
позволяет указать требования выравнивания общей переменной:общий commvar 4:рядом ; работает в ОБЖ общий интрарей 100:4 ; работает в ELF: выравнивание по 4 байтамЕще раз, как
ВНЕШНИЙ
иГЛОБАЛЬНЫЙ
, примитивная формаCOMMON
отличается от пользовательской формы только что он может принимать только один аргумент за раз.6.8
ЦП
: определение зависимостей ЦПДиректива
CPU
ограничивает сборку теми инструкции, которые доступны на указанном ЦП.Опции:
ЦП 8086
Сборка только набора инструкций 8086CPU 186
Инструкции по сборке до 80186 Набор инструкцийCPU 286
Инструкции по сборке до 286 Набор инструкцийCPU 386
Инструкции по сборке до 386 Набор инструкцийЦП 486
486 набор инструкцийЦП 586
Набор инструкций PentiumЦП PENTIUM
То же, что и 586CPU 686
Набор инструкций P6ЦП PPRO
То же, что и 686ЦП P2
То же, что и 686CPU P3
Pentium III (Katmai) наборы инструкцийЦП KATMAI
То же, что и P3ЦП P4
Pentium 4 (Willamette) набор инструкцийЦП WILLAMETTE
То же, что и P4CPU PRESCOTT
Набор инструкций PrescottПроцессор X64
x86-64 (x64/AMD64/Intel 64) Набор инструкцийCPU IA64
IA64 CPU (в режиме x86) инструкция наборВсе параметры нечувствительны к регистру. Все инструкции будут выбраны только если они применимы к выбранному процессору или ниже. По умолчанию все инструкции доступны.
6.9
FLOAT
: Обработка констант с плавающей запятойПо умолчанию константы с плавающей запятой округляются до ближайшего, а IEEE денормалы поддерживаются. Следующие параметры могут быть установлены, чтобы изменить это поведение:
FLOAT DAZ
Флеш денормализует до нуляFLOAT NODAZ
Не сбрасывать денормали до нуля (по умолчанию)FLOAT NEAR
Округление до ближайшего (по умолчанию)FLOAT UP
Округление вверх (в сторону +бесконечности)FLOAT DOWN
Округление в меньшую сторону (в сторону -бесконечности)FLOAT ZERO
Округление до нуляFLOAT DEFAULT
Восстановить настройки по умолчаниюСтандартные макросы
__FLOAT_DAZ__
,__FLOAT_ROUND__
и__FLOAT__
содержат текущее состояние, если программист избегал использования примитивной формы в скобках, ([ПЛАВАЮЩАЯ]
).