Архитектура компьютера

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

Знакомство с ассемблером Трансляторы можно разделить на две группы в зависимости от отношения между входным и выходным языками. Если входной язык является символическим представлением числового машинного языка, то транслятор называется ассемблером, а входной язык — языком ассемблера, или просто ассемблером.

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

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

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

Отметим, что в ассемблере SPARC после каждой метки нужно ставить двоеточие, а в ассемблере Motorola — нет.

Процессоры семейства Pentium, 680x0 и SPARC позволяют работать с операндами разной длины (размером с байт, слово и длинное слово).

Директивы Ассемблерная программа определяет не только машинные команды, которые нужно выполнять процессору, но и команды, которые нужно выполнять самому ассемблеру (например, выделить немного памяти или выдать новую страницу листинга).

Директива SEGMENT начинает новый сегмент, а директива ENDS завершает его. Разрешается начинать текстовый сегмент, затем начинать сегмент данных, затем переходить обратно к текстовому сегменту и т. д.

Директивы PUBLIC и EXTERN определяют видимость (доступность) символов

Макроопределение — это способ дать имя фрагменту кода. После того как макрос определен, программист может вместо фрагмента кода писать имя макроса

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

Макросы с параметрами Описанные в предыдущем подразделе макросы можно использовать для сокращения объема программ, в которых часто повторяется одна и та же последовательность команд.

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

Реализация макросов в ассемблере Для реализации макросов ассемблер должен уметь выполнять две функции: сохранять макроопределения и расширять макровызовы. Мы рассмотрим эти функции по очереди.

Процесс ассемблирования

Главная цель первого прохода — построить таблицу символов, содержащую значения всех символов.

В таблице кодов операций предусмотрена, по крайней мере, одна запись для каждого символьного кода операции ассемблера

В листинге 7.9 показан механизм, который лежит в основе первого прохода ассемблера.

Цель второго прохода — создать объектную программу и напечатать протокол ассемблирования (если нужно)

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

Задачи компоновщика

Компоновщик объединяет отдельные адресные пространства объектных модулей в единое линейное адресное пространство.

Компоновщик находит все команды, которые обращаются к процедурам, и вставляет в них адреса этих процедур.

Четвертая часть объектного модуля — машинные команды и константы. Это единственная часть объектного модуля, которая загружается в память для выполнения. Остальные пять частей используются компоновщиком, а затем отбрасываются еще до начала выполнения программы.

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

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

Динамическая компоновка Стратегия компоновки, которую мы обсуждали в подразделе «Задачи компоновщика», имеет одну особенность: все процедуры, требуемые программе, компонуются до начала работы программы.

Динамическая компоновка в Windows Все версии Windows, в том числе Windows NT, поддерживают динамическую компоновку. При динамической компоновке используется специальный файловый формат, который называется DLL (Dynamic Link Library — библиотека динамической компоновки)

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

Компилятор вместо ассемблерного кода генерирует объектные модули? Можете ли вы представить себе обстоятельства, при которых метка совпадет с кодом операции (например, может ли команда M0V использоваться в качестве метки)? Аргументируйте

Примеры решения типовых задач математика, физика, электротехника