Открыть сервис

Синтаксис AT&T

Синтаксис AT&T — это один из двух основных способов записи инструкций (мнемоник) и операндов в языке ассемблера для архитектуры x86 (и её расширений, таких как x86-64). Назван в честь компании AT&T (American Telephone and Telegraph), в недрах которой в 1970-х годах была разработана операционная система UNIX, а также ассемблеры для процессоров PDP-11 и VAX, которые впоследствии повлияли на синтаксис для x86. В отличие от альтернативного, более распространённого в среде MS-DOS и Windows синтаксиса Intel, синтаксис AT&T отличается рядом строгих правил, особенно в отношении порядка операндов, обозначения размера данных и способа записи адресов. Основное применение он находит в среде операционных систем семейства UNIX и Linux, в частности, в ассемблере GNU Assembler (GAS), который является частью набора компиляторов GCC.

История

Синтаксис AT&T возник в контексте разработки операционной системы UNIX. Исходные версии UNIX были написаны на ассемблере для PDP-11, где использовался синтаксис, ставший предшественником AT&T. Когда архитектура x86 (Intel 8086, 80286, 80386) стала популярной, компания AT&T портировала на неё свои инструменты, включая ассемблер. В результате для x86 был принят синтаксис, основанный на традициях PDP-11 и VAX, а не на синтаксисе, предложенном Intel.

В 1980-х годах, с распространением UNIX-систем на платформе x86 (например, Xenix, System V), синтаксис AT&T стал стандартом де-факто для этой операционной среды. Позднее, с появлением проекта GNU и созданием ассемблера GAS (GNU Assembler), синтаксис AT&T был выбран в качестве основного режима работы по умолчанию. Это было обусловлено тем, что GAS разрабатывался как часть набора компиляторов GNU, ориентированного на UNIX-подобные системы. Хотя GAS поддерживает и синтаксис Intel (через директиву .intel_syntax), синтаксис AT&T остаётся его родным и наиболее тесно интегрированным с другими инструментами GNU, такими как GCC и GDB.

Основные отличия от синтаксиса Intel

Синтаксис AT&T принципиально отличается от синтаксиса Intel по нескольким ключевым параметрам. Эти различия часто вызывают путаницу у программистов, переходящих с одной платформы на другую.

Порядок операндов

Самое заметное отличие — порядок операндов в инструкции.

  • Синтаксис Intel: инструкция назначение, источник (например, mov eax, ebx — скопировать значение из ebx в eax).
  • Синтаксис AT&T: инструкция источник, назначение (например, movl %ebx, %eax — скопировать значение из %ebx в %eax). Источник всегда указывается первым, назначение — вторым.

Обозначение регистров

В синтаксисе AT&T имена всех регистров предваряются символом процента (%).

  • Intel: eax, ebx, ax, cl
  • AT&T: %eax, %ebx, %ax, %cl

Обозначение непосредственных значений

Непосредственные значения (константы) в синтаксисе AT&T предваряются символом доллара ($).

  • Intel: mov eax, 5 (загрузить число 5 в регистр eax)
  • AT&T: movl $5, %eax (загрузить число 5 в регистр %eax)

Суффиксы размера операндов

В синтаксисе AT&T мнемоника инструкции часто содержит суффикс, указывающий на размер обрабатываемых данных. В синтаксисе Intel размер обычно определяется типом операндов (регистром или размером памяти).

  • b (byte) — 1 байт (8 бит)
  • w (word) — 2 байта (16 бит)
  • l (long) — 4 байта (32 бита)
  • q (quad) — 8 байт (64 бита, для x86-64)

Примеры:

  • movb — переместить байт
  • movw — переместить слово
  • movl — переместить двойное слово (32-битное)
  • movq — переместить четверное слово (64-битное)

Синтаксис адресации памяти

Синтаксис адресации памяти в AT&T является более сложным для восприятия, но более формальным. Общая форма записи: смещение(базовый_регистр, индексный_регистр, множитель). В синтаксисе Intel та же адресация записывается как [базовый_регистр + индексный_регистр * множитель + смещение].

Примеры:

  • Intel: mov eax, [ebx + ecx*4 + 8]
  • AT&T: movl 8(%ebx, %ecx, 4), %eax
  • Intel: mov eax, [var] (загрузка значения из переменной var)
  • AT&T: movl var, %eax (в AT&T переменная без скобок и префикса $ означает адрес в памяти).

Классификация инструкций

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

Инструкции передачи данных

  • movl %eax, %ebx — копирование 32-битного значения из %eax в %ebx.
  • pushl %ecx — помещение 32-битного значения регистра %ecx в стек.
  • popl %edx — извлечение 32-битного значения из стека в регистр %edx.
  • leal 4(%esp), %eax — загрузка эффективного адреса (адреса %esp + 4) в регистр %eax.

Арифметические и логические инструкции

  • addl $10, %eax — прибавление 10 к значению в регистре %eax.
  • subl %ebx, %eax — вычитание значения %ebx из %eax (результат в %eax).
  • imull %ecx, %eax — умножение %eax на %ecx (результат в %eax).
  • andl $0xFF, %edx — логическое И между %edx и маской 0xFF.
  • orl %eax, %eax — логическое ИЛИ (часто используется для проверки на ноль).
  • xorl %eax, %eaxисключающее ИЛИ (обнуление регистра).

Инструкции управления потоком

  • jmp label — безусловный переход на метку label.
  • je label — переход, если равенство (флаг ZF установлен).
  • jne label — переход, если не равно.
  • call function — вызов подпрограммы function.
  • ret — возврат из подпрограммы.
  • cmpl %eax, %ebx — сравнение %eax и %ebx (вычисление %ebx - %eax без сохранения результата, только установка флагов).

Строковые и прочие инструкции

  • rep movsl — повторение инструкции movsl (перемещение строки 32-битных слов) число раз, указанное в регистре %ecx.
  • cld — сброс флага направления (DF) для строковых операций.

Применение

Синтаксис AT&T является доминирующим в следующих областях:

  • Разработка под Linux и другие UNIX-подобные системы: Абсолютное большинство встроенного ассемблерного кода в ядре Linux, драйверах и системных библиотеках написано с использованием синтаксиса AT&T. Компилятор GCC, при вставке ассемблерного кода на C (inline assembly), по умолчанию использует именно этот синтаксис.
  • Обратная разработка (Reverse Engineering) в среде Linux: Дизассемблеры, такие как objdump (с флагом -d), по умолчанию выводят код в синтаксисе AT&T. Для получения синтаксиса Intel требуется явно указать флаг -M intel.
  • Отладка с использованием GDB: Отладчик GNU GDB (GNU Debugger) по умолчанию отображает дизассемблированный код в синтаксисе AT&T. Это может быть изменено командой set disassembly-flavor intel.
  • Образовательные курсы по системному программированию: Многие университетские курсы, особенно в рамках изучения операционных систем и архитектуры компьютеров, используют синтаксис AT&T, так как он тесно связан с инструментарием GNU.

Критика

Синтаксис AT&T часто подвергается критике за его неинтуитивность для начинающих и за избыточную многословность по сравнению с синтаксисом Intel.

  • Обратный порядок операндов: Главный источник ошибок. Программисты, привыкшие к синтаксису Intel, где назначение стоит слева, часто путают источник и назначение в AT&T, что приводит к неверным результатам.
  • Избыточные символы: Необходимость ставить % перед регистрами и $ перед константами делает код более громоздким и менее читаемым, особенно при работе с длинными строками.
  • Сложность адресации: Синтаксис адресации памяти смещение(база, индекс, множитель) считается менее наглядным, чем [база + индекс * множитель + смещение] в синтаксисе Intel.
  • Неочевидность суффиксов: Хотя суффиксы размера (b, w, l, q) делают размер операнда явным, они добавляют лишний символ к каждой инструкции, что увеличивает объём кода.

Несмотря на критику, синтаксис AT&T остаётся стандартом для инструментов GNU и широко используется в сообществе разработчиков открытого программного обеспечения. Его изучение необходимо для глубокого понимания работы операционных систем семейства UNIX и низкоуровневого программирования на платформе x86.

Интересные факты

  • Ассемблер GNU Assembler (GAS) может работать как в режиме AT&T, так и в режиме Intel. Переключение между ними осуществляется директивой .intel_syntax noprefix (для синтаксиса Intel без префиксов % и $) и .att_syntax для возврата к AT&T.
  • Несмотря на то, что синтаксис AT&T ассоциируется с UNIX, он также поддерживается некоторыми ассемблерами для Windows, например, в составе инструментов Cygwin и MinGW.
  • В документации к процессорам Intel и AMD официально используется синтаксис Intel, что делает синтаксис AT&T вторичным по отношению к аппаратной документации.

Источники

  • Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2: Instruction Set Reference.
  • GNU Assembler (GAS) Manual.
  • «Язык ассемблера для процессоров Intel» (К. Ирвин).
  • «Low-Level Programming: C, Assembly and Program Execution on Intel 64 Architecture» (И. Жуков).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →