Литвек - электронная библиотека >> Игорь Орещенков >> Программирование: прочее и др. >> Введение в NASM (низкоуровневое программирование для Windows)

Игорь Орещенков ВВЕДЕНИЕ В NASM (низкоуровневое программирование для Windows)

«Абстрактных, ненужных знаний нет. В жизни может случиться, что только знание того, какой чешский король разбил монголов, спасет твою голову».

В. Короткевич «Черный замок Ольшанский».
Несмотря на победное и безостановочное шествие технологических инноваций, постоянное увеличение плотности транзисторов на кристалле и ошеломляющие прорывы в области нанотехнологий, процессоры по-прежнему не способны общаться с человеком на естественном языке. И вряд ли станут способны на это в обозримом будущем. Скорее всего, они, как и в прошлом веке, будут понимать лишь ограниченный набор машинных команд, а значит, сохранится потребность в специалистах, которые способны выразить идею лаконичным машинным языком.

Сегодня мы можем наблюдать проникновение микропроцессорной техники практически во все отрасли деятельности человека. Организации осознали выгоду электронного документооборота, вкладывают все большие средства в развитие собственных вычислительных систем и интегрируются в глобальную сеть. Сетевое оборудование должно обладать достаточным «интеллектом», чтобы управлять трафиком и обеспечивать эффективное функционирование сети. Мобильные телефоны благодаря наличию в них мощных вычислительных устройств превратились в тамагочи для взрослых. Да что там говорить — самая последняя кофеварка норовит обзавестись собственным микропроцессором и подключиться не только к электрической, но и к вычислительной сети. Современные микропроцессоры обеспечивают огромную производительность и предоставляют в распоряжение разработчиков постоянно расширяющиеся наборы команд. С одной стороны, это открывает потрясающие перспективы, с другой — накладывает ответственность на специалистов, управляющих их работой. Ведь чтобы реализовать весь потенциал микропроцессора, программист должен применить эффективный алгоритм и воспользоваться при этом самыми подходящими из имеющихся инструкций.

Да, компиляторы с языков высокого уровня обеспечивают такую необходимую сегодня скорость разработки конечного продукта. В большинстве случаев, с которыми сталкивается рядовой программист, ему нет необходимости искать эффективный путь решения задачи — микропроцессор сам «вытянет» это решение, за считанные секунды перебрав миллионы вариантов. Но кому-то придется разрабатывать эти компиляторы, включать в них поддержку инструкций новых процессоров, оптимизировать перевод лексем языка высокого уровня в машинный код. Кто-то должен оптимизировать критические участки кода, чтобы дать возможность остальным позабыть о подобных проблемах и стремиться к «более высоким вершинам». В конце концов, кто-то должен написать первый SDK для нового микропроцессорного устройства, будь то мобильный телефон или кофеварка. Конечно, потребность в таких специалистах намного меньше, чем в программистах «1С» и Visual Basic. Но она будет всегда, пока будут микропроцессоры современного типа. И эти же специалисты пойдут в первых рядах, когда (если) будут изобретены принципиально новые вычислительные устройства. И для тех же прикладных программистов никогда не будет лишним знать, во что превращается высокоуровневый код при его исполнении процессором, и где могут возникнуть «узкие места». Естественно, сразу разобраться с принципами программирования на низком уровне не удастся. Нужно «учиться, учиться и еще раз учиться», а потом приобретать опыт, наступать на грабли, работать над ошибками. И начинать лучше всего в привычной среде, каковой для большинства IT-специалистов является персональный IBM-совместимый компьютер. Кроме того, желательно при разработке программного обеспечения ориентироваться сразу на современную операционную систему, а не на DOS, как это зачастую делается в учебниках.

Возможно ли это — низкоуровневое программирование под Windows? На этот вопрос можно с полной уверенностью заявить: да, и процесс этот можно обставить с достаточным комфортом. Речь в этой статье пойдет как раз о выборе инструментария, организации рабочего места и базовых правилах программирования на ассемблере для 32-разрядных операционных систем семейства Windows. Что же нужно смельчаку, рискнувшему погрузиться в мир низкоуровневого программирования? Если он является убежденным аскетом, то абсолютно ничего, кроме операционной системы и горы технической документации. В самом деле, набрать программу в шестнадцатеричном коде можно даже при помощи текстового редактора. И это не просто бравада автора — на сайте [1] заинтригованный читатель может ознакомиться с лучшими образцами «программистского дзэна». Однако такой подход является скорее искусством и требует огромных затрат времени и сил, обладая при этом очень низким коэффициентом полезного действия. Можно ли сделать низкоуровневое программирование продуктивным? Чтобы разработчик мог не только отвести душу, но и конкурировать на рынке программного обеспечения? Ответить однозначно на эти вопросы сложно. Скорее всего, читатель сам получит ответ, если дочитает эту статью, а потом опробует предложенные рекомендации на практике.

Итак, для продуктивного низкоуровневого программирования прежде всего необходим ассемблер — компилятор мнемонических инструкций в машинный код. Действительно, листинг программы на ассемблере при наличии в нем комментариев и осмысленных меток после некоторой практики читается практически так же легко, как и программа, записанная на языке высокого уровня. Какой же компилятор предпочесть? Чтобы остановить свой выбор на конкретном экземпляре, необходимо рассмотреть хотя бы несколько возможных. На первом месте, естественно, стоит Macro Assembler от Microsoft (MASM).

Большинство приверженцев низкоуровневого программирования для Windows используют его в своих проектах и не имеют претензий. Следует отметить, что Macro Assembler как самостоятельный продукт перестал существовать с версии 6.13, зато появились энтузиасты, которые стали формировать пакеты, отбирая необходимые утилиты из SDK, DDK и Visual Studio. Так появился MASM32 [2] — пакет, содержащий все необходимое для низкоуровневого программирования: собственно ассемблер, компоновщик, библиотекарь и даже пакет документации с большим количеством примеров. К числу положительных черт MASM можно отнести его популярность. Огромное количество макроинструкций и отвлеченных понятий, которые не являются необходимыми для записи алгоритма в понятной для процессора форме, вызывает уважение с одной стороны и вносит путаницу с другой. Кажется, что этот язык