Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции Ассемблер.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
286.77 Кб
Скачать

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

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

Рисунок 1 - Состав СПО

Операционные системы

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

Основные ресурсы:

  • процессор

  • оперативная память

  • периферийные устройства Управление ресурсами сводится к :

  1. упрощению доступа к ресурсам

  2. распределению ресурсов между конкурирующими за ними процессами Сервисные системы

Сервисные системы - это системы, дополняющие и расширяющие пользовательский интерфейс и ОС. Делятся на:

  1. интерфейсные

  2. оболочки

  3. утилиты

Инструментальные системы

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

Системы программирования - совокупность языка программирования и виртуальной машины.

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

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

Транслятор - программа, осуществляющая перевод текста с одного языка на другой.

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

Ассемблер - это транслятор, осуществляющий перевод программ с языка низкого уровня на машинный язык.

Интерпретатор - программный продукт, выполняющий предъявленную программу путем одновременного ее анализа и реализации ее действий Представление данных в компьютерах

Минимальной единицей информации в компьютере является бит. Бит может принимать значения 0 или 1.

Группа из восьми бит представляет собой байт. Биты или разряды в байте пронумерованы от 0 до 7 справа налево:

Номера битов: 7 6 5 4 3 2 1 0 Значение битов :1 0 1 0 1 0 0 1

Два байта или шестнадцать бит представляют собой слово.

Биты в слове пронумерованы от 0 до 15 справа налево:

Номера битов: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Значение битов: 1 0 1 0 1 0 1 0 1 1 1 1 0 0 0 0

В этом слове байт с разрядами от 8 до 15 является старшим байтом и имеет значение 10101010, байт с разрядами от 0 до 7 является младшим байтом и имеет значение 11110000.

Все вычисления в компьютере производятся в двоичной системе счисления, т.е. в двоичном коде. Шестнадцатеричная форма представления чисел является краткой записью чисел в двоичном коде. Для этого четыре двоичных разряда записываются одним шестнадцатеричным разрядом. Кроме этих двух форматов представления чисел могут использоваться десятичный, двоично-десятичный (BCD) и ASCII - коды.

  1. Двоичный код.

Двоичный код допускает двоичные цифры 0 и 1. Признаком двоичного числа является буква В, которая ставится в конце. Например, 10101001В.

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

Позиционные веса: 128 64 32 16 8 4 2 1 Включенные биты : 1 1 1 1 1 1 1 1

Сумма восьми единичных битов в данном случае составит 255 (1+2+4+...+128).

  1. Десятичный код

Десятичный код допускает десятичные цифры от 0 до 9.

Признаком десятичного числа является буква D, которая ставится в конце. Если в конце числа буква отсутствует, то число воспринимается как десятичное.

  1. Шестнадцатеричный код

Шестнадцатеричный код допускает цифры от 0 до 9 и буквы от A до F. Признаком шестнадцатеричного числа является буква H, которая ставится в конце. Число должно обязательно начинаться с цифры. Байт содержит два шестнадцатеричных разряда, слово - четыре разряда.

Ниже приведены двоичные, десятичные и шестнадцатеричные значения чисел от 0 до 15.

Двоич.

Дес.

Шест.

Двоич.

Дес.

Шест.

0000

0

0

1000

8

8

0001

1

1

1001

9

9

0010

2

2

1010

10

А

0011

3

3

1011

11

В

0100

4

4

1100

12

С

0101

5

5

1101

13

D

0110

6

6

1110

14

Е

0111

7

7

1111

15

F

  1. Двоично-десятичный код (BCD)

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

от 00 до 99.

В распакованном формате в байте содержится одна цифра в младшей тетраде, старшая тетрада равна нулю:

от 00 до 09.

  1. ASCII - код

Для обмена данными между МП и принтером, клавиатурой или дисплеем используются ASCII коды. ASCII код (американский стандартный код для обмена информацией) используется для кодирования алфавитно-цифровой информации в компьютере.

Например, цифры от 0 до 9 имеют ASCII коды от 48 до 57 (30h до 39h). Заглавные буквы от "A" до "Z" имеют ASCII коды от 65 до 90 (от 41h до 5Ah), прописные буквы от "а" до "z" -от 097 до 122 (от 61h до 7Ah). Для вывода результата на дисплей нужно его представить в ASCII коде. Например: требуется вывести на дисплей число 17h. Для этого сначала его нужно распаковать, а затем преобразовать в ASCII код.

  1. Unicode

Unicode — это универсальная международная кодировка, которая предусматривает выделение для набора символов каждого языка определенной непрерывной последовательности двоичных чисел. Символы Unicode хранятся в памяти компьютера в виде 16-разрядных чисел (в отличие от символов ASCII- кода, которые хранятся в виде 8-разрядных чисел), что позволяет представить свыше 60 тысяч различных символов; расплатой за универсальность Unicode является снижение плотности хранения информации (на каждый символ расходуется два байта памяти вместо одного).

Набор символов латинского алфавита (то есть символов английского языка) и математические символы считаются в Unicode основными, обозначаются в документации как Basic Latin и размещаются в диапазоне 0020h-007Eh. Преобразование латинских символов из формата Unicode в ASCII-код сводится к простому отсечению старшего байта.

  1. Представление отрицательных чисел.

Отрицательные числа в компьютере представляется в дополнительном коде (получение дополнительного кода: инвертировать все биты и прибавить 1). Так для числа 65, имеющем представление в двоичном коде01000001, дополнительный код имеет вид 10111111 ,это и есть -65. Знаковый - самый старший разряд. Таким образом, для байтов со знаком минимальное число -128, а максимальное +127.

Основная литература: 1[2-16],2[17-20][12-15],

Дополнительная литература: 10[17-20].

Контрольные вопросы:

  1. Перечислите составляющие системного программного обеспечения.

2.Чем отличается Unicode от ASCII кода.

  1. Запишите формулу для представления числа в позиционной системе счисления.

  2. Как представляется отрицательное число.

Тема лекции 2. Архитектура микропроцессора I 8086.

Архитектура ЭВМ — это абстрактное представление ЭВМ, которое отражает ее структурную, схемотехническую и логическую организацию. Понятие архитектуры ЭВМ включает в себя:

-структурную схему ЭВМ;

-средства и способы доступа к элементам структурной схемы ЭВМ; -организацию и разрядность интерфейсов ЭВМ;

-набор и доступность регистров;

-организацию и способы адресации памяти;

-способы представления и форматы данных ЭВМ;

-набор машинных команд ЭВМ;

-форматы машинных команд;

-обработку нештатных ситуаций (прерываний).

Все современные ЭВМ обладают некоторыми общими и индивидуальными свойствами архитектуры. Индивидуальные свойства присущи только конкретной модели компьютера. Наличие общих архитектурных свойств обусловлено тем, что большинство типов существующих машин принадлежат 4 и 5-му поколениям ЭВМ фон-неймановской архитектуры. К числу общих архитектурных свойств и принципов можно отнести:

-Принцип хранимой программы. Согласно ему, код программы и ее данные находятся в одном адресном пространстве в оперативной памяти.

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

-Линейное пространство памяти — совокупность ячеек памяти, которым последовательно присваиваются номера (адреса) О, 1, 2, .... Последовательное выполнение программ. Процессор выбирает из памяти команды строго последовательно. Для изменения прямолинейного хода выполнения программы или осуществления ветвления необходимо использовать специальные команды. Они называются командами условного и безусловного перехода.

-С точки зрения процессора нет принципиальной разницы между данными и командами. Данные и машинные команды находятся в одном пространстве памяти в виде последовательности нулей и единиц. Это свойство связано с предыдущим. Процессор, исполняя содержимое некоторых последовательных ячеек памяти, всегда пытается трактовать его как коды машинной команды, а если это не так, то происходит аварийное завершение программы, содержащей некорректный фрагмент. Поэтому важно в программе всегда четко разделять пространство данных и команд.

-Безразличие к целевому назначению данных. Машине все равно, какую логическую нагрузку несут обрабатываемые ею данные.

Набор регистров.

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

-16 пользовательских регистров;

- 16 системных регистров.

Пользовательские регистры

Пользовательскими регистрами программист может пользоваться и при написании своих программ. К этим регистрам относятся:

-восемь 32-битных регистров, которые могут использоваться программистами для хранения данных и адресов (их еще называют регистрами общего назначения (РОН)): eax/ax/ah/al, ebx/bx/bh/bl, edx/dx/dh/dl, ecx/cx/ch/cl, ebp/bp, esi/si, edi/di, esp/sp

-шесть регистров сегментов: cs, ds, ss, es, fs, gs;

-регистры состояния и управления: регистр флагов eflags/flags и регистр указателя команды eip/ip.

Регистры общего назначения

Все регистры этой группы позволяют обращаться к своим «младшим» частям; использовать для самостоятельной адресации можно только младшие 16- и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты недоступны. Так как регистры общего назначения находятся в процессоре внутри арифметико-логического устройства (АЛУ), то их еще называют регистрами АЛУ:

  • eax/ax/ah/al (Accumulator register) — аккумулятор. Применяется для хранения промежуточных данных. В некоторых командах использование этого регистра обязательно;

  • ebx/bx/bh/bl (Base register) — базовый регистр. Применяется для хранения базового адреса некоторого объекта в памяти;

  • ecx/cx/ch/cl (Count register) — регистр-счетчик. Применяется в командах, производящих некоторые повторяющиеся действия. Его использование зачастую неявно и скрыто в алгоритме работы соответствующей команды. Например, команда организации цикла loop кроме передачи управления команде, находящейся по некоторому адресу, анализирует и уменьшает на единицу значение регистра есх/сх;

  • edx/dx/dh/dl (Data register) — регистр данных. Так же как и регистр еах/ах/ ah/al, он хранит промежуточные данные. В некоторых командах его использование обязательно; для некоторых команд это происходит неявно. Следующие два регистра используются для поддержки так называемых цепочечных операций, то есть операций, производящих последовательную обработку цепочек элементов, каждый из которых может иметь длину 32, 16 или 8 бит:

  • esi/si (Source Index register) — индекс источника. Этот регистр в цепочечных операциях содержит текущий адрес элемента в цепочке-источнике;

  • edi/di (Destination Index register) — индекс приемника (получателя). Этот регистр в цепочечных операциях содержит текущий адрес в цепочке-приемнике.

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

  • esp/sp (Stack Pointer register) — регистр указателя стека. Содержит указатель вершины стека в текущем сегменте стека;

  • ebp/bp (Base Pointer register) — регистр указателя базы кадра стека. Предназначен для организации произвольного доступа к данным внутри стека.

Сегментные регистры

В программной модели микропроцессора имеется шесть сегментных регистров: cs, ss, ds, es, gs, fs. Их существование обусловлено спецификой организации и использования оперативной памяти микропроцессорами Intel. Она заключается в том, что микропроцессор аппаратно поддерживает структурную организацию программы в виде трех частей называемых сегментами.

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

  1. Сегмент кода. Содержит команды программы. Для доступа к этому сегменту служит регистр cs (code segment register) — сегментный регистр кода. Он содержит адрес сегмента с машинными командами, к которому имеет доступ микропроцессор (то есть эти команды загружаются в конвейер микропроцессора);

Сегмент данных. Содержит обрабатываемые программой данные. Для доступа к этому сегменту служит регистр ds (data segment register) — сегментный регистр данных, который хранит адрес сегмента данных текущей программы;

  1. Сегмент стека. Этот сегмент представляет собой область памяти, называемую стеком. Работу со стеком микропроцессор организует по следующему принципу: последний записанный в эту область элемент выбирается первым. Для доступа к этому сегменту служит регистр ss (stack segment register) — сегментный регистр стека, содержащий адрес сегмента стека;

  2. Дополнительный сегмент данных. Неявно алгоритмы выполнения большинства машинных команд предполагают, что обрабатываемые ими данные расположены в сегменте данных, адрес которого находится в сегментном регистре ds. Если программе недостаточно одного сегмента данных, то она имеет возможность использовать еще три дополнительных сегмента данных. Но в отличие от основного сегмента данных, адрес которого содержится в сегментном регистре ds, при использовании дополнительных сегментов данных их адреса требуется указывать явно с помощью специальных префиксов переопределения сегментов в команде. Адреса дополнительных сегментов данных должны содержаться в регистрах es, gs, fs (extension data segment/ registers).

  3. Регистры состояния и управления

В микропроцессор включены несколько регистров, которые постоянно содержат информацию о состоянии как самого микропроцессора, так и программы, команды которой в данный момент загружены на конвейер. К этим регистрам относятся: 1- регистр флагов eflags/flags; 2- регистр указателя команды eip/ip.

Используя эти регистры, можно получать информацию о результатах выполнения команд и влиять на состояние самого микропроцессора. Назначение и содержимое этих регистров:

eflags/flags (flag register) — регистр флагов. Разрядность eflags/flags — 32/16 бит. Отдельные биты данного регистра имеют определенное функциональное назначение и называются флагами. Младшая часть этого регистра полностью аналогична регистру flags для i8086.

Флаги регистра eflags/flags можно разделить на три группы:

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

  2. 1 флаг управления. Обозначается как df (Directory Flag). Он находится в 10­м бите регистра eflags и используется цепочечными командами.

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

Флаги состояния.

Мне

мони

ка

флага

Флаг

Номе

р

бита

в

eflags

Содержание и назначение

cf

Флаг

переноса(Car ry Flag)

0

1 — арифметическая операция произвела перенос из старшего бита результата. Старшим является 7-й, 15-й или 31-й бит в зависимости от размерности операнда;

0 — переноса не было

pf

Флаг

паритетами ty Flag)

2

1 — 8 младших разрядов (этот флаг — только для 8 младших разрядов операнда любого размера) результата содержат четное число единиц;

0 — 8 младших разрядов результата содержат нечетное число единиц

af

Вспомогател ь-ный флаг переноса (Auxiliary carry Flag)

4

Только для команд, работающих с BCD- числами. Фиксирует факт заема из младшей тетрады результата:

1 — в результате операции сложения был произведен перенос из разряда 3 в старший разряд или при вычитании был заем в разряд 3 младшей тетрады из значения в старшей тетраде;

0— переносов и заемов в (из) 3 разряд(а) младшей тетрады результата не было

zf

Флаг нуля(Zero Flag) Флаг знака(Sign Flag)

б

1 — результат нулевой;

0 — результат ненулевой

sf

7

Отражает состояние старшего бита результата (биты 7, 15 или 31 для 8, 16 или 32­разрядных операндов соответственно):

1— старший бит результата равен 1; 0— старший бит результата равен 0

of

Флаг

переполнени

я(Overflow

Flag)

11

Флаг of используется для фиксирования факта потери значащего бита при арифметических операциях:

1— в результате операции происходит перенос (заем) в (из) старшего, знакового бита результата (биты 7, 15 или 31 для 8, 16 или 32­разрядных операндов соответственно);

0 — в результате операции не происходит переноса (заема) в (из) старшего, знакового бита результата

iopl

Уровень

привилегий

ввода-

вывода^^^

/Output

Privilege

Level)

12, 13

Используется в защищенном режиме работы микропроцессора, для контроля доступа к командам ввода-вывода в зависимости от привилегированности задачи

nt

Флаг

вложенности

задачи

(Nested Task)

14

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

Системные флаги

tf

Флаг трассировки (Trace Flag)

8

Предназначен для организации пошаговой работы микропроцессора:

I — микропроцессор генерирует прерывание с номером 1 после выполнения каждой машинной команды. Может использоваться при отладке программ, в частности отладчиками;

0 — обычная работа

if

Флаг прерывания (Interrapt ena ble Flag)

9

Предназначен для разрешения или запрещения (маскирования) аппаратных прерываний (прерываний по входу INTR): I — аппаратные прерывания разрешены;

0 — аппаратные прерывания запрещены

rf

Флаг

возобновления (Resume Flag)

16

Используется при обработке прерываний от регистров отладки

vm

Флаг

виртуального8086 (Virtual 8086 Mode)

17

Признак работы микропроцессора в режиме виртуального 8086:

1 — процессор работает в режиме виртуального 8086;

0 — процессор работает в реальном или защищенном режиме

ас

Флаг контроля выравнивания (Alignment Check)

18

Предназначен для разрешения контроля выравнивания при обращениях к памяти,И кратным 2 или 4, то установка данных битов приведет к тому, что все обращения по некратным адресам будут возбуждать исключительную ситуацию

eip/ip (Instruction Pointer register) — указатель команд. Регистр eip/ip имеет разрядность 32/16 бит и содержит смещение следующей подлежащей выполнению команды относительно содержимого сегментного регистра cs в текущем сегменте команд. Этот регистр непосредственно недоступен программисту, но загрузка и изменение его значения производятся различными командами управления, к которым относятся команды условных и безусловных переходов, вызова процедур и возврата из процедур. Возникновение прерываний также приводит к модификации регистра eip/ip.

Основная литература :5[16-36], 38[33-44],3[7-12],

Дополнительная литература :19[10-15].

Контрольные вопросы:

1.Что входит в понятие Архитектура ЭВМ?

  1. В каких регистрах содержится информация об адресах сегментов?

  2. Какие регистры можно использовать для подсчета числа циклов?

  3. Какие регистры используются для адресации исполняемой программы?

Тема лекции 3. Язык Ассемблер. Структура программы на ассемблере. Использование сегментов в микропроцессоре I 8086.

Ассемблер - это машинно-ориентированный язык представления программ, написанных в машинных кодах. Он дает программисту следующие возможности:

-использовать символические обозначения машинных команд (мнемокоды);

-присваивать символические имена регистрам и ячейкам памяти;

-использовать различные системы счисления и арифметические и логические

выражения для записи чисел и др.

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

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

20

делятся на две группы: команды и директивы (псевдокоманды). При

трансляции команды переводятся в машинный код, трансляция директивы сводится к ее выполнению в ходе трансляции.

Команда, записанная на языке Ассемблера, имеет следующий вид: [Метка:] Мнемокод [Операнды] [; Комментарии],

где в квадратные скобки помещены необязательные поля команды. Приведенные поля команд отделяются друг от друга пробелами, либо знаками табуляции - Tab. Поле метки служит для присваивания команде имени, по которому на нее могут ссылаться другие команды, например, команды передачи управления. Метка должна заканчиваться двоеточием, состоять из латинских букв, цифр и специальных символов "?", "@", "_" и "$", при этом первым символом не может быть цифра. Поле мнемокода содержит название команды ЦП. Поле операндов содержит информацию о местонахождении данных, подлежащих обработке. В некоторых случаях, когда операнды заданы по умолчанию (строковые команды, XLAT и др.) или вовсе не нужны (команда NOP), это поле пустое. В командах с двумя операндами первый является приемником результата, второй - источником информации. Поле комментариев содержит текст, поясняющий работу программы. Комментарий может занимать всю строку, если в первой позиции указать точку с запятой. Псевдокоманды записываются в следующем виде:

[Идентификатор] Псевдокоманда [Операнды] [; Комментарии], где в квадратные скобки помещены необязательные поля псевдокоманды. Приведенные поля псевдокоманд отделяются друг от друга пробелами либо знаками табуляции.

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

Физическая память, к которой микропроцессор имеет доступ по шине адреса, называется оперативной памятью (или оперативным запоминающим устройством — ОЗУ). На самом нижнем уровне память компьютера можно рассматривать как массив битов. Один бит может хранить значение О или 1. ОЗУ организовано как последовательность ячеек — байтов. Один байт состоит из 8 бит. Каждому байту соответствует свой уникальный адрес (его номер), называемый физическим. Диапазон значений физических адресов зависит от разрядности шины адреса

32

микропроцессора. Для i486 и Pentium он находится в пределах от 0 до 2 - 1 (4

Гбайт).

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

Каждая программа в общем случае может состоять из любого количества сегментов, но непосредственный доступ она имеет только к трем основным: кода, данных и стека, — и от одного до трех дополнительных сегментов данных. Операционная система размещает сегменты программы в оперативной памяти по определенным физическим адресам, после чего помещает значения этих адресов в определенные места. Куда именно, зависит от режима работы микропроцессора. Так, в реальном режиме эти адреса помещаются непосредственно в соответствующие сегментные регистры, а в защищенном режиме они размещаются в элементы специальной системной дескрипторной таблицы. Внутри сегмента программа обращается к адресам относительно начала сегмента линейно, то есть начиная с 0 и заканчивая адресом, равным размеру сегмента. Этот относительный адрес, или смещение, который микропроцессор использует для доступа к данным внутри сегмента, называется эффективным.

Под физическим адресом понимается адрес памяти, выдаваемый на шину адреса микропроцессора Другое название этого адреса — линейный адрес. Эта двойственность в названии обусловлена наличием страничной модели организации оперативной памяти. Эти названия являются синонимами только при отключении страничного преобразования адреса (в реальном режиме страничная адресация всегда отключена).

Формирование физического адреса в реальном режиме

В реальном режиме механизм адресации физической памяти имеет следующие характеристики:

  • диапазон изменения физического адреса от 0 до 1 Мбайт. Эта величина определяется тем, что шина адреса i8086 имела 20 линий;

  • максимальный размер сегмента 64 Кбайт. Это объясняется 16­разрядной архитектурой i8086. Таким образом максимальное значение, которое могут содержать 16-разрядные регистры, составляет 216 - 1, что применительно к памяти и определяет величину 64 Кбайт;

Для обращения к конкретному физическому адресу оперативной памяти необходимо определить адрес начала сегмента (сегментную составляющую)и смещение внутри сегмента. Сегменты располагаются в памяти на границе паpагpафов

(паpагpаф - объем памяти pазмеpом в 16 байт), поэтому в адресе начала сегмента последняя цифра равна нулю. Напpимеp:10000h, 1FFF0h. (Таким образом, в сегментном регистре достаточно хранить только старшие 16 бит физического адреса начала сегмента. Недостающие младшие нулевые четыре бита 20-битного адреса получаются сдвигом значения в сегментном регистре влево на 4 разряда. Эта операция сдвига выполняется аппаратно и для программного обеспечения абсолютно прозрачна. Получившееся 20-битное значение и является настоящим физическим адресом, соответствующим началу сегмента. Что касается второго компонента, участвующего в образовании физического адреса некоторого объекта в памяти, — смещения, — то оно представляет собой 16-битное значение. Это значение может содержаться явно в команде либо косвенно в одном из регистров общего назначения. В микропроцессоре эти две составляющие складываются на аппаратном уровне, в результате чего получается физический адрес памяти размерностью 20 бит. Данный механизм образования физического адреса позволяет сделать программное обеспечение перемещаемым, то есть не зависящим от конкретных адресов загрузки его в оперативной памяти.)

(Следует заметить следующее о несоответствии размеров шины адреса микропроцессора i486 или Pentium (32 бита) и 20-битного значения физического адреса реального режима. Пока микропроцессор находится в реальном режиме, старшие 12 линий шины адреса недоступны, хотя при определенных условиях и существует возможность работы с первыми 64 Кбайт оперативной памяти, лежащими сразу после первого мегабайта.)

Так как в реальном режиме адреса сегментов хранятся в сегментных pегистpах, а адреса смещений - в pегистpе IP для сегмента кода, в одном из pегистpов BX,SI,DI для сегмента данных, в одном из pегистpов SP, BP для сегмента стека и в pегистpе DI для дополнительного сегмента данных, то микpопpоцессоp вычисляет адреса памяти доступа к сегменту данных по формулам:

(DS)x16 + BX или (ds)x16 + S1 или (ds)x16 + D1 к сегменту кода:

(CS)x16 + (IP) к сегменту стека:

(SS)x16 + SP или (SS)x16 + BP

к дополнительному сегменту данных:

(ES)x16 + DI.

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

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

Например: Задан массив слов DW 0110h , 0220H , 0330h, 0440h В памяти он будет представлен : DS:0000 10 01 20 02 30 03 40 04 Основная литература :5[46,120-125],8[21-32]7 [40-50].

Контрольные вопросы:

  1. Какие возможности предоставляет ассемблер программисту?

  2. Какой вид имеет команда, записанная на языке Ассемблера?

  3. Какой вид имеет псевдокоманда на языке Ассемблера?

  4. Как определяется эффективный адрес?

  5. Как вычисляется физический адрес в реальном режиме?

Тема лекции 4.Описание данных. Режимы адресации.

Описание данных

Для определения данных используются, главным образом, три директивы ассемблера: db (define byte, определить байт) длёя записи байтов, dw (define word, определить слово) для записи слов и dd (define double, определить двойное слово) для записи двойных слов:

size dw 256 ;В ячейку size записывается

;десятичное число 256

setb7 db 80h ;Bячейку setb7записывается

;1б-ричное число 80h

Для резервирования места под массивы используется оператор dup (duplicate, дублировать), который позволяет «размножить» байт, слово или двойное слово заданное число раз:

rawdata dw 300 dup (1) ;Резервируются 300 слов,

;заполненных числом 1

string db 80 dup (") /Резервируются 80 байтов,

;заполненных знаком "

Кроме перечисленных, имеются и другие директивы, например df (define farword, определить поле из 6 байт), dq (define quadword, определить четверное слово) или dt (define teraword, определить 10-байтовую переменную), но они используются значительно реже.

Режимы адресации.

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

Способы задания операндов команды определяют режимы адресации.

Все обращения к данным делятся на три типа:

  • Обращения к непосредственным данным

  • Обращения к данным в регистрах

  • Обращения к данным в памяти

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

В двухоперандной машинной команде возможны следующие сочетания операндов:

  • регистр—регистр;

  • регистр—память;

  • память—регистр;

  • непосредственный операнд—регистр;

  • непосредственный операнд—память.

Непосредственная адресация (непосредственный операнд) - операнд задается в самой команд ,т.е его значения записываются прямо в машинном коде команд.

Например: mov ах, 5

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

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

Например: mov ax, bx

В качестве регистров могут использоваться:

- 32-разрядные регистры ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP; - 16­разрядные регистры АХ, ВХ, СХ, DX, SI, DI, SP, ВР; - 8-разрядные регистры АН, AL, BH, BL, CH, CL, DH, DL; -

сегментные регистры CS, DS, SS, ES, FS, GS.

Основные виды адресации операндов в памяти. Цель всех разновидностей данной адресации- помочь процессору вычислить 16-битовое беззнаковое значение, называемое эффективным адресом, или ЭА. ЭА показывает смещение, начиная от базового сегмента, адресуемого одним из четырех сегментных регистров: cs, ds, es, ss. (Сегментный регистр и смещение образуют 32-битовый логический адрес, который в дальнейшем преобразуется в 20-битовый физический адрес, однозначно определяющий положение байта в памяти.) Общее число режимов адресации, т.е способов обращения к операндам определяется архитектурой микропроцессора (так по документации только микропроцессор 8088 имеет 24 режима адресации операндов!).

Основные виды адресации операндов в памяти : прямая, косвенная ,базовая ,индексная , базово-индексная.

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

;Сегмент данных

meml dw 0; слово памяти содержит 0 mem2 db 230; байт памяти содержит 230 ;Сегмент команд

inc meml ; Содержимое слова meml увеличивается на 1 mov DX, meml ; Содержимое слова с именем meml загружается в DX mov AL,mem2 ;Содержимое байта с именем mem2 загружается в AL При прямой адресации можно использовать выражение, состоящее из некоторой переменной или константы, которая добавляется к соответствующему смещению имени переменной. Таким образом можно обращаться к полям составной переменной (например, можно обеспечить доступ к полям сложной переменной, например, структуры).

Адрес любой ячейки состоит из двух компонентов: сегментного адреса и смещения. Сегментные же адреса хранятся в сегментных регистрах: DS, ES, CS и

SS. Процессор узнает, из какого регистра взять сегментный адрес с помощью префиксов замены сегмента (Имеется несколько групп префиксов: повторения, размера адреса, размера операнда, замены сегмента.)

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

ES

assume ES: data

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

Однако в ряде случаев префикс замены сегмента должен указываться в программе в явной форме. Такая ситуация возникает, например, если данные расположены в сегменте команд, что типично для резидентных обработчиков прерываний. Для обращения к таким данным можно, конечно, использовать регистр DS, если предварительно настроить его на сегмент команд, но проще выполнить адресацию через регистр CS, который и так уже настроен должным образом. Если в сегменте команд содержится поле данных с именем mem, то команда чтения из этого поля будет выглядеть следующим образом: mov АХ,С S:mem1

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

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

mov AX,0B800h ;Сегментный адрес видеобуфера

mov ES,AX ;Отправим его в ES

mov byte ptr ES: 0, ' ! ' ;Отправим символ на 1-е

знакоместо экрана

mov byte ptr ES:2, ' ! ' ;Отправил символ на 2-е

знакоместо экрана

Заметим, что команда mov ES:0,'!'

вызовет ошибку трансляции, так как ассемблер не сможет определить, надо ли транслировать это предложение, как команду пересылки в видеобуфер байта 21h, или как команду пересылки слова 0021h.

При необходимости можно было воспользоваться для записи в видеобуфер регистром DS:

mov AX ,0B800h ;Сегментный адрес

mov DS, AX ;видеобуфера в DS

mov byte ptr DS:0,'!' ;Символ в видеобуфер

В код команды префикс замены сегмента не включается, но запись DS: необходима,

так как при записи mov 6,10 . будет ошибка (переслать число 10 в число 6),

команда mov DS:6,10 пересылает число 10 по относительному адресу 6, что имеет смысл.

Косвенная адресация

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

Синтаксически в команде этот режим адресации выражается заключением имени регистра в квадратные скобки [ ].

команда mov ax,[ecx] помещает в регистр ах содержимое слова по адресу из сегмента данных со смещением, хранящимся в регистре есх.

Косвенной адресации для микропроцессора 18086 можно использовать только регистры [ВХ], [SI], [DI], [ВР]. Для первых трех регистров их содержимое является смещением по отношению к сегменту данных (т.е. текущее значение сегментного регистра DS определяет вторую составляющую адреса). Регистр [ВР] определяет смещение в сегменте стека (текущее содержимое сегментного регистра SS) для вычисления адреса. При использовании регистров ВХ или ВР адресацию называют базовой, при использовании регистров SI или DI — индексной.

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

mov AX,OB800h ;Сегментный адрес

mov ES, AX ; видеобуфера в ES

mov BX,2 0 0 0 ; Смещение к середине экрана

mov byte ptr ES : [BX] , ‘!’ ; Символ на экран

Если косвенная адресация осуществляется через один из регистров ВХ, SI или DI, то подразумевается сегмент, адресуемый через DS, поэтому при адресации через этот регистр обозначение DS: можно опустить: mov AX, 0B800h ; Сегментный адрес

mov DS, AX ;Видеобуфера в DS

mov BX, 2000 ; Смещение к середине экрана

mov byte ptr [BX] , ' ! ' ;Символ на экран

Этот фрагмент немного эффективнее предыдущего в смысле расходования памяти. Из-за отсутствия в коде последней команды префикса замены сегмента он занимает на 1 байт меньше места.

Регистры ВХ, SI и DI в данном применении совершенно равнозначны, и с одинаковым успехом можно воспользоваться любым из них: mov D1, 2 000 ;Смещение к середине экрана

mov byte ptr [DI] , ' ! ' ; Символ на экран

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

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

Команда с базовой адресацией занимает меньше места в памяти (так как в нее не входит адрес ячейки) и выполняется быстрее команды с прямой адресацией (из-за того, что команда короче, процессору требуется меньше времени на ее считывание из памяти). Поэтому базовая адресация эффективна в тех случаях, когда по заданному адресу приходится обращаться многократно, особенно, в цикле.

Для микропроцессоров старше I80386 косвенная индексная адресация и косвенная адресация по базе расширена. В качестве индексных регистров можно использовать все регистры данных - ([ЕАХ], [ЕВХ], [ЕСХ], [EDX]), а так же три индексных регистра - ([ЕВР], [ESI], [ED1]). В этом случае константа может быть или байтом, или двойным словом, и эта константа рассматривается как число со знаком.

Для всех регистров, кроме [ЕВР], при расчете адреса используется текущее содержимое сегментного регистра DS, а для регистра [ЕВР] -содержимое сегментного регистра SS.

Регистровая косвенная адресация со сдвигом (базовая и индексная). Относительный адрес операнда определяется, как сумма содержимого регистра ВХ, ВР, SI или DI и указанной в команде константы, называемой сдвигом, смещением или перемещением. Сдвиг может быть числом или адресом. Так же, как и в случае базовой адресации, при использовании регистров ВХ, SI и DI подразумевается сегмент, адресуемый через DS, а при использовании ВР подразумевается сегмент стека и, соответственно, регистр SS.

Рассмотрим применение косвенной адресации со смещением на примере прямого вывода в видеобуфер.

mov AX,0B800h ;Сегментный адрес

mov ES, АХ ; видеобуфера в ES

mov DI, 80*2*24 ;Смещение к нижней строке

экрана

mov byte ptr ES: [DI] , 'О' ;Символ на экран mov byte ptr ES: 2 [DI] , 'К' ;Запишем символ в следующую позицию

mov byte ptr ES : 4 [DI], '! ' ;Запишем символ в следующую позицию В этом примере в качестве базового выбран регистр DI; в него заносится базовый относительный адрес памяти, в данном случае смещение в видеобуфере к началу последней строки экрана. Модификация этого адреса с целью получить смещение по строке экрана осуществляется с помощью констант 2 и 4,

которые при вычислении процессором исполнительного адреса прибавляются к содержимому базового регистра DI.

Вместо, 4[ВХ] можно с таким же успехом написать [ВХ+4], 4+[ВХ] или [BX]+4.

Рассмотрим пример, когда сдвиг задается адресом массива, а в регистре находится индекс адресуемого элемента в этом массиве. Пусть надо заполнить массив из 10000 слов натуральным рядом чисел.

;Сегмент данных array dw 10000 dup(0)

;Сегмент команд

mov S1, 0 Начальное значение индекса элемента в

массиве

mov AX, 0 ;Первое число-заполнитель

mov СХ,10000 ; Число шагов в цикле (всегда в СХ)

fill: mov array[SI],AX ;Занесение числа в элемент массива

inc AX Инкремент числа-заполнителя

add SI, 2 ;Смещение в массиве к следующему слову

loop fill ;Возврат на метку fill (СХ раз)

Цикл начинается с команды, помеченной меткой fill (правила образования имен меток такие же, как и для имен полей данных). В этой команде содержимое АХ, сначала равное 0, переносится в ячейку памяти, адрес которой вычисляется, как сумма адреса массива array и содержимого индексного регистра SI, в котором в первом шаге цикла тоже 0. В результате в первое слово массива заносится 0. Далее содержимое регистра АХ увеличивается на 1, содержимое регистра SI — на 2 (из-за того, что массив состоит из слов), и командой loop осуществляется переход на метку fill, после чего тело цикла повторяется при новых значениях регистров АХ и SI. Число шагов в цикле, отсчитываемое командой loop, определяется исходным содержимым регистра СХ.

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

Относительный (эффективный ) адрес операнда определяется как сумма содержимого следующих пар регистров.

[ВХ] [SI] (подразумевается DS : [ВХ] [SI])

[ВХ] [DI] (подразумевается DS:[BX][DI])

[ВР] [SI] (подразумевается SS:[BP][SI])

[ВР] [DI] (подразумевается SS:[BP][DI])

В одном из регистров находится, как правило адрес массива, а в другом - индекс.

Рассмотрим предыдущий пример с введением в него базово-индексной адресации .

Сегмент данных

array dw 10000 dup(0)

;Сегмент команд

mov BX,offset array ;Базовый адрес массива в ;базовом регистре

mov SI, 0 ;Начальное значение индекса ;элемента в массиве

mov AX, 0 ;Первое число-заполнитель

mov CX,10000 ; Число шагов в цикле

fill: mov [BX][SI],AX ; Отправим число в массив

inc AX Инкремент числа-заполнителя

add SI, 2 ; Смещение в массиве к следующему слову

loop fill ;На метку fill (CX раз)

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

Базово-индексная адресация со сдвигом. Относительный адрес операнда определяется как сумма содержимого двух регистров и сдвига

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

Пусть в сегменте данных определен массив из 24 байтов, в котором записаны коды латинских и русских символов верхнего ряда клавиатуры: sims db QWERTYUIOP{}”

db "ЙЦУКЕНГШЩЗХЪ ”

Последовательность команд mov BX,12 ; Число байтов в строке

mov SI,6

mov DL,syms[BX][SI]

загрузит в регистр DL элемент с индексом 6 из второго ряда, т.е. код ASCII буквы Г. Тот же результат можно получить, загрузив в один из регистров не индекс, а адрес массива:

mov BX, offset sym

mov SI, 6

mov DL,12 [BX] [SI]

Косвенная адресация с масштабированием (микропроцессор I80386 и старше)

Еще одна дополнительная возможность косвенной адресации используется в микропроцессорах I80386 и старше - при индексной адресации (простой и адресации по базе с индексированием) содержимое индексного регистра ([ЕАХ], [ЕВХ], [ЕСХ], [EDX], [EBP], [ESI], [EDI]) можно дополнительно умножить на масштабный множитель -число 1, 2, 4, 8. (Использование множителя 1 соответствует обычной индексной адресации). Такой подход позволяет упростить доступ к элементам массива, имеющих элементы, кратные множителю (например, к элементам массивов, состоящим

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

Основная литература:5[125-135],7[74-82],4[98-110],

Дополнительная литература: 18[113-118].

Контрольные вопросы:

1 Какие три основные директивы ассемблера используются для определения данных ?.

  1. Как описать строку в ассемблере?

  2. На какие типы делятся все обращения к данным?

  3. Назовите основные виды адресации операндов в памяти.

  4. Какие способы адресации удобно использовать для работы с массивами?

Тема лекции 5. Команды микропроцессора. Классификация. Группа команд пересылки данных.

Система команд микропроцессора содержит около 130 машинных команд. С появлением каждой новой модели микропроцессора их количество, как правило, возрастает.Классификация команд представлена на рисунке 2.

Пересылки

Арифметичес

Логические

Передачи

Цепочечные

Управления

данных

кие

управления

состоянием

ЦП

Команды ассемблера

Общего

назначения

Двоичной

арифметики

Манипуляции битами

Безусловные

Десятичной

арифметики

Рисунок 2. Машинные команды и их функциональные группы

Группа команд пересылки данных.

Включает

  1. команды пересылки данных

  2. команды ввода-вывода в порт;

Условные

Работы со стеком

Сдвига

Преобразование

типов

  1. команды работы с адресами и указателями;

  2. команды преобразования данных;

  3. команды работы со стеком.

Команды пересылки данных

К этой группе относятся следующие команды: mov < операнд назначения>, <операщ~источник> xchg <операнд 1>,<операнд2>

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

mov АХ,500 ; АХ :=500 mov BL,DH ; BL:=DH

Требование: необходимо следить, чтобы размерности (типы) пересылаемых операндов соответствовали друг другу.

Нельзя:

1 пересылать из одной области памяти в другую;

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

  1. загрузить в сегментный регистр значение непосредственно из памяти (нужно использовать промежуточный объект: регистр общего назначения или стек.)

  2. переслать содержимое одного сегментного регистра в другой сегментный регистр. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных все те же регистры общего назначения. Вот пример инициализации регистра es значением из регистра ds:

mov ax, ds mov es,ax

Но есть и другой, более красивый способ выполнения данной операции — использование стека и команд push и pop:

push ds ; поместить значение регистра ds в стек pop es ;записать в es число из стека

  1. нельзя использовать сегментный регистр cs в качестве операнда назначения, так как пара cs:ip всегда содержит адрес команды, которая должна выполняться следующей. Изменение командой mov содержимого регистра cs фактически означало бы операцию перехода, а не пересылки, что недопустимо.

Как известно, в ПК числа размером в слово хранятся в памяти в "перевернутом" виде, а в регистрах - в нормальном, неперевернутом. Команда MOV учитывает это и при пересылке слов между памятью и регистрами сама "переворачивает" их:

Q dw 1234h ; Q: 34h, Q+l: 12h MOV AX, Q. ; AH-12h, AL-34h Пусть имеются такие описания переменных X DB ?

YDW ?

Как правило, в команде MOV легко узнается тип (размер) одного из операндов, он и определяет размер пересылаемой величины. Например:

MOV ВН, 0; пересылка байта (ВН - байтовый регистр)

MOV х, 0 ; то же самое (X описан как имя байтовой переменной)

MOV SI, 0 ; пересылка слова (SI - регистр размером в слово)

MOV Y, 0 ; то же самое (Y описан как имя переменной-слова)

Отметим, что здесь по второму операнду (0) нельзя определить, какого он размера: ноль может быть и байтом (00h), и словом (0000h).

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

MOV DI, ES ; пересылка слова

MOV СН, Х ; пересылка байта

MOV DX, AL ; ошибка (DX - слово, AL - байт)

MOV BH, 300 ; ошибка (ВН - байт, а 300 не может быть байтом)

Необходимо использовать оператор ptr во всех сомнительных относительно согласования размеров операндов случаях.

mov ax, word ptr [bx] ;если [Ьх] адресует слово в памяти inc byte ptr [bx] ; если [bx] адресует байт в памяти dec dword ptr [bx] ;если [bx] адресует двойное слово в памяти mov word ptr [bx],0 ;если [bx] адресует слово в памяти (PTR (от pointer, указатель) записывается следующим образом:

<тип> PTR <выражение>

где <тип> • это BYTE, WORD или DWORD (есть и другие варианты), а выражение может быть константным или адресным.

Если указано константное выражение, то оператор "говорит", что значение этого выражения (число) должно рассматриваться ассемблером как величина указанного типа (размера); например, BYTE PTR 0 - это ноль как байт, a WORD PTR 0 - это ноль как слово (запись BYTE PTR 300 ошибочна, т. к. число 300 не может быть байтом). Отметим, что в этом случае оператор PTR относится к константным выражениям.

Если же в PTR указано адресное выражение, то оператор "говорит", что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа (размера); например: WORD PTR A - адрес А обозначает слово (байты с адресами А и А+1). В данном случае оператор PTR относится к адресным выражениям.

Также этот оператор нужно применять, когда требуется принудительно поменять размерность операндов. Например, требуется переслать значение 0ffh во второй байт поля flp:

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

flp dw 0

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

mov byte ptr (flp+1), 0ffh

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

Команды ввода-вывода в порт

Операнды машинной команды могут находиться в портах ввода-вывода. Каждое устройство ввода/вывода, каждое системное устройство имеет один или несколько регистров, доступ к которым осуществляется через адресное пространство ввода/вывода. Эти регистры имеют разрядность 8, 16 или 32 бит. Адресное пространство ввода/вывода физически независимо от пространства оперативной памяти и имеет ограниченный объем, составляющий 216, или 65536 адресов ввода/вывода. Таким образом, понятие порта ввода-вывода можно определить как 8, 16 или 32-разрядный аппаратный регистр, имеющий определенный адрес в адресном пространстве ввода/вывода. Вся работа системы с устройствами на самом низком уровне выполняется с использованием портов ввода-вывода. Упрощенная, концептуальная схема управления оборудованием компьютера имеет вид:

Рисунок3. Концептуальная схема управления оборудованием компьютера

Для работы с портами используются две команды : in и out .

in аккумулятор, номерпорта — ввод в аккумулятор из порта с номером номер_ порта;

out порт, аккумулятор - вывод содержимого аккумулятора в порт с номером номер_ порта.

Команды работы со стеком

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

Для работы со стеком предназначены три регистра: ss — сегментный регистр стека; sp/esp — регистр указателя стека;

bp/ebp — регистр указателя базы кадра стека.

Размер стека зависит от режима работы микропроцессора и ограничивается 64 Кбайт (или 4 Гбайт в защищенном режиме).

Особенности работы со стеком:

  • запись и чтение данных в стеке осуществляется в соответствии с принципом LIFO (Last In First Out — «последним пришел, первым ушел»);

  • по мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком;

  • при использовании регистров esp/sp и ebp/bp для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра ss.

Для организации работы со стеком существуют специальные команды записи и чтения.

push источник — запись значения источник в вершину стека. алгоритм работы этой команды:

  1. (sp) = (sp) - 2; значение sp уменьшается на 2;

pop назначение — запись значения из вершины стека по месту, указанному операндом назначение. Значение при этом «снимается» с вершины стека

  1. -значение из источника записывается по адресу, указываемому парой ss:

sp.

pop назначение — запись значения из вершины стека по месту, указанному операндом назначение. Значение при этом «снимается» с вершины стека алгоритм работы этой команды:

1) запись содержимого вершины стека по месту, указанному операндом назначение

2 )(sp) = (sp) + 2; увеличение значения sp.

Основная литература :5[129-152],9[42-46]

Дополнительная литература: 19[78-88].

Контрольные вопросы:

  1. Приведите классификацию команд ассемблера.

  2. Перечислите команды, входящие в группу пересылки данных.

  3. Назовите команды пересылки для работы со стеком.

  4. Какой оператор необходимо использовать во всех сомнительных отно­сительно согласования размеров операндов случаях.

Лекция 6 . Команды микропроцессора. Группа команд передачи управления. Циклы.

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

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

  1. Команды безусловной передачи управления:

- команда безусловного перехода;

  • вызов процедуры и возврата из процедуры;

  • вызов программных прерываний и возврат из программных прерываний.

  1. Команды условной передачи управления:

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

  • команды перехода по состоянию определенного флага;

  • команды перехода по содержимому регистра есх/сх.

  1. Команды управления циклом:

  • команда организации цикла со счетчиком есх/сх;

  • команда организации цикла со счетчиком есх/сх с возможностью досрочного выхода из ци- near — переход на эту метку возможен только в пределах сегмента кода, где эта метка описана. Физически это означает, что для перехода на метку достаточно изменить только содержимое регистра eip/ip;

  • far — переход на эту метку возможен только в результате межсегментной передачи управления, для осуществления которой требуется изменение как содержимого регистра eip/ip, так и регистра cs.

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

Транслятор ассемблера предоставляет две возможности работы с этим счетчиком:

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

  • Применение специального символа $ для обозначения счетчика адреса команд. Этот символ позволяет в любом месте программы использовать численное значение счетчика адреса. Классический пример:

.data

; вычисление длины строки в сегменте данных

Str_Mes db ".Работаешь на ПК - изучи ассемблер”,’$’

Len_Msg=$-Str_Mes

После ассемблирования значение Len_Msg будет равно длине строки, так как значение символа $ в месте его появления отличается от Str_Mes ровно на длину строки.

Кроме возможности получения значения счетчика адреса, компилятор TASM позволяет, при необходимости, установить счетчик адреса в нужное абсолютное значение. Это делается с помощью директивы ORG:

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

Безусловные переходы осуществляются с помощью команды jmp, которая может использоваться в 5 разновидностях. Переход может быть:

  • прямым коротким (в пределах -128...+127 байтов); прямым ближним (в пределах текущего сегмента команд); прямым дальним (в другой сегмент команд);

  • косвенным ближним (в пределах текущего сегмента команд через ячейку с адресом перехода);

косвенным дальним (в другой сегмент команд через ячейку с адресом перехода).

Рассмотрим последовательно структуру программ с переходами разного

вида.

Прямой короткий (short) переход. Прямым называется переход, в команде которого в явной форме указывается метка, на которую нужно перейти. Метка должна присутствовать в том же программном сегменте, при этом помеченная ею команда может находиться как до, так и после команды jmp. Команда короткого перехода занимает 2 байт памяти: в первом байте записывается код операции (EBh), во втором — смещение к точке перехода. Расстояние до точки перехода отсчитывается от очередной команды, т.е. команды, следующей за командой jmp. Поскольку требуется обеспечить переход как вперед, так и назад, смещение рассматривается, как число со знаком и, следовательно, переход может быть осуществлен максимум на 127 байт вперед или 128 байт назад. Прямой короткий переход оформляется следующим образом:

code segment

jmp short go ;Код ЕВ dd

go: code ends

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

code segment

jmp go ;Код EB dddd

go: code ends

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

предполагается, что программный комплекс включает несколько сегментов

команд. Команда дальнего перехода имеет длину 5 байт и включает, кроме кода

операции EAh, еще и полный адрес точки перехода, т.е. сегментный адрес и смещение. Транслятору надо сообщить, что этот переход — дальний (по умолчанию команда jmp транслируется, как команда ближнего перехода). Это делается с помощью описателя far ptr, указываемого перед именем точки перехода.

codel segment

assume CS:codel ;Сообщим транслятору, что это сегмент команд jmp far ptr go ;Код EA dddd ssss • • •

codel ends code2 segment

assume CS:code2 ; Сообщим транслятору, что это сегмент команд go:

code2 ends

Метка go находится в другом сегменте команд этой двухсегментной программы. В коде команды ssss — сегментный адрес сегмента code2, a dddd — смещение точки перехода go в сегменте команд code2.

Косвенный ближний (внутрисегментный) переход. В отличие от команд прямых переходов, команды косвенных переходов могут использовать различные способы адресации и, соответственно, иметь много разных вариантов. Общим для них является то, что адрес перехода не указывается явным образом в виде метки, а содержится либо в ячейке памяти, либо в одном из регистров. Это позволяет при необходимости модифицировать адрес перехода, а также осуществлять переход по известному абсолютному адресу. Рассмотрим случай, когда адрес перехода хранится в ячейке сегмента данных. Если переход ближний, то ячейка с адресом состоит из одного слова и содержит только смещение к точке перехода. code segment jmp DS:go_addr ; go: ;Точка перехода

code ends data segment

go addr dw go ;Адрес перехода (слово)

data ends

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

В приведенном фрагменте адрес точки перехода в слове go_addr задан однозначно указанием имени метки go. Такой вариант косвенного перехода выполняет фактически те же функции, что и прямой (переход по единственному заданному заранее адресу), только несколько более запутанным образом. Достоинства косвенного перехода будут более наглядны, если представить, что ячейка go_addr поначалу пуста, а по ходу выполнения программы в нее, в зависимости от каких-либо условий, помещается адрес той или иной точки перехода:

mov go_addr, offset go1 mov go_addr, offset go2 mov go_addr, offset go3

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

codel segment assume CS:codel, DS:data

jmp DS:go addr; Код FF 2E dddd

codel ends code2 segment assume CS:code2

go: ;Точка перехода в другом сегменте команд

code2 ends data segment

go addr dd go ;Двухсловный адрес точки перехода

data ends

Точка перехода go находится в другом сегменте команд этой двухсегментной программы. В коде команды dddd обозначает относительный ад­рес слова go_addr в сегменте данных. Ячейка go_addr объявляется директивой dd (define double, определить двойное слово) и содержит двухсловный адрес точки перехода; в первом слове содержится смещение go в сегменте команд codel, во втором слове сегментный адрес code2. Оба компонента адреса перехода могут быть вычислены и помещены в ячейку go_addr по ходу выполнения программы.

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

jmp DS:go_addr ;Возможна замена - сегмент

jmp dword ptr go_addr ;Если поле go_addr объявлено ;операторами dw

jmp go_addr Характеристики ячейки должны ;быть известны

Для дальнего косвенного перехода, как и для ближнего, допустима адресация через регистр общего назначения, если в него поместить адрес поля с адресом перехода:

mov BX,offset go_addr jmp [BX]

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

Циклы, позволяют выполнить некоторый участок программы многократно, В системе команд МП 86 циклы реализуются с помощью команды loop (петля), Число шагов в цикле определяется содержимым регистра СХ. При реализации команды loop процессор сначала уменьшает содержимое регистра СХ на 1, а затем сравнивает полученное число с нулем. Если СХ > 0, переход на указанную метку выполняется. Если СХ = 0, цикл разрывается и процессор переходит на команду, следующую за командой loop. Поэтому после нормального выхода из цикла содержимое СХ всегда равно 0. В коде команды под смещение к точке перехода отводится всего 1 байт. Поскольку смещение должно являться величиной со знаком, максимальное расстояние, на которое можно передать управление командой loop, составляет от -128 до +127 байт (хотя довольно трудно представить себе цикл, в котором переход осуществляется вперед), таким образом, тело цикла ограничивается 128 байтами.

Рассмотрим простой пример организации цикла. Пусть в программе зарезервировано место для массива размером 10000 слов, и этот массив надо заполнить натуральным рядом чисел от 0 до 9999. Эти числа, заполняющие последовательные элементы массива, иногда называют числами-заполнителями. Соответствующий фрагмент программы будет выглядеть следующим образом:

;В сегменте данных

array dw 10000 dup(0)

;В программном сегменте

mov BX,offset array ;Адрес массива

mov SI, 0 ;Индекс

mov AX, 0 Начальное значение

;заполнителя mov CX,10000 ;Счетчик цикла

fill: mov [BX][SI],AX /Заполнитель пошлем в массив inc AX /Инкремент заполнителя

add SI,2 /Модификация индекса

loop fill /Команда цикла

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

В составе команд условных переходов имеются две группы команд для сравнения чисел без знака (это команды ja, jae, jb, jbe, jna, jnae, jnb и jnbe) и чисел со знаком (jg, jge, jl, jle, jiig, jnge, jnl и jnle). В аббревиатурах этих команд для сравнения чисел без знака используются слова above (выше) и below (ниже), а для чисел со знаком — слова greater (больше) и less (меньше).

Разница между теми и другими командами условных переходов заключается в том, что команды для чисел со знаком рассматривают понятия «больше-меньше» применительно к числовой оси -32К...0...+32К, а команды для чисел без знака — применительно к числовой оси 0...64К. Поэтому для первых команд число 7FFFh (+32767) больше числа 8000h (-32768), а для вторых число 7FFFh (32767) меньше числа 8000h (32768). Аналогично, команды для чисел со знаком считают, что 0 больше, чем . FFFFh (-1), а команды для чисел без знака — меньше.

Основная литература: 5[203-235],7 [74-82,123-134],9[63-82]

Дополнительная литература:18[ 49-55]

Контрольные вопросы:

1 .Содержимое каких регистров изменяют команды передачи управления?

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

  2. В каких разновидностях осуществляются безусловные переходы с помощью команды jmp?

  3. В каких случаях используется косвенный переход?

  4. Содержимое какого регистра анализирует процессор при выполнении команд условной передачи управления.?

Тема лекции 7. Команды микропроцессора. Логические , строковые .

Логические команды. Система команд микропроцессора имеет средства логического преобразования данных. Под логическими понимаются такие преобразования данных, в основе которых лежат правила формальной логики. Формальная логика работает на уровне утверждений истинно и ложно. Для микропроцессора это, как правило, означает 1 и 0 соответственно. Минимальной единицей данных, с которой работают машинные команды, является байт. Однако на системном уровне часто необходимо иметь возможность работать на предельно низком уровне — на уровне бит. Эти возможности предоставляют логические команды и логические операции; разница между ними в том, что логические команды действуют на этапе выполнения программы, а логические операции - на этапе ее трансляции. На рисунке 4 показаны средства микропроцессора для организации работы с данными по правилам формальной логики.

Рисунок 4. Средства микропроцессора для организации работы с данными по правилам формальной логоки

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

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

Для установки определенных разрядов (бит) в 1 применяется команда ог

операнд _1, операнд _2.

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

операнд _1.

or еах,10Ь установить 1-й бит в регистре еах

Для сброса определенных разрядов (бит) в 0 применяется команда and

операнд_1, операнд_2.

В этой команде операнд_2, выполняющий роль маски, должен содержать нулевые биты на месте тех разрядов, которые должны быть установлены в 0 в

операнд _1.

and eax, fffffffdh ;сбросить в 0 1-й бит в регистре еах Команда хог операнд_ 1, операнд_2 применяется:

  • для выяснения того, какие биты в операнд. 1 и операнд_2 различаются;

  • инвертирования состояния заданных бит в операнд. 1.

Интересующие нас биты маски (операнд_2) при выполнении команды хог должны быть единичными, остальные — нулевыми.

хог еах,10 b - инвертировать 1-й бит в регистре еах jz mes ; переход если 1-й бит в al был единичным (так как маска хог изменяет на противоположный каждый бит начального значения, то повторное применение той же маски к результату восстанавливает первоначальное значение битов).Команда часто применяется для шифрования и в коммуникациях

Для проверки состояния заданных бит применяется команда test операнд_1, операнд_2 (проверить операнд_ 1). Проверяемые биты операнд_ 1 в маске (операнд__2) должны иметь единичное значение. Алгоритм работы команды test подобен алго­ритму команды and, но он не меняет значения операнд. 7. Результатом команды является установка значения флага нуля zf:

  • если zf - 0, то в результате логического умножения получился нулевой ре­зультат, то есть один единичный бит маски, не совпал с соответствующим единичным битом операнд 1;

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

Команды сдвига

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

Количество сдвигаемых разрядов, счетчик сдвигов, располагается, как видите, на месте второго операнда и может задаваться двумя способами:

  • статически; предполагает задание фиксированного значения с помощью непосредственного операнда;

  • динамически; занесением значения счетчикасдвигов в регистр cl перед выполнением команды сдвига.

Исходя из размерности регистра cl, значение счетчика сдвигов может лежать в диапазоне от 0 до 255. В целях оптимизации микропроцессор воспринимает только значение пяти младших битов счетчика, то есть значение лежит в диапазоне от 0 до 31. В последних моделях микропроцессора, в том числе и в микропроцессоре Pentium, есть дополнительные команды, позволяющие делать 64­разрядные сдвиги.

Все команды сдвига устанавливают флаг переноса cf. По мере сдвига битов за пределы операнда они сначала попадают во флаг переноса, устанавливая его равным значению очередного бита, оказавшегося за пределами операнда. Куда этот бит попадет дальше, зависит от типа команды сдвига и алгоритма про­граммы.

По принципу действия команды сдвига можно разделить на два типа:

  • команды линейного сдвига;

  • команды циклического сдвига.

Команды линейного сдвига.

К командам этого типа относятся команды, осуществляющие сдвиг по следующему алгоритму:

  • очередной «выдвигаемый» бит устанавливает флаг cf;

  • бит, вводимый в операнд с другого конца, имеет значение 0;

  • при сдвиге очередного бита он переходит во флаг cf, при этом значение предыдущего сдвинутого бита теряется.

Команды линейного сдвига делятся на два подтипа:

  • команды логического линейного сдвига;

  • команды арифметического линейного сдвига.

К командам логического линейного сдвига относятся следующие: shl операнд, счетчиксдвигов (Shift Logical Left) — логический сдвиг влево. Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик сдвигов. Справа (в позицию младшего бита) вписываются нули;

shr операнд, счетчик сдвигов (Shift Logical Right) — логический сдвиг вправо. Содержимое операнда сдвигается вправо на количество битов, определяемое значением счетчик сдвигов. Слева (в позицию старшего, знакового бита) вписываются нули.

Ниже показан фрагмент программы, который выполняет преобразование двух неупакованных BCD-чисел в слове памяти bcd_dig в упакованное BCD-число в регистре al.

bcd_dig dw 0905h ;описание неупакованного BCD-числа 95 mov ax,bcd_dig ; пересылка shl ah,4 ;сдвиг влево

add al.ah ;сложение для получения результата: al=95h Команды циклического сдвига

К командам циклического сдвига относятся команды, сохраняющие значения сдвигаемых бит. Есть два типа команд циклического сдвига:

  • команды простого циклического сдвига;

  • команды циклического сдвига через флаг переноса cf К командам простого циклического сдвига относятся:

rol операнд, счетчиксдвигов (Rotate Left) — циклический сдвиг влево. Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа;

гог операнд, счетчик сдвигов — (Rotate Right) циклический сдвиг вправо. Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик сдвигов. Сдвигаемые вправо биты записываются в тот же операнд слева.

Команды простого циклического сдвига в процессе своей работы осуществляют одно полезное действие, а именно: циклически сдвигаемый бит не только вдвигается в операнд с другого конца, но и одновременно его значение становится значением флага cf. Например, для того чтобы обменять содержимое двух половинок регистра еах, достаточно выполнить следующую последовательность команд: mov eax.ffTOOOOh mov cl,16 rol eax.cl

Команды циклического сдвига через флаг переноса cf отличаются от команд простого циклического сдвига тем, что сдвигаемый бит не сразу попадает в операнд с другого его конца, а записывается сначала во флаг переноса cf. Лишь следующее исполнение данной команды сдвига (при условии, что она выполняется в цикле) приводит к помещению выдвинутого ранее бита в другой конец операнда К командам циклического сдвига через флаг переноса cf относятся следующие:

rcl операнд, счетчик-сдвигов (Rotate through Carry Left) — циклический сдвиг влево через перенос. Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf;

rcr операнд, счетчик сдвигов (Rotate through Carry Right) — циклический сдвиг вправо через перенос. Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.

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

рассмотрим, как переписать в регистр Ьх старшую половину регистра еах с одновременным ее обнулением в регистре еах:

mov

cx,16

;кол-во сдвигов для еах

clc

;сброс флага cf в О

rcl

еах,1

;сдвиг крайнего левого бита из еах в cf

rcl

bx

;перемещений бита из cf справа в Ьх

loop

ml

;цикл 16 раз

rol

еах, 16

восстановить правую часть еах

Команды простого циклического сдвига можно использовать для операций другого рода. Например, подсчитаем количество единичных бит в регистре еах: xor dx,dx ;очистка dx для подсчета единичных бит mov cx,32 ;число циклов подсчета cycl: ;метка цикла

rr еах, 1 ; циклический сдвиг вправо на 1 бит

jnc not_one ; переход, если очередной бит в cf ;не равен единице

inc dx ; увеличение счетчика цикла

not_one:

loop cycl ; переход на метку cycl, если

; значение в сх не равно 0 Строковые команды.

Для работы со строками, или цепочками символов или чисел в МП предусмотрен ряд специальных команд: movs — пересылка строки; cmps — сравнение двух строк; seas — поиск в строке заданного элемента;

lods — загрузка аккумулятора (регистров AL или АХ) из строки; stos — запись элемента строки из аккумулятора (регистров АХ или AL).

Хотя команды обработки строк, как правило, включаются в программу без явного указания операндов, однако каждая команда, в действительности, использует два операнда. Для команд seas и stos операндом-источником служит аккумулятор, а операнд-приемник находится в памяти. Для команды lods, наоборот, операнд-источник находится в памяти, а приемником служит аккумулятор. Наконец, для команд movs и cmps оба операнда, и источник, и приемник, находятся в памяти.

Все рассматриваемые команды, выполняя различные действия, под­чиняются одинаковым правилам: операнды, находящиеся в памяти, всегда адресуются единообразно: операнд-источник через регистры DS:SI, а операнд- приемник через регистры ES:DI. При однократном выполнении команды обрабатывают только один элемент, а для обработки строки команды должны предваряться одним из префиксов повторения. В процессе обработки строки регистры SI и DI автоматически смещаются по строке вперед (если флаг DF = 0) или назад (если флаг DF = 1), обеспечивая адресацию последующих элементов. Каждая команда имеет модификации для работы с байтами или словами (например, movsb и movsw).

Таким образом, для правильного выполнения команд обработки строк необходимо (в общем случае) предварительно настроить регистры DS:SI и ES:DI, установить или сбросить флаг DF, занести в СХ длину обрабатываемой строки, а для команд seas и stos еще поместить операнд-источник в регистр АХ (или AL при работе с байтами).

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

Стоит подчеркнуть, что строки, обрабатываемые рассматриваемыми командами, могут находиться в любом месте памяти: в полях данных про­граммы, в системных областях данных, в ПЗУ, в видеобуфере. Например, с помощью команды movs можно скопировать массив данных из одной

массивной переменной в другую, а можно переслать страницу текста на экран

терминала.

;Пример. Чтение из ПЗУ BIOS даты его выпуска ; В программном сегменте main proc

mov AX,0F000h ;3анесем в DS

mov DS,AX ;сегментный адрес ПЗУ BIOS

mov SI,0FFF5h;Смещение к интересующему нас полю

mov AX,data ;Настроим ES

mov ES,AX ;на сегмент данных программы

mov DI,offset Ь^;Смещение к полю для хранения даты

mov CX,8 ;Перенести 8 байт

cld ;Движение по строке вперед

rep movsb ;Перенос байтов

;Выведем полученнуюинформацию на экран

mov AX, data ;Теперь настроим DS

mov DS,AX ;на сегмент данных программы

mov АН,40h ;Функция вывода

mov BX, 1 ;Дескриптор экрана

mov СХ, 8 ; Вывести 8 байт

mov DX,offset bios;Смещение к строке

int 2Ih ;Вызов DOS

; В сегменте данных

bios db 8 dup(");Поле для хранения даты

Основная литература: 4[69-76],5[186-205],7[130-134],9[104-116]. Дополнительная литература: 13[[50-60].

Контрольные вопросы:

  1. Какие команды и операторы относятся к средствам логической обработки данных.

  2. Опишите действия команды хог и области ее применения.

  3. Опишите структуру команд сдвига.

  4. Каким образом может задаваться счетчик сдвигов в командах сдвига?

  5. На какие два типа можно разделить команды сдвига по принципу действия?

  6. По какому алгоритму осуществляется сдвиг в командах линейного сдвига?

  7. По какому алгоритму осуществляется сдвиг в командах циклического сдвига?

  8. Каким правилам подчиняются все строковые команды?

Тема лекции 8.Использование подпрограмм

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

Процедура представляет собой группу команд для решения конкретной подзадачи и обладает средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку.

В простейшем случае программа может состоять из одной процедуры. Другими словами, процедуру можно определить как правильным образом оформленную совокупность команд, которая, будучи однократно описана, при необходимости может быть вызвана в любом месте программы. Процедура, часто называемая также подпрограммой. Вызов процедуры осуществляется с помощью команды CALL <имя процедуры>. При вызове процедуры адрес точки возврата запоминается в стеке (как будет описано при описании команд). Возврат из процедуры происходит с помощью команды RET (или RETF), по которой из стека достается и загружается в IP сохраненный в стеке адрес точки возврата.

Для описания последовательности команд в виде процедуры в языке ассемблера используются две директивы: PROC и ENDP.

В заголовке процедуры (директиве PROC) обязательным является только задание имени процедуры. Среди большого количества операндов директивы PROC следует особо выделить [расстояние].

Этот атрибут может принимать значения near или far и характеризует возможность обращения к процедуре из другого сегмента кода. По умолчанию атрибут [расстояние] принимает значение near.

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

Схема команды: call цель

Назначение:

передача управления близкой или дальней процедуре с запоминанием в стеке адреса точки возврата;

переключение задач. Алгоритм работы определяется типом операнда: метка ближняя — в стек заносится содержимое указателя команд eip/ip и в этот же регистр загружается новое значение адреса, соответствующее метке;

метка дальняя — в стек заносится содержимое указателя команд eip/ip и cs. Затем в эти же регистры загружаются новые значения адресов, соответствующие дальней метке;

г16, 32 или ml6, 32 — определяют регистр или ячейку памяти, содержащие смещения в текущем сегменте команд, куда передается управление. При передаче управления в стек заносится содержимое указателя команд eip/ip;

указатель на память — определяет ячейку памяти, содержащую 4 или 6- байтный указатель на вызываемую процедуру. Структура такого указателя 2+2 или 2+4 байта Интерпретация такого указателя зависит от режима работы микропроцессора:

в реальном режиме — в зависимости от размера адреса (use 16 или use32) первые два байта трактуются как сегментный адрес, вторые два/четыре байта, как смещение целевой метки передачи управления. В стеке запоминается содержимое регистров cs и eip/ip;

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

Целью здесь являются дальний вызов процедуры без изменения уровня привилегий, дальний вызов процедуры с изменением уровня привилегий или переключение задачи. Состояние флагов после выполнения команды (кроме переключения задачи): выполнение команды не влияет на флаги

При переключении задачи значения флажков изменяются в соответствии с информацией о регистре eflags в сегменте состояния TSS задачи, на которую производится переключение. Применение:

Как видно из описания алгоритма, команда call позволяет организовать гибкую и многовариантную передачу управления на подпрограмму с сохранением адреса точки возврата. См. также команду ret RET/RETF

(RETurn/RETum Far from procedure) Возврат ближний (дальний) из процедуры

Схема команды, ret ret число

Назначение: возврат управления из процедуры вызывающей программе. Алгоритм работы: Работа команды зависит от типа процедуры:

для процедур ближнего типа — восстановить из стека содержимое eip/ip; для процедур дальнего типа — последовательно восстановить из стека содержимое eip/ip и сегментного регистра cs

если команда ret имеет операнд, то увеличить содержимое esp/sp на величину операнда число; при этом учитывается атрибут режима адресации — use 16 или use32:

если use 16, то в sp = (sp +число), то есть указатель стека сдвигается на число байт, равное значению числа;

если use32, то sp=(sp+2*число), то есть указатель стека сдвигается на число слов, равное значению числа.

Состояние флагов после выполнения команды: выполнение команды не влияет на флаги

Применение:

Команду ret необходимо применять для возврата управления вызывающей программе из процедуры, управление которой было передано по команде call. На самом деле микропроцессор имеет три варианта команды возврата ret - это ret, ее синоним retn, а также команда retf. Они отличаются типами процедур, в которых используются. Команды ret и retn служат для возврата из процедур ближнего типа. Команда retf — команда возврата для процедур дальнего типа. Какая конкретно команда будет использоваться, определяется компилятором; программисту лучше использовать команду ret и доверить транслятору самому сгенерировать ее ближний или дальний вариант. Количество команд ret в процедуре должно соответствовать количеству точек выхода из нее.

В процедуру (и из процедуры) параметры могут передаваться.

  • через общие переменные. Данный способ не требует особых комментариев - перед вызовом процедуры в переменную заносится необходимое значение данных, а затем в процедуре происходит обращение к данной переменной;

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

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

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

Основная литература: 2[236-246],9[152-168],7[135-139]

Дополнительная литература:14[75-79]

Контрольные вопросы:

  1. Что такое процедура (подпрограмма) в ассемблере? Как оформляется процедура?

  2. Как осуществляется запоминание адреса точки возврата в основную программу?

  3. Как происходит возврат из процедуры в основную программу?

  4. Назовите команду вызова процедуры?

  5. Назовите команду возврата из процедуры?

  6. Каким образом можно передать параметры в процедуру?

  7. Каким образом можно передать параметры из процедуры в основную программу?

  8. Как осуществить передачу параметров через стек.

Лекция 9.Прерывания.

Обработка прерываний Прерывание - инициируемый определенным образом процесс, временно переключающий микропроцессор на выполнение другой программы с последующим возобновлением прерванной программы.

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

Главные функции механизма прерываний:

  1. Распознавание или классификация прерываний;

  2. Передача управления соответствующему обработчику прерываний:

  3. Корректное возвращение к прерванной программе.

Классификация прерываний представлена на рисунке 5

Рисунок 5. Классификация прерываний

Внутренние прерывания возникают в МП во время вычислительного процесса по двум причинам:

  1. Исключительная ситуация (исключение) - ненормальное внутреннее состояние микропроцессора, возникшее при обработке некоторой команды программы (непланируемое).

(примером исключительных ситуаций могут служить :

-нарушение адресации

-наличие в поле кода операции незадействованной двоичной комбинации; -при делении на нуль.

- при переполнении или исчезновении порядка.

-при обнаружении ошибок четности, ошибок в работе различных устройств аппаратуры средствами контроля.)

2.Обработка машинной команды Int xx. (Этот тип прерываний называется программным.) Это планируемое прерывание ,так как с их помощью программист обращается в нужное для него время за обслуживанием своих запросов либо к операционной системе , либо к BIOS ,либо к собственным программам обработки прерываний . )

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

Рисунок 6 Подсистема обработки прерываний компьютера на базе микропроцессора

Intel

Внешние прерывания делятся на немаскируемые и маскируемые.

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

Маскируемые прерывания поступают на вход INT процессора от УВВ, требующих обслуживания. Эти прерывания можно запрещать или разрешать тремя различными способами:

-сбрасывая или устанавливая соответствующие биты INTE (Interrupt Enable)

регистров состояний интерфейсных блоков;

-устанавливая или сбрасывая соответствующие биты регистра маски контроллера прерываний

- выполняя команды CLI (Clear Interrupt) или STI (Set Interrupt), соответственно сбрасывающие или устанавливающие флаг IF.Прерывания от стандартных УВВ желательно запрещать на очень короткие промежутки времени, необходимые для выполнения критических участков программы.

Система прерываний - совокупность программных и аппаратных средств, реализующих механизм прерываний. Аппаратные средства системы прерываний:

А) выводы микропроцессора :

INTR- вывод для входного сигнала внешнего прерывания.

INTA- вывод микропроцессора для выходного сигнала, подтверждения в получении сигнала прерывания микропроцессором.

NMI- вывод микропроцессора для входного сигнала немаскируемого прерывания.

Б) микросхема программируемого контроллера прерываний 8259А

52

В) внешние устройства ( клавиатура, таймер, магнитные диски и т.д.)

  1. Программные средства системы прерываний:

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

Б) следующие флаги в регистре flags\ eflags

IF- флаг прерывания- Запрещение прерывания ко входу INTR. IF= 1 ® МП обрабатывает внешние прерывания. IF =0 ® МП игнорирует сигналы на входе INTR.

TF- флаг трассировки TF= 1 ® режим покомандной работы.

  1. Машинные команды МП.

Основные:

cli- запрет прерываний sti- разрешить прерывания iret- возврат

Контроллер прерываний выполняет следующие функции:

  1. фиксирование запросов на обработку прерываний от 8 источников;

  2. формирование единого запроса на прерывание и подача его на вход INTR

МП;

  1. формирование номера вектора прерывания и выдача его на шину данных;

  2. организация приоритетной обработки прерываний;

  3. запрещение ( маскирование прерываний с определенными номерами). 09.02.2004

На рисунке 7 представлена Структурная схема и схематическое представление данных i 8259А.

d7 d0

Блок управления чтением/записью

Буфер данных

Схема

каскадирования

Регистр состояний (ISR)

Программный

Арбитр приоритетов

контроллер

прерываний

(ПКП)

|

| |

rq7

ir

q5

irq3

ir

I1 INTA INT