Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Учебники 80389

.pdf
Скачиваний:
7
Добавлен:
01.05.2022
Размер:
43.33 Mб
Скачать

оперирует с двоичной системой счисления (двоичной системой представления данных). Символьная информация кодируется в соответствии с кодом ASCII (Американский стандартный код для обмена информацией). Числовые данные кодируются в соответствии с двоичной арифметикой. Отрицательные числа представляются в дополнительном коде.

Группа из восьми битов называется байтом (Byte) и представляет собой наименьшую адресуемую единицу – ячейку памяти. Биты в байте нумеруют справа налево цифрами 0...7.

BYTE

7

6

5

4

3

2

1

0

Двухбайтовое поле образует шестнадцатиразрядное машинное слово (Word), биты в котором нумеруются от 0 до 15 справа налево. Байт с меньшим адресом считается младшим.

WORD

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

Четырехбайтовое поле образует двойное слово (Double Word), а шестнадцатибайтовое – параграф (Paragraph).

Таким образом, с помощью 16-разрядной шины данных можно передавать числа от 0 (во всех проводниках сигнал 0) до 65535 (во всех проводниках сигнал 1). Несмотря на то, что двоичная система обладает высокой наглядностью, она имеет существенный недостаток – числа, записанные в двоичной системе, слишком громоздки. С другой стороны, привычная для нас десятичная система слишком сложна для перевода чисел в двоичную систему счисления и обратно. Поэтому наибольшее распространение в практике программирования получила шестнадцатеричная система счисления.

При написании программ принято двоичные числа сопровождать латинской буквой B или b, (например, 101B), а шестнадцатеричные – буквой H или h на конце. Если число начинается с буквы, то обязательной является постановка нуля впереди, например, 0BA8H.

Регистры

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

Регистры общего назначения. К ним относятся 16-разрядные регистры АХ, ВХ, СХ, DX, каждый из которых разделен на 2 части по 8 разрядов:

АХ состоит из АН (старшая часть) и AL (младшая часть); ВХ состоит из ВH и BL;

СХ состоит из СН и CL;

DX состоит из DH и DL;

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

регистр АХ служит для временного хранения данных (регистр аккумулятор); часто используется при выполнении операций сложения, вы-

61

читания, сравнения и других арифметических и логических операции;

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

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

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

Регистры для адресации. В микропроцессоре существуют четыре 16-битовых (2 байта или 1 слово) регистра, которые могут принимать участие в адресации операндов. Один из них одновременно является и регистром общего назначения — это регистр ВХ, или базовый регистр. Три другие регистра — это указатель базы ВР, индекс источника SI и индекс результата DI. Отдельные байты этих трех регистров недоступны.

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

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

CS - регистр программного сегмента (сегмента кода) определяет местоположение части памяти, содержащей программу, т. е. выполняемые процессором команды;

DS - регистр информационного сегмента (сегмента данных) идентифицирует часть памяти, предназначенной для хранения данных;

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

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

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

Регистр указателя стека. Указатель стека SP – это 16-битовый регистр, который определяет смещение текущей вершины стека. Указатель стека SP вместе с сегментным регистром стека SS используются микропроцессором для формирования физического адреса стека. Стек всегда растет в направлении меньших адресов памяти, т.е. когда слово помещается в стек, содержимое SP уменьшается на 2, когда слово извлекается из

62

стека, микропроцессор увеличивает содержимое регистра SP на 2. Регистр указателя команд IP. Регистр указателя команд IP, иначе

называемый регистром счетчика команд, имеет размер 16 бит и хранит адрес некоторой ячейки памяти – начало следующей команды. Микропроцессор использует регистр IP совместно с регистром CS для формирования 20битового физического адреса очередной выполняемой команды, при этом регистр CS задает сегмент выполняемой программы, а IР – смещение от начала сегмента. По мере того, как микропроцессор загружает команду из памяти и выполняет ее, регистр IP увеличивается на число байт в команде. Для непосредственного изменения содержимого регистра IP служат команды перехода.

Регистр флагов. Флаги – это отдельные биты, принимающие значение 0 или 1. Регистр флагов (признаков) содержит девять активных битов (из 16). Каждый бит данного регистра имеет особое значение, некоторые из этих бит содержат код условия, установленный последней выполненной командой. Другие биты показывают текущее состояние микропроцессора.

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

X

X

X

X

OF

DF

IF

TF

SF

ZF

X

AF

X

PF

X

CF

Биты регистра флагов имеют следующее назначение:

OF (признак переполнения) – равен 1, если возникает арифметическое переполнение, то есть когда объем результата превышает размер ячейки назначения;

DF (признак направления) – устанавливается в 1 для автоматического декремента в командах обработки строк, и в 0 – для инкремента;

IF (признак разрешения прерывания) – прерывания разрешены, если IF=1. Если IF=0, то распознаются лишь немаскированные прерывания;

TF (признаков трассировки) - если TF=1, то процессор переходит в состояние прерывания INT 3 после выполнения каждой команды;

SF (признак знака) – SF=1, когда старший бит результата равен 1. Иными словами, SF=0 для положительных чисел, и SF=1 для отрицательных чисел;

ZF (признак нулевого результата) – ZF=1, если результат равен нулю; AF (признак дополнительного переноса) – этот флаг устанавливается в 1 во время выполнения команд десятичного сложения и вычитания при

возникновении переноса или займа между полубайтами;

PF (признак четности) – этот признак устанавливается в 1, если результат имеет четное число единиц;

CF (признак переноса) – этот флаг устанавливается в 1, если имеет место перенос или заем из старшего бита результата; он полезен, для произведения операций над числами длиной в несколько слов, которые сопряжены с переносами и займами из слова в слово;

X – зарезервированные биты.

Все флаги младшего байта регистра флагов устанавливаются арифметическими или логическими операциями процессора. За исключением

63

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

Сегменты, принцип сегментации

Числа, устанавливаемые процессором на адресной шине, являются адресами, то есть номерами ячеек оперативной памяти (ОП). Размер ячейки ОП составляет 8 разрядов, т.е. 1 байт. Поскольку для адресации памяти процессор использует 16-разрядные адресные регистры, то это обеспечивает ему доступ к 65536 (FFFFh) байт или 64К (1К = 1024 байт = 210 байт) основной памяти. Такой блок непосредственно адресуемой памяти называется сегментом. Сегмент задаёт порядковый номер сегмента.

Память

Сегмент

1

Сегмент

2

Сегмент

3

Сегмент

4

и так далее

(64kb)

 

(64kb)

 

(64kb)

 

(64kb)

 

 

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

Сегмент 1(64kb)

Смещение 1 Смещение 2 Смещение 3 Смещение 4 Смещение 5 и так далее

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

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

Чтобы получить 20-битовый адрес, дополнительные 4 бита адресной информации извлекаются из сегментных регистров. Сами сегментные регистры имеют размер в 16 разрядов, а содержащиеся в этих регистрах (CS, DS, SS или ES) 16-битовые значения называются базовым адресом сегмента. С помощью16 битможноадресоватьтолько65536 байтпамятии65536 сегментов.

Например: 0030:4012 (всё шестнадцатеричное)

Это означает: сегмент 30, смещение 4012. Чтобы узнать, что находится в том адресе, сначала переходим на сегмент 30, а затем в сегменте смещаемся на 4012.

64

Существуют следующие сегментов: CS - Сегмент кода

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

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

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

FS - Универсальный сегмент

GS - Универсальный сегмент

Названия говорят о их функциях: сегмент кода (CS) содержит номер секции, где выполнен текущий код. Сегмент данных для получения данных из текущего сегмента. На стек указывает сегмент стека (SS), ES, FS, GS - универсальные регистры и могут использоваться для любого сегмента (не в 32 разрядных системах).

В 16-разрядном программировании, сегменты необходимы. Эта проблема решена в 32-разрядном Windows (95 и выше). Сегменты так же существуют, но имеют размер не 64 Кбайта, а 4 Гбайта (рис.5.13). Windows вероятно даже "повиснет", если вы попытаться изменить один из сегментных регистров. Это называется плоской моделью памяти ( flat ). Здесь есть только смещения и они теперь 32-разрядные (в диапазоне от 0 до 4,294,967,295). Каждая ячейка в памяти указывается смещением. Это одно из лучших преимуществ 32-разрядного программирования над 16-разрядным.

00000000-0000FFFF

не используется

00010000-7FFFFFFF

User space пользовательское пространство

80000000-FFFFFFFF

Kernel space память ядра системы

Рис. 4.13. Общая схема памяти в 32 разрядной системе

(Windows 95 и выше)

Но 4ГБ может и не быть на машине, поэтому эта память называется виртуальной. Мало того, каждый процесс выполняется в своём виртуальном адресном пространстве. А это значит, что никакой другой процесс не сможет получить доступ к вашей памяти. Для этого существуют специальные API функции, но для их использования нужно иметь специальные привилегии в системе. Память 0-0000FFFF не используется и служит для выявления нулевых указателей, значит, если вы укажете адрес 0000С567, то он будет считаться нулевым (рис.4.13). Любая попытка обратиться к этой памяти приводит к ошибке. Память выше 80000000 одна для всех процессов. В этой памяти находится код нулевого кольца, структуры ядра, код планировщика задач, код драйверов, диспетчер ввода вывода, таблица прерываний и т.д. Любая попытка обратиться к памяти ядра приводит к ошибке и к немедленному завершению приложения. Память в диапазоне 00010000-7FFFFFFF доступна для 3 кольца, т.е. для приложения, в неё также грузятся динамические библиотеки DLL.

65

Если в системе 2ГБайта памяти, то это не означает, что программист может обратиться к любому участку памяти. Для того чтобы получить доступ к некоторому участку памяти надо сначала её зарезервировать. Перед резервированием памяти, резервируемого участка памяти просто не существует, программист его как бы создаёт и задаёт ему атрибуты доступа (полный доступ, только чтение, только запись, нет доступа). Минимальный размер выделяемой памяти - страница, равна 1000h байтам = 4096 байт. Даже если необходимо выделить 5 байт, то всё равно выделится 4КБайта. Эта операция выполняется при работе с файлами для того, что бы в эту память читать файл.

Стек

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

адреса

 

 

 

 

 

 

Стек

1

 

 

 

 

 

 

 

2

 

адреса

 

 

 

 

188

3

 

 

 

 

 

44

 

41

 

 

 

 

 

4

 

 

адреса

 

 

6

 

42

 

адреса

5

вызов

 

181

 

0

43

вызов

 

1031

 

6

 

182

 

 

0

 

44

 

 

1032

 

7

 

 

183

 

 

 

 

45

 

 

1033

 

 

8

 

 

184

 

 

 

 

46

 

 

1034

 

 

9

 

 

185

 

 

 

 

47

 

 

1035

 

 

10

 

 

186

 

 

 

 

48

 

 

1036

 

 

11

 

 

187 вызов

 

 

 

49

 

1037

 

 

12

 

 

188

 

 

 

 

50

 

 

1038

 

 

13

 

 

189

 

 

 

 

51

возврат

 

1039

 

 

14

 

190

 

 

 

 

 

 

 

1040

 

 

15

 

 

 

191

 

 

 

 

 

 

 

1041

 

 

16

 

 

 

192

 

 

 

 

 

 

 

1042

 

 

 

 

 

 

193

возврат

 

 

 

 

 

 

1043

возврат

 

 

 

 

 

 

 

 

Рис.4.14. Схема заполнения стека

командам можно записывать отдельные слова (но не байты); при этом для запоминания данных достаточно выполнить лишь одну команду и не нужно беспокоиться о выборе соответствующего адреса: процессор автоматически выделяет для них свободное место в области временного хранения. Наиболее важное использование стека связано с подпрограммами, в этом случае стек содержит адрес возврата из подпрограммы (рис.4.14), а иногда и передаваемые в/из подпрограмму данные. Когда одна подпрограмма вызывает другую, вызываемая подпрограмма завершила свое выполнение, теперь ей надо передать управление подпрограмме, которая её вызвала, как раз адрес следующей команды после вызова подпрограммы находится на верхушке стека.

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

66

гается в старших адресах. Начальный адрес стека, называемый дном (bottom) записывается в регистр SP командой MOV SP,0fffeh. Вместо 0fffeh - адрес предпоследнего байта сегмента, может быть другое значение, но выровненное по двухбайтовым, т. е. четным адресам. Текущее значение содержимого SP называется, также адресом вершины стека (top). Если адрес вершины совпадает с адресом дна - стек считается пустым. Рассмотрим механизм помещения в стек и извлечения из него данных на примере команд PUSH AX и POP BX (рис.4.15 и рис.4.16). Пусть начальное значение аккумулятора AX равно 874c.

push ax

FFFE-2

FFFE-1

вер (SP)=FFFE

шина

XX

XX

XX дно стек пустой

вершина(SP)=FFFE-2 FFFE-1

FFFE

 

87

 

XX

дно

стек не пустой

Рис. 4.15 Пустой стек до выполнения команды PUSH AX

 

pop bx

 

 

AX

 

 

BX

FFFE-2

 

было

874С

XXXX

 

 

 

 

 

 

FFFE-1

87

 

 

AX

 

 

BX

вер (SP)=FFFE

XX

дно

стало

874С

874С

 

 

 

 

 

шина

 

 

 

AH

AL

BH

BL

стек опять пустой

 

 

 

 

 

 

Рис. 4.16 Стек после выполнения команды POP BX

Команда PUSH выполняется в четыре этапа:

Адрес в SP уменьшается на 1: (SP) <-- (SP) - 1.

По этому адресу помещается старший байт 87: ((SP)) <-- (AH).

Содержимое SP снова уменьшается на 1: (SP) <-- (SP) - 1.

По полученному адресу загружается младший байт 4c: ((SP)) <-- (AL). Действие команды POP аналогично описанному процессу, но в про-

исходит в обратном порядке:

(BL) <- ((SP)),

(SP) <- (SP) + 1,

(BH) <- ((SP)),

(SP) <- (SP) + 1.

Байты в стек помещаются по правилу "старший байт по старшему адресу". На рис.4.15 показан пустой стек до выполнения команды PUSH AX и после ее выполнения, а на рис.4.16 после выполнения команды POP BX.

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

67

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

1)сохранения и извлечения адреса возврата из подпрограмм командами ассемблера CALL и RET (IRET),

2)хранения локальных переменных,

3)передачи фактических параметров подпрограммам (трансляторами

сязыков высокого уровня),

4)временного хранения содержимого регистров фоновой программы при ее прерывании.

Прерывания

Часто возникают ситуации, когда необходимо выполнить одну из набора специальных процедур, если в системе или в программе возникают определенные условия, например, нажата клавиша на клавиатуре или произошло деление на ноль. Действие, стимулирующее выполнение одной из таких процедур, называется прерыванием, поскольку основной процесс при этом приостанавливается на время выполнения этой процедуры. Существует два общих класса прерываний: внутренние и внешние. Первые инициируются состоянием ЦП или командой, а вторые – сигналом, подаваемым от других компонентов системы. Типичные внутренние прерывания: деление на нуль, переполнение и т.п., а типичные внешние – это запрос на обслуживание со стороны какого-либо устройства ввода/вывода.

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

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

последовательность прерывания:

текущее значение регистра флагов включается в стек; текущее значение кодового сегмента включается в стек; текущее значение счетчика команд включается в стек; сбрасываются флаги IF и TF.

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

которая извлекает из стека содержимое для: указателя стека; сегмента кода; регистра флагов.

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

68

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

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

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

регистровая;

прямая;

непосредственная;

косвенная;

базовая;

индексная;

базово-индексная.

Регистровая адресация подразумевает использование в качестве операнда регистра процессора, например:

PUSH DS

MOV BP,SP

При прямой адресации один операнд представляет собой адрес памяти, второй – регистр:

MOV Data,AX

Непосредственная адресация применяется, когда операнд, длинной в байт или слово находится в ассемблерной команде:

MOV AH,4CH

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

MOV

AL,[BX]

;База –

в DS, смещение – в BX

MOV

AX,[BP]

;База

в

SS,

смещение

в

BP

MOV

AX,ES:[SI]

;База

в

ES,

смещение

в

SI

В случае применения базовой адресации исполнительный адрес являетсясуммойзначениясмещенияисодержимогорегистраBP илиBX, например:

MOV

AX,[BP+6]

;База

SS,

смещение

BP+6

MOV

DX,8[BX]

;База

DS,

смещение

BX+8

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

MOV DX,[SI+5]

;База – DS, смещение – SI+5

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

MOV

BX,[BP][SI]

;База – SS, смещение – BP+SI

MOV

ES:[BX+DI],AX

;База

ES,

смещение

BX+DI

MOV

AX,[BP+6+DI]

;База

SS,

смещение

-

BP+6+DI

69

Способы ввода - вывода

Обмен данными между ЭВМ и ВУ или ЗУ называется вводом-выводом (ВВ). Существует четыре основных способа ВВ.

Программный ВВ

ВВ по прерываниям

Прямой доступ к памяти (ПДП) или DMA

Транзакции (MCS-96)

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

Программный ввод – вывод.

Для внешних устройств выделяется адресное пространство, либо не входящее в состав ЗУ, либо являющееся его частью. Следовательно программный ВВ может быть двух типов:

с помощью команд ассемблера ввод (IN) и вывод (OUT)

с использованием всех команд пересылки ассемблера (MOV, LODSB,..).

В пределах 64K блока карта распределения памяти для первого случая показана на рис.4.17 слева.

В пределах интервала 0000 ...XXXX адреса ВУ и ЗУ пересекаются. Поэтому для однозначного обращения к ячейкам памяти или ВУ в процессорном блоке формируются управляющие пересылкой стробирующие импульсы - ~IOR,~IOW для ввода или вывода данных во внешнее устройство

и~MEMR,~MEMW для чтения или записи в память. Емкость ЗУ для размещения программ и данных не уменьшается.

ЗУ

ВУ

ЗУ+ВУ

0 0 0 0

 

0 0 0 0

0 0 0 0

X X X X

 

X X X X

X X X X

 

____

____

адреса ЗУ

 

 

 

IOR

IOW

Y Y Y Y

 

 

 

 

 

 

адреса ВУ

F F F F

64K

 

F F F F

______

______

______

______

MEMR

MEMW

MEMR

MEMW

Рис.4.17 Карта распределения памяти при программном вводе – выводе

Карта распределения памяти для второго случая показана на рис.4.17 справа. Под внешние устройства выделяется часть адресного пространства ЗУ. Емкость ЗУ уменьшается на количество адресов отводимых для ВУ. Второй способ позволяет адресоваться к ВУ с помощью всех команд оперирующих с памятью. Основное достоинство программного ВВ в простоте. Но при выполнении ввода, например с клавиатуры, МП затрачивает до 99,99..% времени на ожидание, не выполняя при этом другой полезной работы. Избавиться от этого недостатка позволяет ВВ по прерываниям.

70

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]