Сравнение ассемблерных трансляторов

         

NASM


Транслятор NASM (расшифровывается как Netwide Assembler– Ассемблер Шириной Во Всю Сеть или просто Расширенный Ассемблер) вырос из идеи, поданной на comp.lang.asm.x86 (или возможно на alt.lang.asm — сейчас точно никто и не помнит), когда не было ни одного хорошего свободного ассемблера под x86. FASM'а тогда еще не существовало. MASM/TASM стоили денег и работали только под MS-DOS/Windows. Единственный более-менее работающий транслятор под UNIX – GAS (GNU Assembler) завязан на компилятор GCC и имеет такой ужасный синтаксис, что писать на нем могут только мазохисты (и ведь примеров программ, запрограммированных на GAS'е практически нет!). Остальные ассемблеры (типа A86, AS86) не позволяют писать 16/32 разрядный код или раздаются практически без документации.

Рисунок 4 официальный логотип NASM'a

Кончилось это дело тем, что группа программистов во главе с Петром Анвином (Peter Anvin) решила разработать собственный ассемблер и это у нее получилось! MASM-подобный синтаксис, достаточно мощная макросистема (впрочем, несовместимая с MASM'ом и ничего не знающая об union'ах вместе с кучей других полезных фич), поддержка всей линейки x86 процессоров вплоть до IA64 в x86-режиме, богатство выходных файлов (bin, aout, aoutb, coff, elf, as86, obj, win32, rdf, ieee), генерация отладочной информации в форматах Borland, STABS и DWARF2 вкупе с портами под MS-DOS, Windows, Linux и BSD обеспечили NASM'у неслабую популярность, однако, без ярко выраженного фанатизма, характерного для FASM'а. Количество ошибок в трансляторе крайне довольно невелико, причем в отличии от _работающих_ продуктов (MASM/TASM) при "хитрых ошибках" NASM не падает, а генерирует ошибочный (по структуре) объектный файл. Вот и ищи как он его сгенерировал чем хочешь (даже матерым хакерам это сложно, а нормальный программист может даже и не пытаться). И, как это принято в Open Source -community, полное игнорирование баг-репортов "неудобных" для авторов

(разработки даже утверждают, что ошибок в их трансляторе вообще нет, в смысле им не известен ни один). Тем не менее, в последней версии NASM'а, в зависимости от значения ключа -On, код может сгенерироваться в 2х или более экземплярах, или может пропасть весь экспорт (pubdef'ы).


К минусам NASM' а можно отнести отсутствие поддержки уникода, платформы AMD x86-64, формата отладочной информации CodeView и некоторые странности синтаксиса. В частности, команда "mov eax, 1" не оптимизируется и транслятор умышленно оставляет место для 32-разрядного операнда. Если же мы хотим получить "короткий" вариант, размер операнда необходимо специфицировать явно: "mov eax, byte 1", что очень сильно напрягает или… использовать опцию "-On" для автоматической оптимизации.

Также необходимо принудительно указывать длину переходов short или near, иначе очень легко нарваться на ругательство "short jump out of range". Впрочем, опять-таки, существует возможность настроить транслятор на генерацию near-переходов по умолчанию.

Гораздо хуже, что NASM не помнит типы объявляемых переменных и не имеет нормальной поддержки структур (впрочем, самое понятие "нормальности" структур в ассемблере весьма растяжимо и каждый волен трактовать его по своему).

Из мелких недочетов можно называть невозможность автоматического генерации короткого варианта инструкции "push imm8" и отсутствие контроля за соответствием транслируемых инструкций типу указанного процессора (команда "cpuid" под ".486" ассемблируется вполне нормально, а ведь не должна).

Непосредственная трансляция примеров из SDK/DDK под NASM'ом невозможна, так что разрабатывать на нем драйвера под Windows может только очень крутой поклонник или извращен. NASM — один из лучших ассемблеров под Liux/BSD, а вот под Windows его позиции уже не так сильны (в основном из-за неполной совместимости с MASM'ом).


Содержание раздела