Ассемблер. настройка среды разработки
Содержание:
- 2.2.3 NASM не хранит типы переменных
- 3.1 Однострочные макросы
- 8.2.5 Вызов процедур вне библиотеки
- Entwicklung
- 8.1.1 Внешние символьные имена
- 6.1.2 bin-расширение директивы SECTION
- 6.2 obj: Объектные файлы OMF Microsoft
- NASM — The Netwide Assembler is 80×86 assembler designed for portability and modularity.
- 6.5.3 elf-расширения директивы GLOBAL
- 6.2.4 IMPORT: Импортирование символов из DLL
- Defining Data and Reserving Space
- Примеры программ для различных операционных систем
- 4.3 Изменение и определение секций
- “Hello, World”–Take Five, with WriteConsoleA
- Using NASM on Windows
- RDOFF
- 6.5.4 elf-расширение директивы COMMON
- 6.6 aout: Объектные файлы a.out Линукс
- 6.7 aoutb: Объектные файлы a.out NetBSD/FreeBSD/OpenBSD
- 6.8 as86: Объектные файлы as86 Линукс
- 6.9 rdf: Перемещаемые динамические объектные файлы
2.2.3 NASM не хранит типы переменных
NASM не запоминает определямые вами типы переменных. Поскольку MASM эти вещи
запоминает, то при встрече var dw 0 он запомнит,
что вы определили var как пременную размером в
слово и затем будет способен разрешить неопределенность при появлении инструкции
mov var,2. NASM же преднамеренно не будет помнить
ничто относительно символа var за исключением того,
где он начинается, поэтому вы должны явно указывать mov
word ,2.
В соответствии с этим, NASM не поддерживает инструкции LODS,
MOVS, STOS, SCAS, CMPS, INS или OUTS, поддерживаются
только их формы вида LODSB, MOVSW и SCASD,
где явно задается размер компонентов обрабатываемой строки.
3.1 Однострочные макросы
3.1.1 Обычный способ: %define
Однострочные макросы описываются при помощи директивы препроцессора %define. Определения работают подобно языку С; т.е. вы можете сделать что-то наподобие
%define ctrl 0x1F & %define param(a,b) ((a)+(a)*(b)) mov byte , ctrl ’D’
что будет развернуто в
mov byte , 0x1F & ’D’
Если однострочный макрос содержит символы, вызывающие другой макрос, то развертывание первого осуществляется в процессе вызова, а не при определении. Таким образом код
%define a(x) 1+b(x) %define b(x) 2 *x mov ax,a(8)
будет обработан как и ожидается — mov ax,1+2*8, даже если при описании a макрос b еще не определен.
Макросы, описываемые конструкцией %define, регистрочувствительны: после %define foo bar только foo будет развернуто в bar, но никак не Foo или FOO. При использовании вместо %define конструкции %idefine (‘i’ от слова ‘insensitive’) вы можете сразу описать все варианты комбинации строчных и прописных букв в имени макроса, поэтому %idefine foo bar будет развертывать в bar не только foo, но и Foo, FOO, fOO и т.п.
Существует механизм, следящий за рекурсивным развертыванием макросов, предотвращающий циклические ссылки и бесконечные циклы. Когда это случается, препроцессор будет развертывать только первое вхождение макроса. Следовательно, если вы введете
%define a(x) 1+a(x) mov ax,a(3)
макрос a(3) будет развернут единожды, т.е. в конструкцию 1+a(3) и дальнейшее развертывание производиться не будет. Данная возможность может быть полезна.
Вы можете перегружать однострочные макросы: если вы напишете
%define foo(x) 1+x %define foo(x,y) 1+x*y
препроцессор, подсчитав передаваемые вами параметры, корректно обработает оба типа вызова макроса: foo(3) будет развернуто в 1+3, в то время как foo(ebx,2) — в 1+ebx*2. Однако, если вы напишете
%define foo bar
последующие описания foo будут запрещены: макрос без параметров не допускает описание макроса с тем же именем, но с параметрами, и наоборот.
Несмотря на это, переопределение однострочных макросов не запрещается: вы можете легко описать макрос как
%define foo bar
и затем, в том же самом исходном файле, переопределить его как
%define foo baz
Когда макрос foo будет вызван, он развернется в соответствии с самым поздним своим описанием. Это полезно в основном при описании однострочных макросов с конструкцией %assign (см. параграф ).
Вы можете переопределить однострочные макросы при помощи ключа ‘-D’ командной строки Yasm: см. параграф .
3.1.2 Расширение %define: %xdefine
Чтобы иметь ссылку на внутренний однострочный макрос
Допустим, что у вас есть следующий код
%define isTrue 1 %define isFalse isTrue %define isTrue 0 val1: db isFalse %define isTrue 1 val2: db isFalse
В таком случае, val1 равен 0, а val2 — 1. Это потому, что когда однострочный макрос описывается конструкцией %define, он развернется только тогда, когда будет вызван. Если isFalse развертывается в isTrue, то развернуто будет текущее значение макроса isTrue. Первый её вызов даст 0, а второй 1.
Если бы вы хотели, чтобы isFalse развертывался в значение, назначенное для внутреннего макроса isTrue во время когда isFalse определялся, вы должны изменить вышеприведеный код, чтобы он использовал конструкцию %xdefine.
%xdefine isTrue 1 %xdefine isFalse isTrue %xdefine isTrue 0 val1: db isFalse %xdefine isTrue 1 val2: db isFalse
Теперь каждый раз, когда isFalse вызывается, он развернется в 1, т.е. внутренний макрос isTrue развернется во время определения isFalse.
8.2.5 Вызов процедур вне библиотеки
Вызов процедур извне вашей разделяемой библиотеки может быть
осуществлен через таблицу сборки процедуры(procedure linkage table),
или ТСП(PLT). ТСП помещается по известному смещению от того места, куда
загружена библиотека, поэтому библиотечный код может делать вызовы
к ТСП в переносимом (не зависимого от места) стиле. Внутри ТСП есть
код для перехода на смещения, расположенные в ГТС, поэтому вызовы
из функции к другим разделяемым библиотекам или к коду в главной программе
могут быть незаметно направлены на их реальные местоположения.
Чтобы вызывать внешний код, необходимо использовать другой специальный PIC
(переносимый код) тип переноса, WRT ..plt. Это
намного проще, чем использовать ГТС: просто замещается вызовы, например, такие
CALL printf на версию, использующую ТСП
CALL printf WRT ..plt.
Entwicklung
Die erste Version, Version 0.90, wurde im Oktober 1996 veröffentlicht.
Am 28. November 2007 wurde Version 2.00 veröffentlicht, die Unterstützung für x86-64- Erweiterungen hinzufügt . Die Entwicklungsversionen werden nicht auf SourceForge.net hochgeladen . Stattdessen werden sie mit binären Snapshots, die auf der Projektwebseite verfügbar sind, in GitHub eingecheckt .
Eine Suchmaschine für NASM-Dokumentation ist ebenfalls verfügbar.
Im Juli 2009 wurde NASM ab Version 2.07 unter der vereinfachten (2-Klausel) BSD-Lizenz veröffentlicht. Da NASM unter LGPL lizenziert war , führte dies zuvor zur Entwicklung von Yasm, einer vollständigen Neufassung des NASM unter der . Yasm bot früher als NASM Unterstützung für x86-64 an. Es wurde auch die Unterstützung für die GNU Assembler- Syntax hinzugefügt .
8.1.1 Внешние символьные имена
Большинство 32-ух битных Си-компиляторов поддерживают конвенцию,
используемую в 16-ти битных компиляторах: имена всех глобальных
имен (функций или переменных) они определяют префиксом
“подчеркивание” (например: extrn_link в Си будет _extrnlink в
линкуемом файле), добавляемое к имени, действующем в Си-программе.
Правда, не все это делают: спецификация ELF указывает, что все имена
в Си-программе не имеют предваряющего подчеркивания в их
эквивалентах на языке ассемблера.
Старый Си-компилятор в Линуксе a.out, все компиляторы
для Win32, DJGPP, NetBSD и FreeBSD, все они используют предваряющее “подчеркивание”;
для этих компиляторов макросы cextern и ,
как они описаны в ,
будут работать. Для ELF, разумеется, предваряющее подчеркивание не используется.
6.1.2 bin-расширение директивы SECTION
Выходной формат bin расширяет директиву SECTION
(или SEGMENT), позволяя вам указывать требования
к выравниванию сегментов. Это делается путем добавления в конец строки определения
секции спецификатора ALIGN. Например, строка
section .data align=16
переключается на секцию .data и также указывает,
что эта секция должна быть выровнена в памяти по границе параграфа.
Спецификатор ALIGN указывает, сколько младших
бит в начальном адресе секции должны быть установлены в ноль. Указываемое значение
выравнивания может быть любой степенью двойки.
6.2 obj: Объектные файлы
OMF Microsoft
Файлы формата obj (исторически в NASM они называются
obj, а не omf), создаваемые
MASMом и TASMом, обычно «скармливаются» 16-битным DOS-компоновщикам, на выходе
которых получаются .EXE файлы. Этот формат используется
также в OS/2.
Формат obj предполагает расширение выходного файла
по умолчанию .obj.
obj не является исключительно 16-битным форматом:
NASM полностью поддерживает 32-битные расширения этого формата. В частности,
32-битный obj формат используется Win32-компиляторами
Borland, которые не применяют новый объектный формат win32
от Майкрософт.
Формат obj не определяет специальных имен сегментов:
вы можете называть ваши сегменты как угодно. Типичными именами сегментов obj
формата обычно являются CODE, DATA и BSS.
Если в вашем исходном файле до явного указания директивы SEGMENT
содержится код, NASM будет помещать его в собственный сегмент с именем __NASMDEFSEG.
Когда вы определяете сегменты в obj файле, NASM
воспринимает их имена как символы, поэтому вы можете легко получить адрес любого
определенного сегмента, например:
segment data dvar: dw 1234 segment code function: mov ax,data ; получение сегментного адреса данных mov ds,ax ; и помещение его в DS inc word ; теперь эта ссылка работает ret
Формат obj разрешает также использование операторов
SEG и WRT, поэтому
вы можете писать код, делающий что-то вроде
extern foo mov ax,seg foo ; получение сегмента foo mov ds,ax mov ax,data ; получение другого сегмента mov es,ax mov ax, ; это доступ к 'foo' mov ,bx ; так это делается
NASM — The Netwide Assembler is 80×86 assembler designed for portability and modularity.
NASM is an 80×86 assembler designed for portability and modularity. The project supports a range of object file formats including Linux a.out and ELF, COFF, Microsoft 16-bit OBJ and Win32. It will also output plain binary files.
Its syntax is designed to be simple and easy to understand, similar to Intel’s but less complex. It supports Pentium, P6, MMX, 3DNow! and SSE opcodes, and has macro capability. It includes a disassembler as well.
The Netwide Assembler grew out of an idea on comp.lang.asm.x86 (or possibly alt.lang.asm — I forget which), which was essentially that there didn’t seem to be a good free x86-series assembler around, and that maybe someone ought to write one.
— a86 is good, but not free, and in particular you don’t get any 32-bit capability until you pay. It’s DOS only, too.
— gas is free, and ports over DOS and Unix, but it’s not very good, since it’s designed to be a back end to gcc, which always feeds it correct code. So its error checking is minimal. Also, its syntax is horrible, from the point of view of anyone trying to actually write anything in it. Plus you can’t write 16-bit code in it (properly).
— as86 is Minix- and Linux-specific, and (my version at least) doesn’t seem to have much (or any) documentation.
— MASM isn’t very good, and it’s (was) expensive, and it runs only under DOS.
— TASM is better, but still strives for MASM compatibility, which means millions of directives and tons of red tape. And its syntax is essentially MASM’s, with the contradictions and quirks that entails (although it sorts out some of those by means of Ideal mode). It’s expensive too. And it’s DOS-only.
So here, for your coding pleasure, is NASM. At present it’s still in prototype stage — we don’t promise that it can outperform any of these assemblers. But please, please send us bug reports, fixes, helpful information, and anything else you can get your hands on (and thanks to the many people who’ve done this already! You all know who you are), and we’ll improve it out of all recognition. Again.
Installing NASM under Unix
NASM is an auto-configuring package: once you’ve unpacked it, cd to the directory it’s been unpacked into and type ./configure. This shell script will find the best C compiler to use for building NASM and set up Makefiles accordingly.
Once NASM has auto-configured, you can type make to build the nasm and ndisasm binaries, and then make install to install them in /usr/local/bin and install the man pages nasm.1 and ndisasm.1 in /usr/local/man/man1. Alternatively, you can give options such as —prefix to the configure script (see the file INSTALL for more details), or install the programs yourself.
NASM also comes with a set of utilities for handling the RDOFF custom object-file format, which are in the rdoff subdirectory of the NASM archive. You can build these with make rdf and install them with make rdf_install, if you want them.
If NASM fails to auto-configure, you may still be able to make it compile by using the fall-back Unix makefile Makefile.unx. Copy or rename that file to Makefile and try typing make. There is also a Makefile.unx file in the rdoff subdirectory.
6.5.3 elf-расширения директивы GLOBAL
Объектные файлы ELF могут содержать больше информации о глобальном символе,
чем просто его адрес: они могут содержать размер символа, а также его тип. Это
сделано не только для удобства при отладке, это просто необходимо, если программа
пишется в виде разделяемой библиотеки. Для задания дополнительной информации
NASM поддерживает некоторые расширения директивы GLOBAL.
Поставив после имени глобальной переменной двоеточие и написав function
или data (object является
синонимом data), вы можете указать, чем является
глобальная переменная функцией или объектом данных. Например, строка
global hashlookup:function, hashtable:data
экспортирует глобальный символ hashlookup как
функцию, а hashtable как объект данных.
После ввода спецификатора вы можете также указать в виде числового выражения
(которое может включать метки и даже опережающие ссылки) размер ассоциированных
с символом данных, например:
global hashtable:data (hashtable.end - hashtable) hashtable: db this,that,theother ; здесь некоторые данные .end:
Это заставит NASM автоматически подсчитать длину таблицы и поместить эту информацию
в символьную таблицу ELF.
Объявление типа и размера глобальных символов требуется при написании разделяемых
библиотек. Дополнительную информацию вы можете найти в .
6.2.4 IMPORT: Импортирование символов из DLL
Директива IMPORT определяет символ, импортируемый
из DLL и используемый например для написания в NASM библиотеки импорта. При
использовании директивы IMPORT вы должны объявить
символ как EXTERN.
Директива IMPORT требует указания двух параметров,
разделенных пробелом и являющихся соответственно именем импортируемого символа
и именем библиотеки, из которой он импортируется. Например:
import WSAStartup wsock32.dll
Третьим (необязательным) параметром является имя, под которым импортируемый
символ известен в соответствующей библиотеке. Этот параметр применяется в том
случае, если вы хотите, чтобы имя символа, используемое внутри вашего кода,
не совпадало с именем того же символа в библиотеке. Например:
import asyncsel wsock32.dll WSAAsyncSelect
Defining Data and Reserving Space
These examples come from Chapter 3 of the docs. To place data in memory:
db 0x55 ; just the byte 0x55 db 0x55,0x56,0x57 ; three bytes in succession db 'a',0x55 ; character constants are OK db 'hello',13,10,'$' ; so are string constants dw 0x1234 ; 0x34 0x12 dw 'a' ; 0x61 0x00 (it's just a number) dw 'ab' ; 0x61 0x62 (character constant) dw 'abc' ; 0x61 0x62 0x63 0x00 (string) dd 0x12345678 ; 0x78 0x56 0x34 0x12 dd 1.234567e20 ; floating-point constant dq 0x123456789abcdef0 ; eight byte constant dq 1.234567e20 ; double-precision float dt 1.234567e20 ; extended-precision float
There are other forms; check the NASM docs. Later.
To reserve space (without initializing), you can use the following pseudo instructions. They
should go in a section called (you’ll get an error if you try to use them in
a section):
buffer: resb 64 ; reserve 64 bytes wordvar: resw 1 ; reserve a word realarray: resq 10 ; array of ten reals
Примеры программ для различных операционных систем
Это «Привет мир!» программа для ДОС Операционная система.
раздел .текстorg 0x100 mov ах, 0x9 mov dx, Здравствуйте int 0x21 mov топор, 0x4c00 int 0x21раздел .данныеЗдравствуйте: db 'Привет мир!', 13, 10, '$'
Эквивалентная программа для Linux:
Глобальный _Начнитераздел .текст_Начните: mov eax, 4 ; записывать mov ebx, 1 ; стандартный вывод mov ecx, сообщение mov edx, msg.len int 0x80 ; написать (stdout, msg, strlen (msg)); xor eax, msg.len ; инвертировать возвращаемое значение из write () xchg eax, ebx ; значение для exit () mov eax, 1 ; выход int 0x80 ; выход(...)раздел .данныесообщение: db "Привет мир!", 10.len: равно $ - сообщение
Пример аналогичной программы для Майкрософт Виндоус:
Глобальный _основнойвнешний _MessageBoxA @ 16внешний _ExitProcess @ 4раздел код использовать32 clжопа=код_основной: От себя dword ; UINT uType = MB_OK От себя dword заглавие ; LPCSTR lpCaption От себя dword знамя ; LPCSTR lpText От себя dword ; HWND hWnd = NULL вызов _MessageBoxA @ 16 От себя dword ; UINT uExitCode вызов _ExitProcess @ 4раздел данные использовать32 clжопа=данные баннер: db 'Привет мир!', заглавие: db 'Здравствуйте',
Ниже представлена 64-битная программа для Apple. OS X который вводит нажатие клавиши и показывает его на экране
Глобальный _Начнитераздел .данные Строка запроса: db «Введите символ:» query_string_len: равно $ - Строка запроса out_string: db "Вы ввели:" out_string_len: равно $ - out_stringраздел .bss in_char: resw 4раздел .текст_Начните: mov rax, 0x2000004 ; поместите код системного вызова записи в регистр rax mov rdi, 1 ; скажите ядру использовать stdout mov RSI, Строка запроса ; rsi - это то место, где ядро ожидает найти адрес сообщения mov rdx, query_string_len ; а rdx - это то место, где ядро ожидает найти длину сообщения системный вызов ; читать в персонаже mov rax, 0x2000003 ; читать системный вызов mov rdi, ; стандартный ввод mov RSI, in_char ; адрес для хранения, заявленный в разделе .bss mov rdx, 2 ; получить 2 байта из буфера ядра (один для возврата каретки) системный вызов ; показать пользователю вывод mov rax, 0x2000004 ; написать системный вызов mov rdi, 1 ; стандартный вывод mov RSI, out_string mov rdx, out_string_len системный вызов mov rax, 0x2000004 ; написать системный вызов mov rdi, 1 ; стандартный вывод mov RSI, in_char mov rdx, 2 ; второй байт - применить возврат каретки, ожидаемый в строке системный вызов ; выйти из системного вызова mov rax, 0x2000001 ; выйти из системного вызова xor rdi, rdi системный вызов
4.3 Изменение и определение секций
4.3.1 SECTION и SEGMENT
Директива SECTION (SEGMENT — это абсолютно эквивалентный синоним) указывает, в какую секцию выходного файла будет ассемблирован код, который вы пишете. В некоторых объектных форматах количество и имена секций фиксированы; в других пользователь может сделать их столько, сколько захочет. Следовательно директива SECTION может либо вызвать сообщение об ошибке, либо определить новую секцию, если вы попытаетесь переключиться на секцию, которая (еще) не существует.
4.3.2 Стандартизированные названия секции
Форматы Unix и формат bin объекта поддерживают стандартизированные названия секции .text для кода, .data для данных и .bss для неинициализированных данных. Формат obj наоборот, не признает эти названия секции специальными и более того, удаляет ведущую точку в названии любой секции у которого она есть.
4.3.3 Макрос __SECT__
Директива SECTION необычна тем, что ее пользовательская форма функционально отличается от примитивной. Примитивная форма просто переключает текущую секцию на указанную. Пользовательская форма SECTION xyz сначала определяет однострочный макрос __SECT__ для примитивной директивы , которую собирается выдать, и затем выдает ее. Таким образом, пользовательская директива
SECTION .text
развернется в две строки:
%define __SECT__
“Hello, World”–Take Five, with WriteConsoleA
In the previous example, we used the function WriteFile as the method to write to the console. Technically, the console is a logical file, so there is nothing wrong with that. However, there is a dedicated routine to write text to the console, known as WriteConsoleA. Let us use that now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
BITS 32] extern ExitProcess import ExitProcess kernel32.dll extern GetStdHandle import GetStdHandle kernel32.dll extern WriteConsoleA import WriteConsoleA kernel32.dll segment .data use32 msg db "Hello, World", written dword ? segment .code use32 ..start: push -11 call mov ebx, eax push lea eax, written push eax push 13 push offset msg push ebx call push call |
Using NASM on Windows
I’m not sure what the system calls are on Windows, but I do know that if you want to assemble and link with the C library, you have to understand the x64 conventions. Read them. You will learn such things as:
- The first four integer parameters are passed in RCX, RDX, R8, and R9. The rest are to be pushed on the stack.
- The callee must preserve RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15.
- The first four floating point parameters are passed in, you guessed it, XMM0, XMM1, XMM2, and XMM3.
- Return values go in RAX or XMM0.
IMPORTANT: There’s one thing that’s really hard to find in any documentation: the x64 calling convention requires you to allocate 32 bytes of shadow space before each call, and remove it after your call. This means your “hello world” program looks like this:
hello.asm
; ---------------------------------------------------------------------------------------- ; This is a Win64 console program that writes "Hello" on one line and then exits. It ; uses puts from the C library. To assemble and run: ; ; nasm -fwin64 hello.asm && gcc hello.obj && a ; ---------------------------------------------------------------------------------------- global main extern puts section .text main: sub rsp, 28h ; Reserve the shadow space mov rcx, message ; First argument is address of message call puts ; puts(message) add rsp, 28h ; Remove shadow space ret message: db 'Hello', 0 ; C strings need a zero byte at the end
Did you notice we actually reserved 40 bytes? Thirty-two bytes of shadow space is a minimum requirement. In our function, we are calling another function, so our stack must be aligned on a 16-byte boundary. When is called, the return address (8 bytes) was pushed, so we have to “add” an extra 8 bytes to the shadow space.
RDOFF
Разработан | Джулиан Холл |
---|---|
Тип формата | Формат объектного файла |
Контейнер для | Код объекта |
Формат перемещаемого динамического объектного файла (RDOFF) используется разработчиками для проверки целостности возможностей вывода объектного файла NASM. Он в значительной степени основан на внутренней структуре NASM, по существу состоящей из заголовка, содержащего сериализацию вызовов функций выходного драйвера, за которыми следует массив разделов, содержащих исполняемый код или данные. Инструменты для использования формата, включая компоновщик и загрузчик, включены в дистрибутив NASM.
До выпуска версии 0.90 в октябре 1996 года NASM поддерживал вывод только исполняемых файлов в плоском формате (например, файлов DOS COM ). В версии 0.90 Саймон Тэтхэм добавил поддержку интерфейса вывода объектного файла и файлов DOS .OBJ только для 16-битного кода.
Таким образом, у NASM не было 32-битного объектного формата. Чтобы устранить этот недостаток и в качестве упражнения по изучению интерфейса объектных файлов, разработчик Джулиан Холл собрал первую версию RDOFF, которая была выпущена в версии NASM 0.91.
Начиная с этой первоначальной версии, было одно крупное обновление формата RDOFF, которое добавило индикатор длины записи для каждой записи заголовка, позволяя программам пропускать записи, формат которых они не распознают, и поддерживать несколько сегментов; RDOFF1 поддерживает только три сегмента: текст , данные и bss (содержащий неинициализированные данные).
6.5.4 elf-расширение директивы COMMON
ELF позволяет задавать требования к выравниванию общих переменных. Это делается
путем помещения числа (которое должно быть степенью двойки) после имени и размера
общей переменной и отделения этого числа (как обычно) двоеточием. Например,
массив двойных слов, который должен быть выровнен по двойным словам:
common dwordarray 128:4
Эта строка объявляет массив размером 128 байт и требует, чтобы он был выровнен
по 4-байтной границе.
6.6 aout: Объектные файлы
a.out Линукс
Формат aout генерирует объектные файлы a.out
в форме, используемой устаревшими Линукс системами. (Он отличается от других
объектных файлов a.out магическим числом в первых
четырех байтах файла. Также некоторые реализации a.out,
например NetBSD, поддерживают позиционно-независимый код, который реализация
Линукс не знает).
Формат a.out подразумевает расширение выходных
файлов по умолчанию .o.
Этот формат очень простой. Он не поддерживает специальных директив и символов,
не использует SEG или WRT
и в нем нет расширений никаких стандартных директив. Он поддерживает только
три стандартных секции с именами .text, .data и
.bss.
6.7 aoutb: Объектные файлы
a.out NetBSD/FreeBSD/OpenBSD
Формат aoutb генерирует объектные файлы a.out
в форме, используемой различными BSD-клонами UNIX: NetBSD, FreeBSD и OpenBSD.
Для большинства объектных файлов этот формат не отличается от aout
за исключением магического числа в первых четырех байтах файла. Однако формат
поддерживает (как и формат elf) позиционно-независимый
код, поэтому вы можете использовать его для написания разделяемых библиотек
BSD.
Расширение объектных файлов формата aoutb по умолчанию
.o.
Формат не поддерживает специальных директив и символов и имеет только три стандартных
секции с именами .text, .data и .bss.
Несмотря на это, для обеспечения типов перемещений в позиционно-независимом
коде он поддерживает использование WRT так же,
как это делает elf. Более подробно это описано
в .
aoutb, как и elf
поддерживает также расширение директивы GLOBAL:
см. .
6.8 as86: Объектные файлы
as86 Линукс
16-битный ассемблер Линукс as86 имеет свой собственный
нестандартный формат объектных файлов. Хотя его компаньон компоновщик ld86
выдает что-то близкое к обычным бинарникам a.out,
объектный формат, используемый для взаимодействия между as86
и ld86, все же не является a.out.
NASM на всякий случай поддерживает данный формат как as86.
Расширение выходного файла по умолчанию для данного формата .o.
Формат as86 это очень простой объектный
формат (с точки зрения NASM). Он не поддерживает специальных директив и символов,
не использует SEG и WRT,
и в нем нет никаких расширений стандартных директив. Он поддерживает только
три стандартных секции с именами .text, .data и
.bss.
6.9 rdf: Перемещаемые динамические
объектные файлы
Выходной формат rdf создает объектные файлы RDOFF.
RDOFF это «доморощенный» формат объектных файлов, разработанный вместе
с NASM и отражающий в себе внутреннюю структуру ассемблера.
RDOFF не используется никакими широко известными операционными системами. Однако
тот, кто пишет собственную систему, возможно захочет использовать его в качестве
собственного объектного формата, так как разработан он прежде всего для упрощения
и содержит очень мало бюрократии в заголовках файлов.
Архив Unix NASM и архив DOS с исходниками имеют подкаталог rdoff,
содержащий набор RDOFF-утилит: RDF-компоновщик, менеджер статических библиотек,
утилита, делающая дамп RDF-файла, и программа, загружающая и выполняющая RDF-исполнимый
файл под Линукс.
Формат rdf поддерживает только стандартные секции
с именами .text, .data и .bss.