Смекни!
smekni.com

Разработка виртуальных лабораторных работ средствами эмулятора Emu8086 (стр. 5 из 21)

mov еах, У; Загрузить значение переменной Y в регистр ЕАХ

add eax,4; Прибавить число 4 к регистру ЕАХ

mov ebx,3; Загрузить число 3 в регистр ЕВХ

imul ebx; Умножить содержимое регистра ЕАХ на содержимое ЕВХ

mov Х, еах; Переслать содержимое регистра ЕАХ в переменную X

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

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

Являются ли программы на языке ассемблера переносимыми? Важным отличием языка ассемблера от языков высокого уровня является то, что написанные на нем программы не являются переносимыми. Говорят, что язык программирования является переносимым {portable), если написанные на нем программы можно скомпилировать и запустить на разных компьютерных платформах. Например, программы, написанные на языке C++, Moiyr быть скомпилированы и запушены практически на любом компьютере и п любой операционной системе при условии, что в них не используются вызовы библиотечных функций, характерные для конкретной операционной системы. Основным отличием языка Java является то, что написанные на нем программы после компиляции могут выполняться в любой компьютерной системе, для которой существует реализация виртуальной машины Java.

Учитывая изложенные выше моменты, язык ассемблера не может быть переносимым по определению, поскольку он тесно связан с архитектурой процессоров определенного семейства. Таким образом, на сегодняшний день существует несколько совершенно разных языков ассемблера. Каждый из них привязан либо к конкретному семейству процессоров, либо к конкретной архитектуре компьютера. Среди них можно выделить семейство процессоров Motorola 68x00, Intel IA-32, SUN Sparc, VAX и IBM-370. Команды в языке ассемблера соответствуют командам конкретного процессора. Например, язык ассемблера, рассмотренный в этой книге, предназначен для программирования только процессоров Intel, принадлежащих семейству 1А-32.

Зачем изучать язык ассемблера? А если взять хорошую книгу, в которой описана архитектура конкретного компьютера и структура его процессора? Неужели она не заменит это описание программирования на языке ассемблера?

Я уверен, что вы связаны с написанием программ для встраиваемых компьютерных систем. Подобные программы обычно пишут на языках С, Java или ассемблере, после чего полученный машинный код записывают в запоминающее устройство (постоянное или перепрограммируемое) микроконтроллера. Затем сам микроконтроллер устанавливают в управляемое им устройство. В качестве примера встраиваемых устройств можно привести системы питания и зажигания автомобилей, системы управления кондиционерами, охранные системы, системы управления полетами, электронные записные книжки, модемы, принтеры и другие "умные" устройства, содержащие встроенный микропроцессор.

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

Для прикладного программиста язык ассемблера поможет преодолеть ограничения, накладываемые используемым ими языком высокого уровня в плане выполнения определенных типов операций. Например, в языке Microsoft Visual Basic обработка строковых данных выполняется крайне неэффективно. Поэтому для выполнения операций со строками, такими как шифрование данных и обработка битовых строк, программисты обычно используют подпрограммы, написанные на языке C++ или ассемблере и размешенные в DLL (Dynamic Link Libraries, или динамически загружаемые библиотеки).

Если вы связаны с разработкой специализированного оборудования, то наверняка вам придется написать драйвер устройства, управляющий работой того оборудования, которое выпускает ваша фирма. Драйверы устройств (device drivers) - это низкоуровневые системные программы, напрямую взаимодействующие с обслуживаемыми ими устройствами. В задачу драйвера входит преобразование обобщенных запросов, посылаемых операционной системой на конкретное устройство, в последовательность низкоуровневых команд, характерных для данного конкретного устройства. Например, производители принтеров комплектуют каждое выпускаемое ими устройство отдельными драйверами для каждой из поддерживаемых операционных систем, таких как Microsoft Windows, Mac OS, Linux и др.

Существуют ли какие-либо правила в языке ассемблера? Да, конечно, в языке ассемблера приняты несколько правил, обусловленные внутренней физической структурой самого процессора и его системой команд. Например, два операнда, используемые в одной команде, должны иметь одинаковый размер. Тем не менее, в языке ассемблера гораздо меньше правил, чем, например, вС++.

В программах на языке ассемблера можно легко обойти любые ограничения, принятые в языках высокого уровня. Например, в языке C++ не разрешается присваивать значение указателя одного типа указателю другого типа. Как правило, в этом ограничении нет ничего плохого, поскольку оно позволяет избежать логических ошибок в программах.

Опытный программист может найти способ, как преодолеть это ограничение, однако полученный в результате код будет слишком сложным. В отличие от C++, язык ассемблера не накладывает никаких ограничений относительно указателей. Здесь операции присваивания значений указателям целиком и полностью определяются программистом.

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

Лабораторная работа № 1

Ознакомление с работой эмулятора Emu8086

Цель работы: ознакомление со структурой учебной микроЭВМ (эмулятора Emu8086), органами управления и режимами ее работы.

1. Краткие теоретические сведения

1.1 Структура ассемблерной программы

Каждый язык программирования имеет свои особенности. Язык ассемблера - не исключение. Традиционно первая программа выводит приветственное сообщение на экран ‘Hello World’.

В отличие от многих современных языков программирования в ассемблерной программе каждая команда располагается на ОТДЕЛЬНОЙ СТРОКЕ. Нельзя разместить несколько команд на одной строке. Не принято, также, разбивать одну команду на несколько строк.

Язык ассемблера является РЕГИСТРОНЕЧУВСТВИТЕЛЬНЫМ.Т. е. в большинстве случаев нет разницы между большими и малыми буквами. Команда может быть ДИРЕКТИВОЙ - указанием транслятору. Они выполняются в процессе превращения программы в машинный код. Многие директивы начинаются с точки. Для удобства чтения программы они обычно пишутся БОЛЬШИМИ БУКВАМИ. Кроме директив еще бывают ИНСТРУКЦИИ - команды процессору. Именно они и будут составлять машинный код программы.

Нужно отметить, что понятие "машинного кода" очень условно. Часто оно обозначает просто содержимое выполняемого файла, хранящего кроме собственно машинных команд еще и данные. В нашем случае это будет текст выводимого сообщения "Hello".

1.2 Особенности создания ассемблерной программы в среде DOS средствами TASM и MASM

Язык ассемблера является самым низкоуровневым языком программирования.Т. е. он ближе любых других приближен к архитектуре ЭВМ и ее аппаратным возможностям, позволяя получить к ним полный доступ. В отличие от языков высокого уровня (ЯВУ) ассемблерная программа содержит только тот код, который ВВЕЛ ПРОГРАММИСТ. Никаких дополнительных "обвязок". Вся ответственность за "логичность" кода ПОЛНОСТЬЮ лежит на узких плечах ПРОГРАММИСТА.

Простой пример. Обычно подпрограммы заканчиваются командой возврата. Если ее не задать явно, транслятор все равно добавит ее в конец подпрограммы. Ассемблерная подпрограмма без команды возврата НЕ ВЕРНЕТСЯ в точку вызова, а будет выполнять код, следующий за подпрограммой, как-будто он является ее продолжением. Еще пример. Можно попробовать "выполнить" данные вместо кода. Часто это лишено смысла. Но если программист это сделает, транслятор промолчит. Язык ассемблера позволяет делать все! Тут нет НИКАКИХ ограничений. Но с другой стороны это часто является источником ошибок.

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

Выделим три разновидности "зависания" по способу борьбы с ним.

Простое - для выхода из него достаточно нажать Ctrl+Break или Ctrl+C (сначала нажимается клавиша Ctrl и, НЕ ОТПУСКАЯ ее, нажимается вторая клавиша - C или Break; отпускаются в обратном порядке). Программа при этом аварийно завершается выходом в DOS.

Мягкое - машина не реагирует на Ctrl+Break, но клавиатура "дышит".Т. е. при нажатии на клавиши, типа NumLock, моргают соответствующие светодиоды. В этом случае машину нужно будет перегрузить, нажав Ctrl+Alt+Del. В среде Windows нужно просто "убить" сеанс, закрыв окно.

Жесткое - машина никак не реагирует на клавиатуру и не воспринимает комбинацию Ctrl+Alt+Del. В этом случае поможет аппаратный сброс при помощи кнопки "Reset", расположенной на передней панели системного блока. Не нужно ВЫКЛЮЧАТЬ и включать ЭВМ. Вы как будущие разработчики аппаратуры должны знать, что она выходит из строя в основном при включении и выключении.