Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






ОСНОВЫ ЯЗЫКА АССЕМБЛЕРА




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

Мы научимся подключать фрагменты, написанные на ассемблере, к нашим программам и использовать встроенный (in-line) ассемблер компилятора Microsoft С. Кроме того, мы пойдем чуть дальше и напишем еще парочку графических процедур. Таким образом, эту главу можно разделить на следующие части:

§ Зачем нам нужен ассемблер при написании игр;

§ Описание семейства процессоров 80х86;

§ Регистры ЦПУ;

§ Общий вид процедуры на ассемблере;

§ Передача параметров;

§ Локальные переменные;

§ Создание внешних ссылок;

§ Возвращение параметров;

§ Некоторые полезные управляющие конструкции;

§ Установка видеорежимов;

§ Сверхскоростная очистка экрана;

§ Использование встроенного ассемблера.

Зачем нам нужен ассемблер при написании игр?

Даже для таких компьютерных богов, как Microsoft и Borland, сегодня ассемблер намного быстрее программ на Си. Я помню дни, когда все игры были написаны целиком на ассемблере. Вы можете себе это представить? К счастью сейчас у нас есть куча ученых и программистов, которые заняты разработкой компиляторов. Эти компиляторы дают код, не многим хуже ассемблерного. Но, к сожалению, даже компиляторы чуть-чуть не дотягивают до идеала. Вот почему нам обычно приходится последние пять процентов делать своими руками. Мы должны применять ассемблер для рисования точек, линий, выполнения заливок, наложений и т. д. Мы вынуждены его применять там, где нужна сверхскорость - в графике.

Существует несколько способов включения ассемблера в наши программы:

§ Можно написать на ассемблере отдельную функцию и вызывать ее из Си. Мы используем этот способ в критичных по времени выполнения участках программы;

§ Мы можем использовать такую штуку, как встроенный ассемблер. Он позволяет использовать инструкции ассемблера наравне с Си-кодом. Это неоценимая находка для разработчика видеоигр, поскольку вам не надо использовать кучу промежуточных утилит и создавать массу независимых текстов программ. Кроме того, встроенный ассемблер здорово экономит ваше время.

Прежде чем двинуться дальше, я хочу предостеречь вас от одной из крайностей - не надо пытаться написать на ассемблере все. Используйте его экономно и только тогда, когда он действительно нужен. В противном случае ваш код будет довольно сложен и непереносим (кстати, в том же самом DOOM'e на ассемблере написано всего несколько процедур, а все остальное — это эффективный Си-код). Если же вам надо написать более двух тысяч строк ассемблера, то лучшим решением будет пересмотр применяемого вашего алгоритма.



Обзор семейства процессоров 80x86

Семейство процессоров 80х86 более чем разнообразно. Фирма Intel создала процессоров больше, чем вы в состоянии представить. Игры и программы, которые мы будем создавать в этой книге, ориентированы только на 386-, 486- и 586-процессоры. Для наших целей мы будем говорить о реальном режиме работы этих процессоров: режим эмуляции процессора 8086, используемый DOS с 640-килобайтным ограничением.

Как вы знаете, первым из этого семейства был 8088. Он стоял на первом ПК. Потом его сменил 8086, но это уже история. Весь мир перешел на DOS которая изначально была ориентирована на процессор 8086. Производя процес­соры 286, 386, 486, 586 (и вроде скоро появится 686), Intel обеспечивал поддержку 8086-процессора. Это значит, что даже на 586 ПК вы неизбежно натолкнетесь в DOS'e на 640-килобайтный барьер.

На самом деле, это ужасно, поскольку 386 и все последующие 32-разрядные процессоры имеют непрерывную модель памяти (без сегментов), более мощные инструкции и т. д. Использование только новых инструкций сделает наши игры более мощными. Более того, непрерывная модель памяти устранит понятие сегментных регистров, 640-килобайтного барьера и всего, что с ним связано. Мы можем указать компилятору порождать 286-инструкции, дав соответствующую директиву, но это будут лишь 16-битные команды, которые не дадут нам возможности использования всех средств 32-разрядных процессоров типа 386 486 и 586.



Кстати, для удобства я буду называть 386-, 486- и 586-процессоры просто «процессорами».

В функции процессора входит перемещение данных в памяти и выполнение с ними некоторых преобразований. К ним относятся математические и логические (например, И, ИЛИ, НЕ) операции, проверка различных условий и т. п. Любой процессор должен иметь достаточно много регистров, чтобы его можно было эффективно программировать (они нужны для сохранения данных). Регистры процессора ПК будут описаны в следующем разделе.

Регистры процессора

Регистры общего назначения. Данные регистры используются во время выполнения программ и во многих случая являются взаимозаменяемыми. Кроме того, каждый из них имеет определенное предназначение.

АХ - 16 бит, общего назначения, часто именуется аккумулятором;

ВХ - 16 бит, общего назначения и индексный;

СХ - 16 бит, общего назначения и счетчик;

DX - 16 бит, общего назначения;

ВР - 16 бит, общего назначения, используется для хранения смещения и индексов, часто называется регистром базы;

SI - 16 бит, общего назначения, используется в операциях с памятью (SI — source issue — регистр источника, используется для хранения смещения Источника при выполнении строковых команд);

DI - 16 бит, общего назначения, используется в операциях с памятью (DI - destination issue — регистр приемника, используется для хранения смещения пункта назначения при выполнении строковых команд).

 

Сегментные регистры.Данные регистры используются как указатели на сегменты. Сегмент - это блок размером в 64К, который предназначен для определенных целей: для хранения программного кода, данных и т. д.

DS - сегмент данных;

CS - сегмент кода;

ES - дополнительный сегмент;

SS - сегмент стека;

IP - счетчик.

Флаговый регистр

Этот регистр сохраняет статусы состояния процессора, такие как: Z (zero - ноль), С (carry - перенос) и т. д. Этот регистр не доступен напрямую, но его содержимое можно узнать с помощью соответствующих инструкций.

Общий вид ассемблерной функции

Процедуры ассемблера очень похожи на Си-функции. У них есть начало, конец и код, расположенный в середине. В этой книге мы будем ссылаться на Microsoft macro assembler версий от 5.1 до 6.1 (MASM). Это связано с тем, что.в них уже есть директивы, упрощающие стыковку с программами на Си.

 

Примечание

MASM версии 5.0 подойдет для первого примера, но для успешной работы с книгой вам понадобится версия 5.1 или старше.

 

Прежде чем начать изучение способов передачи параметров и прочих интересных вещей, давайте посмотрим, что нам нужно как минимум для написания внешней программы на ассемблере, которую мы потом вызовем из Си. Итак, Листинг 2.1 покажет вам прототип процедуры на ассемблере.


mylektsii.ru - Мои Лекции - 2015-2019 год. (0.006 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал