Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Раздел 6. Уровень языка ассемблера





Язык ассемблера – это язык, в котором каждое высказывание соответствует ров­но одной машинной команде. Иными словами, существует взаимно однозначное соответствие между машинными командами и операторами в программе на языке ассемблера. Если каждая строка в программе на языке ассемблера содержит ровно один оператор и каждое машинное слово содержит ровно одну команду, то про­грамма на языке ассемблера в n строк произведет программу на машинном языке из n слов.

Програм­мировать на языке ассемблера гораздо проще, т.к. это позволяет избежать работы с кодами команд. Многие могут запомнить, что обозначениями для сложения (add), вычитания (subtract), умножения (multiply) и деления (divide) служат команды ADD, SUB, MUL и DIV, но мало кто может запомнить соответ­ствующие числа, которые использует машина. Программисту на языке ассемблера нужно знать только символические названия, поскольку ассемблер компилирует их в машинные команды.

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

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

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

 

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

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

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

Тема 6.1. Формат оператора в языке ассемблера

В результате изучения данной темы Вы будете:

  • знать структуру операторов языка ассемблер.

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

Для компьютеров семейства Intel существует несколько ассемблеров, которые отличаются друг от друга по синтаксису. Мы будем использовать язык ассемблера Microsoft MASM.

Высказывания языка ассемблера состоят из четырех полей: поля метки, поля операции, поля операндов и поля комментариев (Таблица 6.1).

 

Метка Команда Операнды Комментарии
FORMULA: MOV EAX, I ; регистр EAX=I
  ADD EAX, J ; регистр EAX=I+J
  MOV N, EAX ; N=I+J
       
I: DW   ; резервируем 4 байта и устанавливаем значение 3
J: DW   ; резервируем 4 байта и устанавливаем значение 4
N: DW   ; резервируем 4 байта и устанавливаем значение 0

Таблица 6.1. Вычисление выражения N=I+J в Pentium II

Метки

Метки используются для того, чтобы обеспечить символические имена для адресов памяти. Они нужны для того, чтобы можно было совершить переход к командам, а также для слов с данными, чтобы по символическому имени можно было получить доступ к тому месту, где они хранятся. Если высказывание снабжено меткой, то эта метка обыч­но располагается в колонке 1 (Таблица 6.1).

Метка в языке Ассемблер может содержать следующие символы:

  • буквы: от А до Z и от а до z
  • цифры: от 0 до 9
  • символы: знак вопроса (?)

точка (.) (только первый символ)

знак-"коммерческое эт" (@)

подчеркивание(_)

доллар ($)

Первым символом в метке должна быть буква или специальный символ. Ассемблер не делает различия между заглавными и строчными буквами. Для примера можно привести метки: COUNT, PAGE25, $Е10. Рекомендуется использовать описательные и смысловые метки. Все имена регистров, например, АХ, DI или AL, являются зарезервированными и используются только для указания соответствующих регистров.

Команды

В поле команды содержится либо символическая аббревиатура кода операции (если высказывание является символической репрезентацией машинной коман­ды), либо команда для самого ассемблера.

Операнды

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

Комментарии

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

Подведем итоги

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

Вопросы для самоконтроля

1. Можете ли вы представить себе обстоятельства, при которых метка совпа­дет с кодом операции (например, может ли быть MOV меткой)? Аргументи­руйте свой ответ.

2. Чем отличается счетчик адреса команд от счетчика команд? А существует ли вообще между ними различие? Ведь и тот и другой следят за следующей командой в программе.

3. Какие из следующих имен неправильны: а) PC_AT, б) $50, в) @$_z, г) 34b7, д) EAX?

Тема 6.2. Директивы

В результате изучения данной темы Вы будете:

  • знать, что такое директивы языка ассемблер, чем они отличаются от команд;
  • знать наиболее важные директивы и их предназначение.

Программа на языке ассемблера должна не только определять, какие машинные команды нужно выполнить, но и содержать команды, которые должен выпол­нять сам ассемблер (например, потребовать от него определить местонахожде­ние какой-либо сохраненной информации или выдать новую страницу листинга). Команды для ассемблера называютсяпсевдокомандами илидирективамиассемблера. Мы уже видели одну типичную псевдокоманду DW (Таблица 6.1), ниже приведены некоторые другие директивы. Они взяты из ассемблера MASM для семейства Intel (Таблица 6.2).


 

 

Директива Значение
SEGMENT Начинает новый сегмент (текста, данных и т.п.) с определенными атрибутами
ENDS Завершает текущий сегмент
ALIGN Контролирует выравнивание следующей команды или данных
EQU Определяет новый символ, равный данному выражению
DB Выделяет память для одного или нескольких байтов
DD Выделяет память для одного или нескольких 16-битных полуслов
DW Выделяет память для одного или нескольких 32-битных слов
DQ Выделяет память для одного или нескольких 64-битных двойных слов
PROC Начинает процедуру
ENDP Завершает процедуру
MACRO Начинает макроопределение
ENDM Завершает макроопределение
PUBLIC Экспортирует имя, определенное в данном модуле
EXTERN Импортирует имя из другого модуля
INCLUDE Вызывает другой файл и включает его в текущий файл
IF Начинает условную компоновку программы на основе данного выражения
ELSE Начинает условную компоновку программы, если условие IF над директивой не выполнено
ENDIF Завершает условную компоновку программы
COMMENT Определяет новый отделитель комментариев
PAGE Совершает принудительный обрыв страницы в листинге
END Завершает программу ассемблирования

Таблица 6.2. Некоторые директивы ассемблера MASM

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

Директива ALIGN переводит следующую строку (обычно данные) в адрес, кото­рый делим на аргумент данной директивы. Например, если текущий сегмент уже содержит 61 байт данных, тогда следующим адресом после ALIGN 4 будет адрес 64.

Директива EQU дает символическое название некоторому выражению. Напри­мер, после записи:

BASE EQU 1000

символ BASE можно использовать вместо 1000. Выражение, которое следует за EQU, может содержать несколько символов, соединенных арифметическими и другими операторами, например:

LIMIT EQU 4 * BASE + 2000

Большинство ассемблеров, в том числе MASM, требуют, чтобы символ был определен в программе до появления в некотором выражении.

Следующие 4 директивы DB, DD, DW и DQ распределяют память для одной или не­скольких переменных размером 1, 2, 4 и 8 байтов соответственно. Например:

TABLE DB 11, 23, 49

выделяет пространство для 3 байтов и присваивает им начальные значения 11, 23 и 49 соответственно. Эта директива, кроме того, определяет символ TABLE, равный тому адресу, где хранится число 11.

Директивы PROC и ENDP определяют начало и конец процедур языка ассембле­ра. Процедуры в языке ассемблера выполняют ту же функцию, что и в языках программирования высокого уровня. Директивы MACRO и ENDM определяют начало и конец макроса.

Далее идут директивы PUBLIC и EXTERN. Программы часто пишут в виде совокуп­ности файлов (модулей). Часто процедуре, находящейся в одном файле, нужно вызвать про­цедуру или получить доступ к данным, определенным в другом файле. Чтобы та­кие отсылки между файлами стали возможными, обозначение (имя), которое нужно сделать доступным для других файлов, экспортируется с помощью директивы PUBLIC. Чтобы ассемблер не «ругался» по поводу использования символа, который не определен в данном файле, этот символ может быть объявлен внешним (EXTERN), это сообщит ассемблеру, что символ определен в каком-то другом файле. Символы, которые не определены ни в одной из этих директив, используются только в пре­делах одного файла.

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

Директива COMMENT позволяет пользователю изменять символ комментария на что-либо отличное от точки с запятой. Директива PAGE используется для управле­ния распечаткой листинга (текста) программы. Наконец, директива END отмечает конец программы.

Подведем итоги

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

Вопросы для самоконтроля

1. Чем отличается команда от директивы?

2. Какова длина в байтах для элементов данных, определенных директивами: а) DW, б) DD, в) DB, г) DQ?

3. Укажите различия в значении RET и END.

4. Какая директива заставляет делать прогон листа?

Тема 6.3. Макросы

В результате изучения данной темы Вы будете:

  • знать, что такое макросы и способы их применения;
  • уметь создавать макроопределения, как без параметров, так и с ними.

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

Альтернативный подход – оформить эту последовательность в процедуру и вы­зывать ее в случае необходимости. У такой стратегии тоже есть свои недостатки, поскольку в этом случае каждый раз придется выполнять специальную команду вызова процедуры и команду возврата. Если последовательности команд корот­кие (например, всего две команды), но используются часто, то вызов процедуры может сильно снизить скорость работы программы. Макросы являются простым и эффективным решением этой проблемы.

Макроопределение – это способ дать имя куску текста. После того как макрос был определен, программист может вместо куска программы писать имя макроса. В сущности, макрос – это обозначение куска текста. Ниже приведена про­грамма, которая дважды меняет местами со­держимое переменных P и Q (Листинг 6.1). Эти последовательности команд можно определить как макросы (Листинг 6.2).

 

MOV EAX, P

MOV EBX, Q

MOV Q, EAX

MOV P, EBX

 

MOV EAX, P

MOV EBX, Q

MOV Q, EAX

MOV P, EBX

Листинг 6.1. Код на языке ассемблера, в котором содержимое переменных P и Q дважды меняются местами (без использования макроса)

 

SWAP MACRO

MOV EAX, P

MOV EBX, Q

MOV Q, EAX

MOV P, EBX

ENDM

 

SWAP

SWAP

Листинг 6.2. Тот же код, но с использованием макроса

После определения макроса каждое имя SWAP в програм­ме замещается следующими четырьмя строками:

MOV EAX, P

MOV EBX, Q

MOV Q, EAX

MOV P, EBX

Программист определил SWAP как обозначение для этих четырех операторов.

Макросы состоят из базовых частей:

  1. Заголовок макроса, в котором дается имя определяемого макроса.
  2. Текст, в котором приводится тело макроса.
  3. Директива, которая завершает определение (ENDM).

Когда ассемблер наталкивается на макроопределение в программе, он сохраня­ет его в таблице макроопределений для последующего использования. Всякий раз, когда в программе в качестве кода операции появляется макрос (в нашем примере SWAP), ассемблер замещает его телом макроса. Использование имени макроса в ка­честве кода операции называетсямакровызовом, а его замещение телом макроса называетсямакрорасширением.

Макросы могут содержать параметры. Например, макрос SWAP можно переписать как:

SWAP MACRO P1, P2

MOV EAX, P1

MOV EBX, P2

MOV P2, EAX

MOV P1, EBX

ENDM

Таким образом, программа примет вид:

SWAP P, Q

SWAP P, Q

А макрос SWAP можно будет применять не только для переменных P и Q, но и любых других.

Подведем итоги

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

Вопросы для самоконтроля

1. Что такое макрос, макровызов, макрорасширение?

2. Может ли регистр использоваться в качестве фактического параметра в макровызове? А константа? Объясните свой ответ.

3. Чем отличается макрос от вызова процедуры?

4.

Какой сгенерированный код будет меньше – тот, который содержит макросы, или тот, который содержит аналогичные процедуры? Какой код будет выполняться быстрее? Ответ обоснуйте.

Индивидуальные задания

Напишите макрос SWAP для обмена содержимым двух регистров.

_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________







ЧТО И КАК ПИСАЛИ О МОДЕ В ЖУРНАЛАХ НАЧАЛА XX ВЕКА Первый номер журнала «Аполлон» за 1909 г. начинался, по сути, с программного заявления редакции журнала...

Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычис­лить, когда этот...

ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между...

ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.