Основная причина, по которой используется ассемблер в Linux - это написание очень небольших по размеру программ, которые не зависят от системных библиотек. Такие программы особенно нужны для встраиваемых систем, где объемы запоминающих устройств обычно невелики.
GAS - это сокращение от GNU Assembler. Поскольку GAS был разработан для поддержки 32-битных компиляторов Unix, он использует стандартный синтаксис ATT, который несколько отличается от обычного ассемблера DOS. Основные отличия синтаксиса GAS от синтаксиса Intel:
mov eax,edx
(передать содержимое регистра edx в регистр eax) будет выглядеть в GAS как
mov %edx,%eax
.
movl %edx,%eax
. Однако gas не требует соблюдения строгого синтаксиса
ATT, так что суффикс необязателен, если размер может быть определен для
регистрового операнда, либо по умолчанию принимается 32-bit.
addl $5,%eax\end{verbatim}
(добавить константу 5 к регистру eax).
\item Отсутствие префикса операнда указывает на адрес в памяти; поэтому
\begin{verbatim} movl $foo,%eax\end{verbatim} помещает адрес переменной \verb|foo| в регистр \verb|eax|, а
команда \begin{verbatim} movl foo,%eax\end{verbatim} помещает в \verb|eax| содержимое переменной \verb|foo|.
\end{itemize}
Индексация выполняется с помощью заключения индексного регистра в скобки,
например, \verb|in testb \$0x80,17(%ebp)| (проверить установку старшего бита
в байте по смещению 17 от ячейки, указанной \verb|ebp|).
Замечание: известно несколько программ, которые могут помочь вам преобразовать
исходный код для ассемблеров AT\&T и Intel; некоторые из них способны на
преобразование в двух направлениях.
Ассемблер NASM разрабатывается в рамках проекта The Netwide Assembler, и
представляет собой мощный ассемблер на базе i386, написанный на C, который
построен по модульному принципу и обеспечивает поддержку практически вссех
известных синтаксисов и форматов объектных файлов.
Используется синтаксис Intel. Поддерживается обработка
макроопределений.
Среди поддерживаемых форматов объектных файлов есть bin, aout, coff, elf, as86,
obj (DOS), win32, rdf (собственный формат). Кроме того, NASM поставляется
с дизассемблером NDISASM.
Как и для GAS, для NASM применяется несколько программ преобразования
синтаксиса.
В качестве примера здесь приводятся две программы на ассемблере. Программы
написаны с учетом того, что Linux является 32-битной системой, работает в
защищенном режиме, имеет плоскую модель памяти и использует для исполняемых
файлов формат ELF.
Программа обычно делится на разделы: .text -- для программного кода (только
для чтения), .data -- для записи данных (чтение-запись), .bss --
для неинициализируемых данных (чтение-запись); могут также присутствовать и
другие стандартные разделы, а также разделы, определенные пользователем. В
программе должен быть как минимум раздел .text.
Пример для NASM (\texttt{hello.asm}):
\begin{verbatim}
section .data ; описание раздела
msg db "Hello, world!",0xa ; выводимая строка
len equ $ - msg ; длина строки
section .text ; описание раздела
; нам нужно передать точку входа
; компоновщику или
global _start ; загрузчику ELF. Обычно они
; распознают _start по умолчанию
; Используйте ld -e foo,
; чтобы переопределить ее.
_start:
; записываем строку в стандартный вывод
mov edx,len ; третий аргумент:
; длина строки
mov ecx,msg ; второй аргумент:
; указатель на строку
mov ebx,1 ; первый аргумент:
; дескриптор файла (stdout)
mov eax,4 ; номер системного вызова
; (sys_write)
int 0x80 ; обращение к ядру
; и выходим
mov ebx,0 ; первый аргумент: код возврата
mov eax,1 ; номер системного вызова
; (sys_exit)
int 0x80 ; обращение к ядру
Пример для GAS (hello.S):
.data # описание раздела
msg:
.string "Hello, world!\n" # выводимая строка
len = . - msg # длина строки
.text # описание раздела
# нам нужно передать точку входа
# компоновщику или
global _start # загрузчику ELF. Обычно они распознают
# _start по умолчанию.
# Используйте ld -e foo,
# чтобы переопределить ее.
_start:
# записываем строку в стандартный вывод
movl $len,%edx # третий аргумент:
# длина строки
movl $msg,%ecx # второй аргумент:
# указатель на строку
movl $1,%ebx # первый аргумент:
# дескриптор файла (stdout)
movl $4,%eax # номер системного вызова
# (sys_write)
int $0x80 # обращение к ядру
# и выходим
movl $0,%ebx # первый аргумент:
# код возврата
movl $1,%eax # номер системного вызова
# (sys_exit)
int $0x80 # обращение к ядру
Основные опции ассемблера GAS:
--defsym sym=value
определить символом sym величину value перед разбором входного файла; value должно быть целой константой. Как и в C, префикс 0x определяет шестнадцатеричное число, а префикс 0 - восьмеричное;
--help
вывести список опций командной строки;
-I dir
добавить каталог dir в список поиска для директив `.include';
-o objfile
имя объектного файла для вывода из `as';
-R
распознавать вложенные в код разделы данных;
--no-warn
опускать сообщения о предупреждениях;
--fatal-warnings
рассматривать предупреждения как ошибки.
-h
вывести информацию об опциях и поддерживаемых форматах выходных файлов nasm;
-a
ассемблировать файл без предварительного препроцессинга;
-e
выполнить препроцессинг входного файла и вывести результат в stdout (или указанный файл-приемник), но без ассемблирования;
-M
вывести в stdout зависимости в стиле make-файла;
-E filename
перенаправлять сообщения об ошибках в файл filename. Опция предназначена для операционных систем, в которых stderr нельзя перенаправить;
-f format
определить формат выходного файла. Форматы включают в себя bin - для плоских двоичных файлов, и aout или elf - для создания объектных файлов типа Linux a.out и ELF соответственно;
-o outfile
определить точное имя выходного файла, переопределив имя по умолчанию;
-l listfile
перенаправить листинг ассемблера в указанный файл, в котором с правой стороны будет выведен исходный текст (а также текст включаемых файлов и расширенные макросы), а с левой стороны - сгенерированный код в шестнадцатеричном формате;
-s
выводить сообщения об ошибках в файл стандартного вывода;
-w[+-]foo
подключить (или отключить) некоторые классы предупреждающих сообщений,
например, -w+orphan-labels или
-w-macro-params, чтобы соответственно разрешить
сообщения о метках в пустой строке или отключить сообщения о неверном
количестве параметров в вызовах макросов;
-I directory
добавить каталог в путь поиска включаемых файлов.