Forums.Avtograd.Ru: Вопросы по Assembler - Forums.Avtograd.Ru

Перейти к содержимому

  • (2 Страниц)
  • +
  • 1
  • 2
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

Вопросы по Assembler

#1 Пользователь офлайн   KORENHACK

  • Старожил
  • PipPipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 464
  • Регистрация: 01 Ноябрь 07

Отправлено 01 Ноябрь 2007 - 18:17

Начнём...
Кто-нить знает как упорядочить массив любого измерения?
0


  • (2 Страниц)
  • +
  • 1
  • 2
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

Другие ответы в этой теме

#21 Пользователь офлайн   Alex Z. Saver

  • Старожил
  • PipPipPipPipPip
  • Группа: Модераторы
  • Сообщений: 3 890
  • Регистрация: 01 Ноябрь 07

Иконки сообщения  Отправлено 18 Май 2009 - 06:51

Cравнение ассемблерных трансляторов
Крис Касперски, aka мыщъх, aka nezumi, aka elrton, aka souriz, no e-mail.


проблема выбора "единственного правильного" ассемблерного транслятора мучает не только начинающих, но и профессиональных программистов. у каждого продукта есть своя когорта поклонниках и спор о преимуществах/недостатках рискует превратиться в священные войны с выносом тел погибших. на форумах такие дискуссии лучше не разводить и вещать в одностороннем порядке, как мыщъх, собственно, и поступил, сравнив MASM, TASM, FASM, NASM, YASM и некоторые другие ассемблеры по всему спектру критериев, значимость которых каждый должен оценивать сам

введение

Компиляторы языков высокого уровня (Си, Паскаль) в определенной степени совместимы между собой и хотя исходный текст, предназначенный для одного компилятора, не всегда без переделок транслируется на другом, синтаксис и прочие языковые концепции остаются неизменными, позволяя "летать" между MS VC, Intel C++, GCC, Open WATCOM, сравнивая полноту поддержки Стандарта, скорость трансляции, качество кодогенерации, популярность компилятора и вытекающее отсюда изобилие (недостаток) библиотек и компонент к нему.
С трансляторами ассемблера все обстоит иначе. Казалось бы, x86 ассемблер - он и в Африке ассемблер, так ведь нет! Помимо поддержки мнемоник машинных команд, каждый транслятор обладает своим собственным набором директив и макросредств, зачастую ни с чем не совместимых. Ассемблерный листинг, "заточенный", например, под MASM, бесполезно переносить на FASM, поскольку, _возможности,_ предоставляемые макросредствами, у них сильно неодинаковые!

Перефразируя известную поговорку, можно сказать: выбирая транслятор ассемблера, вы выбираете судьбу, изменить которую впоследствии за здорово живешь не удастся! Придется _переучиваться,_ фактически осваивая новый язык. Но это еще полбеды! Всякий уважающий себя программист со временем обрастает ворохом маленьких библиотек, делающих кучу грязной работы. Их-то куда при переходе на новый ассемблер девать?! Перенести ничуть не легче, чем переписать с нуля!

К счастью, ассемблер - это только инструмент, а не религия, и совместное использование нескольких трансляторов еще никто не запрещал. На практике, обычно, так и поступают. Ставится конкретная задача и для ее решения выбирается наиболее адекватный инструмент. Естественно, чтобы сделать правильный выбор необходимо знать какие ассемблеры вообще есть и чем они отличаются.

основополагающие критерии

Богатый ассортимент - верный признак отсутствия продукта, который устраивает если не всех, то хотя бы большинство, а потому если что-то существует и не просто существует, но еще и собирает под свое крыло нехилое количество пользователей, значит, кому-то оно _действительно_ необходимо и отстоем быть _никак_ _не_ _может_ (это сразу, чтобы пресечь возможные разговоры шепотом).
Сравнивая ассемблеры друг с другом, мыщъх не пытался найти "самый лучший" транслятор (таких просто не существует), а стремился свести воедино информацию о предоставляемых ими возможностях, ведь значимость любых критериев _всегда_ субъективна по определению. Человеку, упорно игнорирующего существование LINUX/BSD, абсолютно все равно на какое количество платформ был перенесен данный транслятор. А для кого-то это вопрос первостепенной важности!

Тем не менее, существует ряд основополагающий критериев, существенных для всех категорий программистов. Начнем с генерации отладочной информации, без которой отладка программы сложнее, чем "hello, word", превращается в настоящую пытку. Вот тут некоторые уже пытаются возразить, что ассемблерам, в отличии от языков высокого уровня, отладочная информация на хрен не нужна, ведь мнемоники машинных команд, что в листинге, что в отладчике - одни и те же. А метки?! А структуры?! А имена функций?! Уберите их - и код станет совершенно не читаемым! Можно, конечно, воспользоваться отладочной печатью (просто вставлять макрос, выводящий значение регистров/переменных на экран/файл в указанных местах) - давным-давно, когда интерактивных отладчиков и в помине не существовало, отладочная печать была основным средством борьбы с багами. Еще можно отлаживать программу, держа перед носом распечатку исходных текстов, но это извращение еще покруче будет.

Проблема в том, что формат отладочной информации _не_ стандартизован и различные трансляторы используют различные форматы, что ограничивает нас в выборе отладчиков или вынуждает использовать конверторы сторонних производителей, а некоторые ассемблеры (например, FASM) не генерируют отладочной информации вообще. Ну хоть бы простейший map-файл, эх…

Но, если формат отладочной информации - это задний двор транслятора, то формат выходных файлов - это его лицо. Непосвященные только пожмут плечами. Какой там формат? Обыкновенный obj, из которого с помощью линкера можно изготовить все, что угодно - от exe до dll. На самом деле, "обыкновенных" объектных файлов в природе не бывает. Есть omf (в редакциях от Microsoft и IBM), coff, elf, aout и куча разной экзотики в стиле as86, rdf, ieee и т. д. Так же заслуживает внимания возможность "сквозной" генерации двоичных файлов не требующая помощи со стороны линкера. А некоторые ассемблеры (например, FASM) даже позволяют "вручную" генерировать исполняемые файлы и динамические библиотеки различных форматов полностью контролируя процесс их создания и заполняя ключевые поля по своему усмотрению. Впрочем, программы, целиком написанные на ассемблере, - это либо вирусы, либо демки, либо учебные, либо просто садомазохизм такой. Обычно на ассемблере пишутся лишь системно-зависимые компоненты или модули, критичные к быстродействию, которые затем линкуются к основному проекту и, если ассемблер генерирует только omf, а компилятор - coff, то… возникает проблема сборки "разнокалиберных" форматов воедино. Мыщъху известен только один линкер, умеющий это делать - ulink от Юрия Харона, он же обеспечивают не хилые возможности по сборке файлов "вручную", так что выбор конкретного ассемблерного транслятора целиком лежит на совести (и компетенции) программиста, но все-таки лучше, чтобы и ассемблер, и компилятор, генерировали одинаковые форматы объектных файлов.

Другой немаловажный критерий - количество поддерживаемых процессорных архитектур, которых в линейке x86 набралось уже больше десятка. Конечно, недостающие команды можно реализовать с помощью макросов или запрограммировать непосредственно в машинном коде через директиву DB, но… если так рассуждать, то зачем вообще нужны ассемблеры, когда есть hex-редакторы?! Особое внимание следует обратить на платформы AMD x86-64 и Intel IA64. Хотим ли мы этого или нет, но 64-разрядные архитектуры имеют хорошие шансы потеснить x86, поэтому учиться программировать под них обязательно, так что поддержка со стороны транслятора должна быть обеспечена уже сейчас!

Кстати, ни один из трансляторов не поддерживает набор команд x86-процессоров в полном объеме. Например, на MASM'е невозможно написать jmp 0007h:00000000h и приходится прибегать к различным ухищрениям: либо реализовать команду через DB, что не наглядно и неудобно, либо заталкивать в стек сегмент/смещение, а потом делать retf, но это длинно и к тому же воздействует на стек, которого у нас может и не быть.

Программирование на смеси 16- и 32-разрядного кода с кратковременным переходом в защищенный режим и возвращением обратно в реальный - это вообще песня и на MASM'е такое скорее умрешь, чем запрограммируешь, однако, большинству программистов подобного трюкачество просто не нужно!

А вот что _реально_ нужно большинству - так это интеграция в мировое сообщество. Свои собственные оси обычно пишут пионеры, только что прочитавшие Юрова/Зубкова и открывшие для себя защищенный режим с его поистине безграничными возможности. В учебном плане, это, бесспорно, очень даже хорошо, но коммерческим программистам обычно приходится программировать под уже существующие системы, туже Windows, например. И, если в состав DDK входит MASM в кучей исходных текстов драйверов, то пытаться собрать их под другим транслятором - означает впустую убивать время. Опять-таки, если компилятору Microsoft Visual C++ задать ключ /FA, то он выдаст ассемблерный листинг в стиле MASM, точно так же поступит и IDA Pro, Borland C++ выберет TASM (ну еще бы!), а GCC - GNU Assembler (он же GAS). Вот это и называется интеграцией в среду. Чистый ассемблер сам по себе мало кому интересен и практически всегда он становится приложением к чему-то еще. То есть, если вы пишите драйвера под Windows на Microsoft Visual C++, то разумнее всего остановить свой выбор на MASM'е, поклонникам же Borland C++ лучше TASM'а ничего не найти. Под Linux/BSD рулит GAS (GNU Assembler) уже хотя бы за счет того, что ассемблерные программы можно транслировать с помощью компилятора GCC, используя Си-сопроцессор с одной стороны и освобождаясь от головной боли с поиском стартового кода и библиотек, однако, GAS использует AT&T-синтаксис, являющийся полной противоположностью Intel-синтаксису, которого придерживаются MASM, TASM, FASM, NASM/YASM, поэтому в данной ### статье не рассматривается. Разработчики вирусов и просто маленьких ассемблерных программ, написанных из любви к искусству, намного меньше ограничены в своем выборе и могут использовать все, что им по душе, вне зависимости от степени "поддержки".

Качество документирования играет весьма важную роль и еще важнее _кому_ принадлежит проект. Трансляторы, созданные энтузиастами-одиночками, могут умереть в любой момент, поэтому закладываться на них в долговременной перспективе мыщъх ни за что бы ни стал. Коммерческие ассемблеры крупных компаний выглядят намного более стабильными и непоколебимыми, однако, никаких гарантий, что в один "прекрасный" момент компания не забьет на своей продукт у нас нет (достаточно вспомнить историю с TASM'ом). Открытые трансляторы, поддерживаемые независимой группой лиц, наиболее живучи. Стоило коллективу NASM'а чуть-чуть приостановить его развитие, как тут же появился YASM - "позаимствовавший" исходные тексты и добавивший все необходимое (поддержку x86-64, формат отладочной информации CodeView и т. д.).

Последнее, на чем хотелось бы заострить внимание - это макросредства. Отношение к ним у программистов двоякое. Одни во всю пользуются плодами прогресса, программируя на смеси ассемблера, бейсика и препроцессора си (существует даже проект HLA: High Level Assembler - Ассемблер Высокого Уровня), другие - презирают их, ратуя за чистоту ассемблерного кода. Вот и разберись тут кто прав, а кто виноват! Макросы упрощают программирование, зачастую позволяя невозможное (например, шифровать код программы еще на стадии ассемблирования!), но переносимость программы от этого резко ухудшается и переход на другой транслятор становиться труднореализуемым. Но как бы там ни было, поддержка макросов совсем не обязывает этими макросами пользоваться!

MASM

Продукт жизнедеятельности ранней компании Microsoft, которой тот был нужен для создания MS-DOS (исходные тексты MS-DOS 6.x, добытые из парнокопытного животного все поимели? видели, _сколько_ там ассемблерных вставок?), а позднее и для Windows 9x/NT. После выхода версии 6.13 продукт на некоторое время тормознул в развитии, но потом здравый смысл взял вверх и последняя версия (на момент написания этих строк - 6.13.8204) поддерживает уникод, все SSE/SSEII/SEEIII расширения (объявляемые двумя директивами .686/.XMM), а так же архитектуру AMD x86-64. Платформа Intel IA64 не поддерживается, но Microsoft поставляет Intel-ассемблер IAS.EXE.
Аббревиатура MASM расшифровывается отнюдь не как Microsoft Assembler, а как Macro Assembler, то есть Ассемблер с поддержкой Макросов, покрывающих своими возможностями широкий круг задач: повторения однотипных операций с параметризацией (шаблоны), циклические макросы, условное ассемблирование и т. д., по сравнению с которым препроцессор языка Си выглядит жалкой подделкой. Имеется даже зачаточная поддержка основных парадигм ООП, впрочем, так и получившая большого распространения, поскольку ассемблер и ООП концептуально несовместимы. Многие пишут даже без макросов на чистом ассемблере, считая свой путь идеологически наиболее правильным. Но о вкусах не спорят.

Сначала MASM распространялся в виде самостоятельного (и притом весьма дорогостоящего) пакета, но позже он был включен в состав DDK, которое вплоть до Windows 2000 DDK раздавалось бесплатно, а сейчас доступно только подписчикам MSDN. Впрочем, вполне полноценное DDK (с ассемблером) для Windows Server 2003 входит в Kernel-Mode Driver Framework, а сам транслятор MASM'а еще и в Visual Studio Express, которая такая бесплатна.

Стив Хатчессон собрал последние версии транслятора MASM'а, линкер от Microsoft, включаемые файлы, библиотеки, обширную документацию, статьи разных авторов, посвященные ассемблеры и даже простенькую IDE в один дистрибутив, известный под "пакетом хатча" (hutch), бесплатно раздаваемый всем желающим на вполне лицензионной основе, так что это не хак, а вполне удобный комплект инструментов для программирования под Windows на ассемблере.

MASM'у посвящено множество книг, что упрощает процесс обучения, а в сети можно найти кучу исходных текстов ассемблерных программ и библиотек, освобождающих программиста от необходимости изобретать велосипед. Также, MASM является выходным языков для многих дизассемблеров (Sourcer, IDA Pro). Все это делает MASM транслятором номером один в программировании под Wintel.

Поддерживаются два выходных формата: 16/32 Microsoft OMF и (16)/32/64 COFF, что позволяет транслировать 16/32-разрядные программы под MS-DOS, работающие в реальном и защищенном режиме, 16-разрядные приложения и драйвера для Windows 3.x, 32-разряныые приложения и драйвера для Windows 9x/NT, а так же 64-разрядные приложения и драйвера для Windows NT 64-bit Edition. Для создания бинарных файлов потребуется линкер, который умеет это делать (например, ulink от Юрия Харона). Кстати говоря, последние версии штатного Microsoft Linker'а, входящее в SDK и DDK, утратили способность собирать 16-разряные файлы под MS-DOS/Windows 3.x и приходится возвращаться к старой версии, которая лежит в папке NTDDK\win_me\bin16.

MASM генерирует отладочную информацию в формате CodeView, которую Microsoft Linker может преобразовывать в PDB-формат, хоть и не документированный, но поддерживаемый библиотекой dbghelp.dll, позволяющей сторонним разработчикам "переваривать" отладочную информацию, поэтому, файлы, оттранслированные MASM'ом, можно отлаживать в Soft-Ice, дизассемблировать в IDA Pro и прочих продуктах подобного типа.

Главный недостаток MASM'а - его жуткая багистность. Стоит только открыть Knowledge Base, посмотреть на список официально подтвержденных багов и… ужаснуться! Как только после этого на MASM'е вообще можно программировать?! Особенно много ошибок в штатной библиотеке. Вот только несколько примеров: dwtoa и atodw_ex не понимают знака и по скорости очень тормозят, хотя в документации написано: "A high speed ascii decimal string to DWORD conversion for applications that require high speed streaming of conversion data"; ucFind не находит в строке подстроку, если длина подстроки равна 1 символу; функции BMHBinsearch и SBMBinSearch (поиск алгоритмом Бойера-Мура) реализованы с ошибками; некоторые функции обрушивают программу (если передать ustr2dw строку длиннее пяти байт - программа падает).

Другой минус - отсутствие поддержки некоторых инструкций и режимов адресации процессора, например, невозможно сделать jmp far seg:offset, а попытка создания смешанного 16/32 разрядного кода - это настоящий кошмар, который приходится разгребать руками и всячески извращаться, преодолевая сопротивление "менталитета" транслятора.

Наконец, MASM - типичный коммерческий продукт с закрытыми исходными текстами, судьба которых покрыта мраком. Microsoft интенсивно продвигает высокоуровневое программирование, отказываясь от ассемблера везде, где это только возможно, поэтому, не исключено, что через несколько лет MASM прекратит свое существование...

Тем не менее, несмотря на все эти недостатки, MASM остается самым популярным _профессиональным_ транслятором ассемблера при программировании под Windows NT, хотя разработчикам приходится плеваться и материться, но _реальных_ альтернатив ему нет.

TASM

Самый популярный транслятор ассемблера времен MS-DOS, созданный фирмой Borland (известной в народе как Багдад), и полностью совместимый с MASM'ом вплоть до версий 6.x и поддерживающий свой собственный режим IDEAL с большим количеством улучшений и расширений.
Удобство программирования, скромные системные требования и высокая скорость трансляции обеспечивали TASM'у лидерство на протяжении всего существования MS-DOS (буква "T" означает Turbo, вот так - без ложной скромности). Но с появлением Windows популярность TASM'а стала таять буквально на глазах. Не сумев (или не захотев) добиться совместимости с заголовочными файлами и библиотеками, входящими в комплект SDK/DDK, фирма Borland решила поставлять свой собственный порт, причем далеко неидеальный. К тому же штатный линкер tlink/tlink32 не поддерживает возможности создания драйверов, а формат выходных файлов (Microsoft OMF, IBM OMF, Phar Lap), не поддерживается текущими версиями линкерома от Microsoft (впрочем, 16-битные версии это умеют). В довершении ко всему, формат отладочной информации не совместим с CodeView и реально поддерживается только TurboDebugger'ом и soft-ice.

И хотя эти проблемы в принципе разрешимы: возможность низкоуровневого ассемблерного программирования (без включаемых файлов и макросов) осталась там же, где и была, несовместимость форматов компенсируется наличием конверторов, но… преимущества режима IDEAL над стандартным синтаксисам MASM'а день ото дня казались все менее и менее значительными, ряды поклонников редели и в конце концов проект загнулся. Последней версией транслятора стал TASM 5.0, поддерживающая команды вплоть до 80486 процессора. Отдельно был выпушен патч, обновляющий TASM до версии 5.3 и поднимающий его вплоть до Pentium MMX, однако, команды Pentium II такие, например, как SYSENTER как не работали, так и не работают. Поддержка уникода тоже отсутствует.

В настоящее время Borland прекратила распространение своего ассемблера и достать его можно только в магазинах торгующих старыми CD-ROM или у какого-нибудь коллекционера. Пацак по кличке !tE выпустил пакет TASM 5+, включающий в себя транслятор, линкер, библиотекарь, какое-то подобие документации, несколько заголовочных файлов под Windows и пару демонстрационных примеров. Когда будете искать это добро не перепутайте его с TASM32 фирмы Squak Valley Software - это совершенно независимый кроссассемблер, ориентированный на процессоры 6502,6800/6801/68HC11, 6805, TMS32010, TMS320C25, TMS7000, 8048, 8051,8080/8085, Z80, 8096/80C196KC, о которых большинство из нас в лучшем случае просто слышало, что они есть.

Короче, TASM - это труп. Причем вполне конкретный. Однако, для разработки прикладных приложений под Windows 16/32 и MS-DOS он все-таки подходит, особенно, если вы уже имеете опыт работы с ним и некоторые собственные наработки (библиотеки, макросы), с которыми жалко расставаться, а конвертировать под MASM - весьма проблематично. Возможно, вам понравится бесплатный Lazy Assembler (автор - Половников Степан), совместимый с режимом IDEAL TASM и поддерживающим команды из наборов MMX, SSE, SSEII, SSEIII, 3DNow!Pro.

FASM

Писать о культовых проектах, не затронув чувства верующих и сохранив при этом здоровую долю скептицизма и объективизма не так-то просто, особенно если ты сам являешься апологетом веры, за которую готов если не отдать жизнь, то уж точно порвать любого критика на куски, а потом прихлопнуть дампам памяти или своп файлом. FASM (расшифровывается как Flat Assembler - Ассемблер Плоского Режима) - это крайне необычный транслятор с экзотичными возможностями, которых все мы давно (и безуспешно!) ждали от крупных производителей, но те были слишком далеки от практического программирования и пытались формировать новые потребности (например, путем введения поддержки ООП), вместо того, чтобы удовлетворять те, что есть.
Так продолжалось до тех пор, пока Томаш Гриштар (Tomasz Grysztar) - аспирант Ягеллонского университета в Кракове - не задумал написать свою собственную ось, названную Титаном и представляющую некоторое подобие DOS-системы для защищенного режима. Перебрав несколько ассемблерных трансляторов, но так и не обнаружив среди них подходящего, Томаш пошел на довольно амбициозный шаг, решив разработать необходимый инструментарий самостоятельно. Это произошло в 1999-03-23, 14:24:33 (дата создания первого файла) и уже к началу мая 1999 года появилась версия, способная транслировать сама себя (FASM написан на FASM'е). Операционная система в результате одной случайной катастрофы пала смертью храбрых, а вот исходные тексты FASM'а - остались и с тех пор он продолжает активно развиваться.

Что же такое FASM? Это ассемблер с предельно упрощенным синтаксисом (никаких offset'ов и прочих захламляющих листинг директив), полной поддержкой _всех_ процессорных команд (в том числе и jmp 0007:00000000), качественным кодогенератором, мощным макропроцессором и гибкой системой управления за форматом выходных файлов.

FASM распространяется в исходных текстах на бесплатной основе и к настоящему моменту перенесен на MS-DOS, Windows 9x/NT, LINUX, BSD, поддерживает уникод и все x86 процессоры вплоть до Pentium-4 с наборами мультимедийных инструкций MMX, SSE, SSEII, SSEIII, AMD 3DNow!, а так же платформу AMD x86-64, позволяя генерировать не только Microsoft coff, но и готовые bin, mz, pe и elf файлы. То есть, фактически, FASM позволяет обходиться без линкера, однако, при этом раскладку секций в PE-файле и таблицу импорта приходится создавать "вручную" с помощью специальных директив ассемблера, что выглядит очень заманчиво, но на практике все же намного удобнее сгенерировать coff и скомпоновать его с модулями, написанными на языках высокого уровня.

Макроязык FASM'а настолько мощный, что позволяет писать программы на себе самом без единой ассемблерной строки, вот например (см. листинг 1). И пускай кто-то ворчит, ну вот, мол, еще одна попытка опустить ассемблер до уровня Бейсика. Ничего подобного! Макросы - вещь добровольная. Хочешь - пользуйся, не хочешь - не надо.

file 'interp.asm'
repeat $
load A byte from %-1
if A>='a' & A<='z'
A = A-'a'+'A'
end if
store byte A at %-1
end repeat

Листинг 1 программа, целиком написанная на интерпретируемом языке FASM'a

Все это были достоинства. Теперь поговорим о недостатках. Ни на что не похожий синтаксис FASM'а напрягает даже матерых программистов, заставляя их вгрызаться в плохо структурированную документацию и небольшое количество демонстрационных примеров, поставляемых вместе с транслятором. На это требуется время, которое в конечном счете ничем не компенсируется, поскольку, круг задач, на которых FASM реально рвет MASM крайне мал. Категорическая несовместимость с MASM'ом чрезвычайно затрудняет разработку Windows-драйверов (в большинстве своем создаваемых на основе примеров из DDK). Прикладным задачам в свою очередь требуется SDK и желательно первой свежести, а не второй, да и программы, целиком написанные на ассемблере, - это совсем не то, чего требует бизнес-машина. "Математические" задачи, перемножающие матрицы, вычисляющие координаты пересечения кривых в N-мерном пространстве или трансформирующие графику - легко пишутся на FASM'е, поскольку не привязаны к конкретной операционной системе, никаких API-функций они не вызывают и вообще не лезут туда, где можно обойтись Си/Си++.

Если бы FASM поддерживал генерацию отладочной информации, его (с некоторой натяжкой) еще было бы можно рассматривать как серьезный инструмент, а так… он остается игрушкой, пригодной для мелких задач типа "hello, world", вирусов, демок и прочих произведений хакерского творчества.

Наконец, ни у кого нет гарантий, что создатель FASM'а не утратит к нему интереса, а ведь без поддержки новых процессорных инструкций всякий транслятор обречен на медленное, но неизбежное вымирание. Открытость исходных текстов тут не поможет, помимо них нужна еще и команда. Нужны "носители знания", способные удержать детали проекта у себя в голове, а тот факт, что FASM написан на себе самом, увы, читаемости листингам отнюдь не добавляет.

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 разрядный код или раздаются практически без документации.
Кончилось это дело тем, что группа программистов во главе с Петром Анвином (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'ом).

YASM

Когда развитие NASM'а затормозилось, его исходные тексты легли в основу нового транслятора - YASM, что в зависимости от настроения может расшифровываться и как: Yes, it's an assembler, и как Your favorite assembler, и как Yet another assembler, и даже как Why an assembler (последнее - шутка).
Вот основные отличительные черты YASM'а от его предшественника: поддержка платформы AMD x86-64, большое количество исправленных ошибок (которых в NASM'е "нет"), оптимизированный парсер, переваривающий синтаксис как NASM, так и GAS, более полная поддержка COFF (DJGPP) и Win32 obj выходных файлов, генерация отладочной информации в формате CodeView, интернационализация (выполненная через GNU-библиотеку gettext), и прочие мелкие улучшения, которых вполне достаточно, чтобы потеснить NASM особенно в мире UNIX-подобных систем, где GAS-синтаксис по-прежнему играет ведущую роль.

Под Windows же YASM не имеет никаких ощутимых преимуществ перед MASM'ом за исключением того, что поддерживает возможность генерации двоичных файлов, особенно удобных для создания shell-кода, но бесполезных для разработчика драйверов.

заключение

Попробуем подвести итог, обобщив все вышесказанное в нескольких словах (по одному слову для каждого транслятора):
MASM (Macro Assembler) - стандарт де-факто при программировании под Windows 9x/NT;
TASM (Turbo Assembler) - медленно разлагающийся труп, пригодный только для MS-DOS;
Lazy Assembler - реинкцинация TASMа с поддержкой новых команд процессора;
FASM (Flat Assembler) - неординарный и весьма самобытный, но увы, игрушечный ассемблер;
NASM (Netwide Assembler) - хороший ассемблер под LINUX/BSD с Intel-синтаксисом;
YASM (Yet another assembler) - усовершенствованный вариант NASM'а;
HLA (High Level Assembly Language) - очень высокоуровневый ассемблер, на любителя.
1

#22 Пользователь офлайн   [nyncuk]

  • Пользователь
  • PipPip
  • Группа: Пользователи
  • Сообщений: 175
  • Регистрация: 01 Ноябрь 07

Отправлено 18 Май 2009 - 13:58

срочно надо написать программу:
Ввести размерность и элементы (байты, положительные числа) квадратной матрицы.Вывести на экран исхожную матрицу.Определить средние арифметические значения элементов, расположенных на главной SG и побочной SP диагоналях (SG и SP - неполные частные). Если SG>SP, вывести матрицу таким образом, чтобы ее элементы, меньшие SG, были "невидимы" (вместо их выводится ПРОБЕЛ).Сопроводить вывод 10ю звуковыми сигналами.
0

#23 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 11 Октябрь 2009 - 00:13

Что-то тема не развивается...
Хм.. Никто не кодит на асме?...
Ладно я продолжу...
Разбираюсь сейчас с асмом под линь...
Вот какой-то хрено-макрос (не люблю макросы, люблю, когда все руками прописано где нужно)
Я знаю что он делает, но не знаю этого "макро-синтаксиса" или как его назвать...
Хочу его перевести на норм асмерский язык
macro ccall proc,[arg]			; call CDECL procedure

 { common

    local size

    size = 0

   reverse

    pushd arg

    size = size+4

   common

    call proc

    add esp,size }

кароч скажите что делают вот эти common и reverse че то я ваще не догоняю.
Если кто ответит потом еще кое что мб спрошу...(если не нагуглю)
1

#24 Пользователь офлайн   dezdrodomus

  • Пользователь
  • PipPip
  • Группа: Пользователи
  • Сообщений: 177
  • Регистрация: 13 Ноябрь 07

Отправлено 12 Октябрь 2009 - 16:47

Просмотр сообщенияQorlum (11 Октябрь 2009 - 00:13):

Что-то тема не развивается...
Хм.. Никто не кодит на асме?...
Ладно я продолжу...
Разбираюсь сейчас с асмом под линь...
Вот какой-то хрено-макрос (не люблю макросы, люблю, когда все руками прописано где нужно)
Я знаю что он делает, но не знаю этого "макро-синтаксиса" или как его назвать...
Хочу его перевести на норм асмерский язык
macro ccall proc,[arg]			; call CDECL procedure

 { common

    local size

    size = 0

   reverse

    pushd arg

    size = size+4

   common

    call proc

    add esp,size }

кароч скажите что делают вот эти common и reverse че то я ваще не догоняю.
Если кто ответит потом еще кое что мб спрошу...(если не нагуглю)


http://www.comprog.r...article_258.htm
Цитата "
Директивы forward, reverse и common делят макрос на блоки, каждый обрабатывается после того, как обработка предыдущих закончена. Они отличаются по поведению, только если макрос позволяет множественные группы аргументов. Блок инструкций, что следует за директивой forward, будет обработан для каждой группы аргументов с первого до последнего - наподобие обычному блоку (не заданному в соответствии с любой из этих директив). Блок, который следует за директивой reverse, будет обработан для каждой группы аргумента в обратном порядке - от последнего до первого. Блок, который следует за директивой common, будет обработан только однажды, сразу для всех групп аргументов. Значение local, определенное в одном из блоков доступно во всех следующих блоках при обработке той же самой группы аргументов где оно было определено, когда оно определено в блоке common, оно доступно во всех следующих блоках независимо какая группа аргументов обрабатывается.

Вот пример макроса, который создаст таблицу адресов к строкам, заданных этими строками:

macro strtbl name,[string]
{
common
label name dword
forward
local label
dd label
forward
label db string,0
}

Первый аргумент, переданный этому макросу, станет меткой для таблицы адресов, следующие аргументы должны быть строками. Первый блок обрабатывается только один раз и определяет метку, второй блок для каждой строки объявляет ее локальное имя и определяет запись таблицы, содержащую адрес той строки. Третий блок определяет данные каждой строки с соответствующей меткой. Директива, начинающая блок в макросе может сопровождаться первой инструкцией этого блока на той же самой строке, как показано в следующем примере:

macro stdcall proc,[arg]
{
reverse push arg
common call proc
}

Этот макрос может использоваться для вызова процедур, использующих соглашение STDCALL, где аргументы сохраняются на стек в обратном порядке. Для примера stdcall foo, 1,2,3 будет собран как:

push 3
push 2
push 1
call foo

Если некоторое имя в макросе имеет множественные параметры (одним из аргументов, огороженных в квадратные скобки или локальным именем, определенным в блоке, следующем за директивой forward или reverse) и используется в блоке, следующем за директивой common, это имя будет заменено всеми ее величинами, отделенными запятыми. Например следующий макрос передаст все дополнительные аргументы предварительно заданному макросу stdcall:


macro invoke proc,[arg]
{ common stdcall [proc],arg }

Это может использоваться, чтобы вызывать косвенно (по указателю, находящемуся в памяти) процедуру, используя соглашение STDCALL.
"

А терь как сие понимать :)
В макросе 3 блока:
Первый блок size=0
common
local size
size = 0

Второй блок пушит аргументы в обратном порядке(на что нам указывает reverse - т.е. работаем с аргументами в обратном порядке)
Третий блок кол и зачистка стека.
common
call proc
add esp,size
0

#25 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 12 Октябрь 2009 - 18:11

Спасибо... Прочитал ето, и еще статейку там одну с wasm.ru... в общем разобрался с макросами...
И вот еще обещанный вопрос)
каким ассемблерным кодом (желательно FASM) можно заменить
common - ?
reverse - ?
forward - ?


Сейчас начну разбираться...

И кстати нашел более путное описание всех этих коммоннов, форвардов и т. д.
Вот оно!

Операндами этого макроса служат один обязательный (proc) и несколько необязательных параметров (arg). 
Директива reverse сообщает препроцессору, что следующие строки необходимо повторить столько раз, сколько параметров arg передано макросу начиная с последнего параметра.
Директива common сообщает препроцессору, что следующие строки необходимо повторить только один раз.
Директива forward сообщает препроцессору, что следующие строки необходимо повторить столько раз, сколько параметров arg передано макросу начиная с первого параметра. 
Действие директив common, forward и reverse заканчивается другой директивой common, forward или re-verse соответственно или закрывающейся фигурной скобкой. 
Если ни одна из этих директив не встречается в определении макроса, то макрос развернётся для всех параметров начиная с первого. Неизвестное количество параметров можно передать и другому макросу:

1

#26 Пользователь офлайн   dezdrodomus

  • Пользователь
  • PipPip
  • Группа: Пользователи
  • Сообщений: 177
  • Регистрация: 13 Ноябрь 07

Отправлено 13 Октябрь 2009 - 10:33

Чето моя твоя не понимать .... Кворлум Сам вроде задал вопрос и сам вроде на него ответил ... common,reverse,forward это директивы препроцессора, хочешь без них обойтись тады пойми логику макроса и забей все в ручную.
0

#27 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 13 Октябрь 2009 - 20:25

Ну я как бе не сижу просто так... А гуглю...) Ответил не на свой вопрос, а просто написал, что разобрался с макросами...

А вот вам вопрос... загадка)

Сразу говорю код под линух на GTK+
format ELF



include 'cdecl.inc'

include 'gtk.inc'



public main



; extrn blah

extrn gtk_init

extrn gtk_window_new
extrn gtk_button_new_with_label

extrn gtk_signal_connect

extrn gtk_container_add

extrn gtk_container_set_border_width

extrn gtk_widget_show
extrn gtk_main
[b]extrn gtk_widget_set_size_request[/b]
extrn gtk_window_set_default_size
extrn gtk_widget_set_uposition

extrn g_print
extrn exit
section '.data' writeable



    szDeleteEvent   db "delete_event", 0

    szExitMsg	    db "closing application...", 10, 10, 0

    szClicked	    db "clicked", 0

    szClickMe	    db "Click me!", 0

    szWasClicked    db "Button was clicked...", 10, 10, 0



section '.bss' writeable



    hWindow         dd ?
    hButton	    dd ?



section '.text' executable



proc main argc, argv



    lea eax, [argc]

    lea ebx, [argv]



    ccall gtk_init, eax, ebx



    ccall gtk_window_new, GTK_WINDOW_TOPLEVEL

    mov [hWindow], eax


    ccall gtk_button_new_with_label, szClickMe

    mov [hButton], eax



    ccall gtk_signal_connect, [hWindow], szDeleteEvent, DeleteEvent

    ccall gtk_signal_connect, [hButton], szClicked, Buttonclick



    ccall gtk_container_add, [hWindow], [hButton]



    ;ccall gtk_container_set_border_width, [hWindow], 10

    ccall gtk_window_set_default_size, [hWindow],640, 480


    ccall gtk_widget_set_uposition, [hButton],100,150

    [b]ccall gtk_widget_set_size_request, [hButton], 20,50[/b]


    ccall gtk_widget_show, [hButton]



    ccall gtk_widget_show, [hWindow]



    call gtk_main



    ret



endp

proc Buttonclick widget, gdata

    ccall g_print, szWasClicked

    ret

endp

proc DeleteEvent widget, gdata

    ccall g_print, szExitMsg

    ccall exit, 0

    ret

endp


Код на FASMе..
При линковке (gcc -Wall -s -O3 window.o -o window `gtk-config --cflags` `gtk-config --libs`) пишет:
(.text+0xb0): undefined reference to `gtk_widget_set_size_request'
collect2: выполнение ld завершилось с кодом возврата 1

Что это с ним... На другие функции не ругается...
1

#28 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 14 Октябрь 2009 - 23:33

такс... все... решил задачу другим методом...
там походу надо либы обновлять я смотрел там нету такой функции...
1

#29 Пользователь офлайн   dezdrodomus

  • Пользователь
  • PipPip
  • Группа: Пользователи
  • Сообщений: 177
  • Регистрация: 13 Ноябрь 07

Отправлено 15 Октябрь 2009 - 00:06

В старых gtk - gtk_widget_set_size_request нету, надо использовать gtk_widget_set_usize, параметры теже
0

#30 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 15 Октябрь 2009 - 13:25

Я пробовал ее...=)
Она почему то не работает(размер не изменяется...)
Кстати как обновить gtk есть какой-нибудь универсальный способ?
Или надо сносить и по новой останавливать?
1

#31 Пользователь офлайн   Alex Z. Saver

  • Старожил
  • PipPipPipPipPip
  • Группа: Модераторы
  • Сообщений: 3 890
  • Регистрация: 01 Ноябрь 07

Отправлено 17 Октябрь 2009 - 15:38

Может просто дать команду на обновление всех пакетов? B)
0

#32 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 17 Октябрь 2009 - 16:39

Не... пробовал... не обновляется...
0

#33 Пользователь офлайн   o245hc63rus

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 10
  • Регистрация: 30 Январь 09

Отправлено 11 Декабрь 2009 - 12:39

День добрый, срочно нужна помощь, помогите написать 2 программы, у самого мозгов не хватает...
1. задан массив символов. Сформировать на его месте массив, в котором все латинские буквы из исходного массива приобразованы к верхнему регистру. Вывести новый массив и колличество выполненных преобразований.
2.Ввести элементы матрицы 4*4 (слова) - знаковые числа. Если в момент выполнения программы значение минут, определяемое системным таймерова (функция 2CH прерывания 21h), четное, подсчитать сумму отрицательных элементов, если не четное - сумму нечетных элементов матрицы. Вывести на чистом экране: исходную матрицу; Время(часы, минуты), зафиксированное системным таймером; расчитанную сумму или сообщение об тсутствии чисел, удовлетворяющих условию. В последнем случае сопроводить вывод тремя звуковыми сигналами. Очистку экрана выполнить средствами INT 21h
0

#34 Пользователь офлайн   Аllik™

  • Добрый
  • PipPipPipPipPip
  • Группа: Aдминистраторы
  • Сообщений: 2 295
  • Регистрация: 01 Ноябрь 07

Отправлено 12 Декабрь 2009 - 15:07

Первая задачка элементарная, вторая посложнее... Всмысле кода надо побольше писать :)
Сделал бы, но я корыстный и жадный:)



0

#35 Пользователь офлайн   shaggy2007

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 5
  • Регистрация: 01 Ноябрь 07

Отправлено 16 Декабрь 2009 - 17:02

del
-1

#36 Пользователь офлайн   Qorlum

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 42
  • Регистрация: 24 Август 09

Отправлено 19 Декабрь 2009 - 13:55

shaggy2007
1.и что же с ними надо сделать?(с матрицами)
2.компилятор?
3.люди корыстные и жадные
0

#37 Пользователь офлайн   To!!!ka

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 88
  • Регистрация: 13 Август 09

Отправлено 15 Март 2010 - 11:47

Люди добрые, помогите пожалуйста! Препод злой, 5 лаб надо сделать, а никто не знает как, препод ничего толком не объяснила! Дала тест, практики не было вообще.. Мы даже не знаем как ассемблер выглядит :(
ЛИЦЕНЗИОННОЕ программное обеспечение В ЛС
0

#38 Пользователь офлайн   Seskuintan

  • Новичок
  • Pip
  • Группа: Пользователи
  • Сообщений: 7
  • Регистрация: 08 Август 09

Отправлено 19 Июнь 2010 - 20:22

Требуется программист C++, Assembler.
http://forums.avtogr...howtopic=167539
0

  • (2 Страниц)
  • +
  • 1
  • 2
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей