Пользовательские регистры
Как следует из названия, пользовательскими регистры называются потому, что программист может использовать их при написании своих программ. К этим регистрам относятся (рис. 1):
восемь 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.
Рис. 1. Пользовательские регистры микропроцессоров i486 и Pentium
Почему многие из этих регистров приведены с наклонной разделительной чертой?
Нет, это не разные регистры — это части одного большого 32-разрядного регистра. Их можно использовать в программе как отдельные объекты.
Так сделано для обеспечения работоспособности программ, написанных для младших 16-разрядных моделей микропроцессоров фирмы Intel, начиная с i8086.
Микропроцессоры i486 и Pentium имеют в основном 32-разрядные регистры. Их количество, за исключением сегментных регистров, такое же, как и у i8086, но размерность больше, что и отражено в их обозначениях — они имеют приставку e (Extended).
Регистры общего назначения
Все регистры этой группы позволяют обращаться к своим “младшим” частям.
Для самостоятельной адресации можно использовать только младшие 16 и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты недоступны. Это сделано, как мы отметили выше, для совместимости с младшими 16-разрядными моделями микропроцессоров фирмы Intel.
Перечислим регистры, относящиеся к группе регистров общего назначения. Так как эти регистры физически находятся в микропроцессоре внутри арифметико-логического устройства (АЛУ), то их еще называют регистрами АЛУ:
eax/ax/ah/al (Accumulator register) — аккумулятор.
Применяется для хранения промежуточных данных. В некоторых командах использование этого регистра обязательно;
ebx/bx/bh/bl (Base register) — базовый регистр.
Применяется для хранения базового адреса некоторого объекта в памяти;
ecx/cx/ch/cl (Count register) — регистр-счетчик.
Применяется в командах, производящих некоторые повторяющиеся действия. Его использование зачастую неявно и скрыто в алгоритме работы соответствующей команды.
К примеру, команда организации цикла loop кроме передачи управления команде, находящейся по некоторому адресу, анализирует и уменьшает на единицу значение регистра ecx/cx;
edx/dx/dh/dl (Data register) — регистр данных.
Так же, как и регистр eax/ax/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. Она заключается в том, что микропроцессор аппаратно поддерживает структурную организацию программы в виде трех частей, называемых сегментами. Соответственно, такая организация памяти называется сегментной.
Для того чтобы указать на сегменты, к которым программа имеет доступ в конкретный момент времени, и предназначены сегментные регистры. Фактически, с небольшой поправкой, как мы увидим далее, в этих регистрах содержатся адреса памяти с которых начинаются соответствующие сегменты. Логика обработки машинной команды построена так, что при выборке команды, доступе к данным программы или к стеку неявно используются адреса во вполне определенных сегментных регистрах. Микропроцессор поддерживает следующие типы сегментов:
Сегмент кода. Содержит команды программы.
Для доступа к этому сегменту служит регистр cs (code segment register) — сегментный регистр кода. Он содержит адрес сегмента с машинными командами, к которому имеет доступ микропроцессор (то есть эти команды загружаются в конвейер микропроцессора).
Сегмент данных. Содержит обрабатываемые программой данные. Для доступа к этому сегменту служит регистр ds (data segment register) — сегментный регистр данных, который хранит адрес сегмента данных текущей программы.
Сегмент стека. Этот сегмент представляет собой область памяти, называемую стеком. Работу со стеком микропроцессор организует по следующему принципу: последний записанный в эту область элемент выбирается первым. Для доступа к этому сегменту служит регистр ss (stack segment register) — сегментный регистр стека, содержащий адрес сегмента стека.
Дополнительный сегмент данных.
Неявно алгоритмы выполнения большинства машинных команд предполагают, что обрабатываемые ими данные расположены в сегменте данных, адрес которого находится в сегментном регистре ds.
Если программе недостаточно одного сегмента данных, то она имеет возможность использовать еще три дополнительных сегмента данных. Но в отличие от основного сегмента данных, адрес которого содержится в сегментном регистре ds, при использовании дополнительных сегментов данных их адреса требуется указывать явно с помощью специальных префиксов переопределения сегментов в команде.
Адреса дополнительных сегментов данных должны содержаться в регистрах es, gs, fs (extension data segment registers).
Регистры состояния и управления eflags и ip
Они постоянно содержат информацию о состоянии, как самого микропроцессора, так и программы, команды которой в данный момент загружены на конвейер. Используя эти регистры, можно получать информацию о результатах выполнения команд и влиять на состояние самого микропроцессора.
eflags/flags (flag register) — регистр флагов. Разрядность eflags/flags — 32/16 бит. Отдельные биты данного регистра имеют определенное функциональное назначение и называются флагами. Младшая часть этого регистра полностью аналогична регистру flags для i8086.
Рис. 2. Содержимое регистра eflags
Исходя из особенностей использования, флаги регистра eflags/flags можно разделить на три группы:
8 флагов состояния. Эти флаги могут изменяться после выполнения машинных команд. Флаги состояния регистра eflags отражают особенности результата исполнения арифметических или логических операций. Это дает возможность анализировать состояние вычислительного процесса и реагировать на него с помощью команд условных переходов и вызовов подпрограмм.
1 флаг управления - df (Directory Flag). Значение флага df определяет направление поэлементной обработки цепочек данных: от начала строки к концу (df = 0) либо наоборот, от конца строки к ее началу (df = 1).
5 системных флагов, управляющих вводом/выводом, маскируемыми прерываниями, отладкой, переключением между задачами и виртуальным режимом 8086. Прикладным программам не рекомендуется модифицировать без необходимости эти флаги, так как в большинстве случаев это приведет к прерыванию работы программы.
eip/ip (Instraction Pointer register) — регистр-указатель команд.
Регистр eip/ip имеет разрядность 32/16 бит и содержит смещение следующей подлежащей выполнению команды относительно содержимого сегментного регистра cs в текущем сегменте команд. Этот регистр непосредственно недоступен программисту, но загрузка и изменение его значения производятся различными командами управления, к которым относятся команды условных и безусловных переходов, вызова процедур и возврата из процедур. Возникновение прерываний также приводит к модификации регистра eip/ip.
Типы данных. Переменные
В программе на ассемблере переменными являются регистры или ячейки памяти, в которых хранятся данные. Существует несколько типов данных-переменных:
Непосредственные данные, представляющие собой числовые или символьные значения, являющиеся частью команды. 20d, 0a2h, 10111b
Данные простого типа, описываемые с помощью ограниченного набора директив резервирования памяти, позволяющих выполнить самые элементарные операции по размещению и инициализации числовой и символьной информации.
Эти два типа данных являются элементарными, или базовыми; работа с ними поддерживается на уровне системы команд микропроцессора. Используя данные этих типов, можно формализовать и запрограммировать практически любую задачу. Но насколько это будет удобно — вот вопрос.
Данные сложного типа, (массивы, структуры, записи и пр.) которые были введены в язык ассемблера с целью облегчения разработки программ. Сложные типы данных строятся на основе базовых типов, которые являются как бы кирпичиками для их построения. Введение сложных типов данных позволяет несколько сгладить различия между языками высокого уровня и ассемблером
Физическая интерпретация данных простого типа основывается на размерности данных:
байт — восемь последовательно расположенных битов, пронумерованных от 0 до 7, при этом бит 0 является самым младшим значащим битом;
слово — последовательность из двух байт, имеющих последовательные адреса. Размер слова — 16 бит; биты в слове нумеруются от 0 до 15. Байт, содержащий нулевой бит, называется младшим байтом, а байт, содержащий 15-й бит - старшим байтом. Микропроцессоры Intel имеют важную особенность — младший байт всегда хранится по меньшему адресу. Адресом слова считается адрес его младшего байта. Адрес старшего байта может быть использован для доступа к старшей половине слова.
двойное слово — последовательность из четырех байт (32 бита), расположенных по последовательным адресам.
учетверенное слово — последовательность из восьми байт (64 бита), расположенных по последовательным адресам.
Рис. 3. Основные типы данных микропроцессора
Логическая интерпретация этих типов:
Целый тип со знаком — двоичное значение со знаком, размером 8, 16 или 32 бита. Знак в этом двоичном числе содержится в 7, 15 или 31-м бите соответственно. Ноль в этих битах в операндах соответствует положительному числу, а единица — отрицательному. Отрицательные числа представляются в дополнительном коде. Числовые диапазоны для этого типа данных следующие:
8-разрядное целое — от –128 до +127;
16-разрядное целое — от –32 768 до +32 767;
32-разрядное целое — от –231 до +231–1.
Целый тип без знака — двоичное значение без знака, размером 8, 16 или 32 бита. Числовой диапазон для этого типа следующий:
байт — от 0 до 255;
слово — от 0 до 65 535;
двойное слово — от 0 до 232–1.
Указатель на память двух типов:
ближнего типа — 32-разрядный логический адрес, представляющий собой относительное смещение в байтах от начала сегмента. Эти указатели могут также использоваться в сплошной (плоской) модели памяти, где сегментные составляющие одинаковы;
дальнего типа — 48-разрядный логический адрес, состоящий из двух частей: 16-разрядной сегментной части — селектора, и 32-разрядного смещения.
Цепочка — представляющая собой некоторый непрерывный набор байтов, слов или двойных слов максимальной длины до 4 Гбайт.
Битовое поле представляет собой непрерывную последовательность бит, в которой каждый бит является независимым и может рассматриваться как отдельная переменная. Битовое поле может начинаться с любого бита любого байта и содержать до 32 бит.
Неупакованный двоично-десятичный тип — байтовое представление десятичной цифры от 0 до 9. Неупакованные десятичные числа хранятся как байтовые значения без знака по одной цифре в каждом байте. Значение цифры определяется младшим полубайтом.
Упакованный двоично-десятичный тип представляет собой упакованное представление двух десятичных цифр от 0 до 9 в одном байте. Каждая цифра хранится в своем полубайте. Цифра в старшем полубайте (биты 4–7) является старшей.
Рис. 4. Основные логические типы данных микропроцессора
Язык микроопераций. Ассемблер.
Структура программы на ассемблере:
Model small ;модель программы, или же количество памяти на сегмент
.data ;сегмент данных
;описание переменных
.stack 100h ;сегмент стека
.code ;сегмент данных
;процедуры, макрокоманды
main:
;основная программа
end main
Директивы резервирования памяти
Для описания простых типов данных в программе используются специальные директивы резервирования и инициализации данных, которые, по сути, являются указаниями транслятору на выделение определенного объема памяти. Если проводить аналогию с языками высокого уровня, то директивы резервирования и инициализации данных являются определениями переменных.
Машинного эквивалента этим директивам нет; просто транслятор, обрабатывая каждую такую директиву, выделяет необходимое количество байт памяти и при необходимости инициализирует эту область некоторым значением.
Директивы резервирования и инициализации данных простых типов имеют формат:
Рис. 5. Директивы описания данных простых типов
На рис. 5 использованы следующие обозначения:
? показывает, что содержимое поля не определено, то есть при задании директивы с таким значением выражения содержимое выделенного участка физической памяти изменяться не будет. Фактически, создается неинициализированная переменная;
значение инициализации — значение элемента данных, которое будет занесено в память после загрузки программы. Фактически, создается инициализированная переменная, в качестве которой могут выступать константы, строки символов, константные и адресные выражения в зависимости от типа данных. Подробная информация приведена в приложении 1;
выражение — итеративная конструкция с синтаксисом, описанным на рис. 5.17. Эта конструкция позволяет повторить последовательное занесение в физическую память выражения в скобках n раз.
имя — некоторое символическое имя метки или ячейки памяти в сегменте данных, используемое в программе.
db— резервирование памяти для данных размером 1 байт. Директивой db можно задавать следующие значения:
выражение или константу, принимающую значение из диапазона:
для чисел со знаком –128...+127;
для чисел без знака 0...255;
символьную строку из одного или более символов. Строка заключается в кавычки. В этом случае определяется столько байт, сколько символов в строке.
dw — резервирование памяти для данных размером 2 байта. Директивой dw можно задавать следующие значения:
выражение или константу, принимающую значение из диапазона:
для чисел со знаком –32 768...32 767;
для чисел без знака 0...65 535;
выражение, занимающее 16 или менее бит, в качестве которого может выступать смещение в 16-битовом сегменте или адрес сегмента;
1- или 2-байтовую строку, заключенная в кавычки.
dd — резервирование памяти для данных размером 4 байта. Директивой dd можно задавать следующие значения:
выражение или константу, принимающую значение из диапазона:
для i386 и выше:
для чисел со знаком –2 147 483 648...+2 147 483 647;
для чисел без знака 0...4 294 967 295;
относительное или адресное выражение, состоящее из 16-битового адреса сегмента и 16-битового смещения;
строку длиной до 4 символов, заключенную в кавычки.
df — резервирование памяти для данных размером 6 байт;
dp — резервирование памяти для данных размером 6 байт. Директивами df и dp можно задавать следующие значения:
выражение или константу, принимающую значение из диапазона:
для чисел со знаком –2 147 483 648...+2 147 483 647;
для чисел без знака 0...4 294 967 295;
относительное или адресное выражение, состоящее из 32 или менее бит (для i80386) или 16 или менее бит (для младших моделей микропроцессоров Intel);
адресное выражение, состоящее из 16-битового сегмента и 32-битового смещения;
строку длиной до 6 байт, заключенную в кавычки.
dq — резервирование памяти для данных размером 8 байт. Директивой dq можно задавать следующие значения:
относительное или адресное выражение, состоящее из 32 или менее бит
константу со знаком из диапазона –263...263–1;
константу без знака из диапазона 0...264–1;
строку длиной до 8 байт, заключенную в кавычки.
dt — резервирование памяти для данных размером 10 байт. Директивой dt можно задавать следующие значения:
относительное или адресное выражение, состоящее из 32 или менее бит
адресное выражение, состоящее из 16-битового сегмента и 32-битового смещения;
константу со знаком из диапазона –279...279-1;
константу без знака из диапазона 0...280-1;
строку длиной до 10 байт, заключенную в кавычки;
упакованную десятичную константу в диапазоне 0...99 999 999 999 999 999 999.
Очень важно уяснить себе порядок размещения данных в памяти. Он напрямую связан с логикой работы микропроцессора с данными. Микропроцессоры Intel требуют следования данных в памяти по принципу: младший байт по младшему адресу.
Для иллюстрации данного принципа рассмотрим листинг 1, в котором определим сегмент данных. В этом сегменте данных приведено несколько директив описания простых типов данных.
Листинг 1. Пример использования директив резервирования и инициализации данных. Программа вводит строку с клавиатуры.
model small
.stack 100h
.data
message db 'Массив байт, содержащих символьные переменные',10,13 '$'
po db 1, 3, 4, 5, 0fh, 0bh, 32, 01011b
perem_1 db 0ffh
perem_2 dw 3a7fh
perem_3 dd 0f54d567ah
k1 db 10
k2 db ?
mas db 10 dup ('?')
adr dw k1
adr_full dd perem_3
.code
start:
mov ax,@data
mov ds,ax
mov ah,0ah
mov dx,offset message ; mov dx, adr
int 21h
mov ax,4c00h
int 21h
end start
Система команд
Формат предложения ассемблера
[имя метки:] КОП [операнд1] [,операнд2] [;комментарии]
Команды пересылки данных
mov <операнд назначения>,<операнд-источник> |
||
можно | Нельзя | Должно быть |
mov ах, вх; ах:=вх mov ах,0а2h; ах:= 0а2h mov per1,ax |
mov ax,bh mov per1, per2 mov ds,per1 mov cs,ds mov cs,ax; пара cs:ip содержит адрес следующей команды |
mov ah, bh mov al, per2 mov per1,al mov ax, per1 mov ds,ax mov ax,ds либо push ds mov cs,ax pop cs |
xchg <операнд1>,<операнд2> ; двунаправленный обмен данными а:=в; в:=с; с:=а
xchg dl,dh; меняет местами данные
Команды ввода-вывода в порт
in аккумулятор,номер_порта — ввод в аккумулятор из порта
out порт,аккумулятор — вывод содержимого аккумулятора в порт
Команды работы с адресами и указателями памяти
lea назначение,источник — загрузка эффективного адреса источника в регистр-назначение;
lea dx, x ; аналогично команде mov dx,offset x
lds назначение,источник — загрузка эффективного адреса источника в регистр назначения и загрузка указателя (адрес сегмента где содержится источник) в регистр сегмента данных ds;
les назначение,источник —-//-регистр дополнительного сегмента данных es;
lgs назначение,источник — -//- регистр дополнительного сегмента данных gs;
lfs назначение,источник — -//- регистр дополнительного сегмента данных fs;
lss назначение,источник — -//- регистр сегмента стека ss.
les dx,per1 ;полный указатель на per1 в пару es:dx
Команды работы со стеком
Для работы со стеком предназначены три регистра:
ss — сегментный регистр стека;
sp/esp — регистр указателя стека;
bp/ebp — регистр указателя базы кадра стека.
push источник — запись значения источник в вершину стека.
Алгоритм работы:
уменьшить значение указателя стека esp/sp на 4/2 (в зависимости от значения атрибута размера адреса — use16 или use32);
записать источник в вершину стека (адресуемую парой ss:esp/sp).
Размер записываемых значений — слово или двойное слово. Также в стек можно записывать непосредственные значения. В стек можно класть значение сегментного регистра cs. Другой интересный момент связан с регистром sp. Команда push esp/sp записывает в стек значение esp/sp по состоянию до выдачи этой команды
Команда push используется совместно с командой pop для записи значений в стек и извлечения их из стека
pop назначение — запись значения из вершины стека по месту, указанному операндом назначение. Значение при этом “снимается” с вершины стека.
Push ax
Push bx
push cx
…
pop cx
pop bx
pop ax
push ax
pop bx ; аналогично команде mov bx,ax
pusha - размещение в стеке регистров общего назначения в следующей последовательности: ax, cx, dx, bx, sp, bp, si, di
pushad - размещение в стеке регистров общего назначения в следующей последовательности: eax, ecx, edx, ebx, esp, ebp, esi, edi
pushf - размещение в вершине стека (ss:sp) содержимого регистра флагов flags
pushfd - размещение в стеке содержимого регистра флагов eflags.
popa - извлечение из стека регистров общего назначения di, si, bp, sp, bx, dx, cx, ax
popad - извлечение из стека регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax
popf - извлечение из стека слова и восстановление его в регистр флагов flags
popfd - извлечение из стека двойного слова и восстановление его в регистр флагов eflags
Организация вычислений
Логические команды
Любая логическая команда меняет значение следующих флагов of, sf,zf,pf,cf (переполнение, знак, нуля, паритет, перенос)
and операнд_1,операнд_2 — операция логического умножения (И - конъюнкция).
оп1:=оп1 ٧ оп2
and ah, 0a1h; ah:=ah٧0ah
and bx, cx; bx:=bx٧cx
and dx, x1; dx:=dx٧x1
or операнд_1,операнд_2 — операция логического сложения (ИЛИ - дизъюнкцию)
or al, x1; оп1:=оп1 & оп2
or eax,edx
or dx, x1
xor операнд_1,операнд_2 — операция логического исключающего сложения (исключающего ИЛИ ИЛИ-НЕ)
test операнд_1,операнд_2 — операция “проверить” (способом логического умножения).
Команда выполняет поразрядно логическую операцию И над битами операндов операнд_1 и операнд_2. Состояние операндов остается прежним, изменяются только флаги zf, sf, и pf, что дает возможность анализировать состояние отдельных битов операнда без изменения их состояния.
not операнд — операция логического отрицания. Команда выполняет поразрядное инвертирование (замену значения на обратное) каждого бита операнда. Результат записывается на место операнда.
Пример программы логического сложения двух однобайтных чисел.
model small
.stack 100h
.data
x1 db 0c2h
x2 db 022h
y db ?
.code
start:
mov ax,@data
mov ds,ax
mov al, x1
or al, x2
mov y, al
mov ax,4c00h
int 21h
end start
Арифметические операции над целыми двоичными числами
Сложение двоичных чисел без знака
inc операнд - операция инкремента, то есть увеличения значения операнда на 1;
inc ax; ax:=ax+1
inc x1
add оп1,оп2 - команда сложения с принципом действия: оп1 = оп1 + оп2 (addition)
add al, bl
add ax, 0fe2h
add ebx, x1+2
add x1, 0fh
add x2, ax
adc оп1,оп2 - команда сложения с учетом флага переноса cf. оп1 = оп1 + оп2 + знач_cf
Вычитание двоичных чисел без знака
dec операнд — операция декремента, то есть уменьшения значения операнда на 1;
dec cx ;cx:=cx-1
dec x
sub операнд_1,операнд_2 — команда вычитания; ее принцип действия:
операнд_1 = операнд_1 – операнд_2
sub al, bl; al:=al-bl
sub ax, x1
sub x2, dx
sub eax, 0f35h
sub x2, 22h
sbb операнд_1,операнд_2 — команда вычитания с учетом заема (флага cf ):
операнд_1 = операнд_1 – операнд_2 – значение_cf
Пример программы сложения двух однобайтных чисел.
model small
.stack 100h
.data
x1 db 0c2h
x2 db 022h
y db ?
.code
start:
mov ax,@data
mov ds,ax
mov al, x1
add al, x2
mov y, al
mov ax,4c00h
int 21h
end start
Умножение двоичных чисел
mul множитель_1 - операция умножения двух целых чисел без учета знака
Алгоритм работы:
Команда выполняет умножение двух операндов без учета знаков. Алгоритм зависит от формата операнда команды и требует явного указания местоположения только одного сомножителя, который может быть расположен в памяти или в регистре. Местоположение второго сомножителя фиксировано и зависит от размера первого сомножителя
mul dl; ax:=al*dl, dl- множитель_1 , al- множитель_2
mul x1; dx:ax=ax*0ad91h, x1 word- множитель_1 , ax- множитель_2
mul ecx; edx:eax=eax*ecx, ecx- множитель_1 , eax- множитель_2
imul множитель_1 - операция умножения двух целочисленных двоичных значений со знаком
Деление двоичных чисел
div делитель - выполнение операции деления двух двоичных беззнаковых значений
Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно и размер его зависит от размера делителя, который указывается в команде
div dl ;ah:al=ax/dl, ax –делимое, dl- делитель , ah-частное, al -остаток
div x1 ;ax:dx=dx:ax/0ad91h, dx:ax –делимое, x1 word- делитель , ax-частное,
;dx -остаток
div ecx ;eax:edx=edx:eax/ecx, edx:eax –делимое, ecx- делитель , eax-частное,
;edx -остаток
idiv делитель - операция деления двух двоичных значений со знаком
Пример программы умножения двух однобайтных чисел.
model small
.stack 100h
.data
x1 db 78
yl db ?
yh db ?
.code
start:
mov ax,@data
mov ds,ax
xor ax, ax
mov al, 25
mul x1
jnc m1 ;если нет переполнения
mov yh,ah
m1:
mov yl, al
mov ax,4c00h
int 21h
end start
Пример. Вычислите следующее выражение у=(х2-х3)/х1, х1,х2,х3 - однобайтные числа
model small
.stack 100h
.data
s1 db 'Введите х1',10,13,'$'
s2 db 'Введите х2',10,13,'$'
s3 db 'Введите х3',10,13,'$'
x1 db ?
x2 db ?
yc db ? ;частное
yo db ? ;остаток
.code
start:
mov ax,@data
mov ds,ax
mov ah,09h
mov dx, offset s1
int 21h ;вывод строки
mov ah,01h вводим х1
int 21h ;вводим число
sub al,30h ;al:=x1
mov x1,al
mov ah,09h
mov dx, offset s2
int 21h
mov ah,01h вводим х2
int 21h
sub al,30h ;al:=x2
mov x2,al
mov ah,09h
mov dx, offset s3
int 21h
mov ah,01h вводим х3
int 21h
sub al,30h ;al:=x3
mov bl,x2 ;bl:=x2
sub bl,al ;bl:=x2-x3
xchg al,bl ;al:=bl, al:=x2-x3
xor ah,ah ;ax:=x2-x3 вычисляем у
mov dl,x1 ;dl:=x1
div dl ;ax/dl, ax/x1
mov yc,ah
mov yo,al
; можно вывести результат на экран
mov ax,4c00h
int 21h
end start
Команды сдвига
Все команды сдвига обеспечивают манипуляции над отдельными битами операндов, они перемещают биты в поле операнда влево или вправо в зависимости от кода операции.
Все команды сдвига устанавливают флаг переноса cf.
shl операнд,счетчик_сдвигов (Shift Logical Left) - логический сдвиг влево. Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули;
shr операнд,счетчик_сдвигов — логический сдвиг вправо.
Алгоритм работы команд:
очередной “выдвигаемый” бит устанавливает флаг cf;
бит, вводимый в операнд с другого конца, имеет значение 0;
при сдвиге очередного бита он переходит во флаг cf, при этом значение предыдущего сдвинутого бита теряется!
sal операнд,счетчик_сдвигов (Shift Arithmetic Left)
sar операнд,счетчик_сдвигов
арифметический сдвиг влево/вправо. Содержимое операнда сдвигается влево/ вправо на количество битов, определяемое значением счетчик_сдвигов. Справа/ Слева в операнд вписываются нули.
Команда sal не сохраняет знака, но устанавливает флаг cf в случае смены знака очередным выдвигаемым битом. В остальном команда sal полностью аналогична команде shl;
Команда sar сохраняет знак, восстанавливая его после сдвига каждого очередного бита.
Команды циклического сдвига
rol операнд,счетчик_сдвигов (Rotate Left) — циклический сдвиг влево.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа.
ror операнд,счетчик_сдвигов (Rotate Right) — циклический сдвиг вправо.
Как видно из рис., команды простого циклического сдвига в процессе своей работы осуществляют одно полезное действие, а именно: циклически сдвигаемый бит не только вдвигается в операнд с другого конца, но и одновременно его значение становиться значением флага cf.
Команды циклического сдвига через флаг переноса cf отличаются от команд простого циклического сдвига тем, что сдвигаемый бит не сразу попадает в операнд с другого его конца, а записывается сначала в флаг переноса cf. Лишь следующее исполнение данной команды сдвига (при условии, что она выполняется в цикле) приводит к помещению выдвинутого ранее бита с другого конца операнда (см. рис. 4).
rcl операнд,счетчик_сдвигов (Rotate through Carry Left) — циклический сдвиг влево через перенос.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.
rcr операнд,счетчик_сдвигов (Rotate through Carry Right) — циклический сдвиг вправо через перенос.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.
Из рис. 4 видно, что при сдвиге через флаг переноса появляется промежуточный элемент, с помощью которого, в частности, можно производить подмену циклически сдвигаемых битов, в частности, рассогласование битовых последовательностей.
Под рассогласованием битовой последовательности здесь и далее подразумевается действие, которое позволяет некоторым образом локализовать и извлечь нужные участки этой последовательности и записать их в другое место
Пример. Дано отрицательное число. Выведите на экран его значение по модулю деленное на 2.
Любое отрицательное число хранится в дополнительном формате
-1 ffh
-2 feh
…
-10 f6h
получить значение числа по модулю, можно осуществив логическое отрицание над числом и добавив 1.
model small
.stack 100h
.data
x db -12
.code
start:
mov ax,@data
mov ds,ax
mov al,x ;в al отрицательное число
not al
inc al ;число по модулю
shr al,1
;выводим результат на экран
aam ;
;преобразование двоичного числа меньшего 63h (9910), которое находится в al в его ;неупакованный BCD-эквивалент
; -разделить значение регистра al на 10;
; -записать частное в регистр ah, остаток — в регистр al.
mov dx,ax ;число в регистр dx
or dx,3030h ;получаю ASCII код числа
xchg dh,dl ;меняю местами старший и младший байт, для вывода символа из dl
mov ah,02h ;
int 21h ;вывожу старшую половинку числа
xchg dh,dl ;меняю местами старший и младший байт,
int 21h ;вывожу младшую половинку числа
mov ax,4c00h
int 21h
end start
Команды передачи управления
По принципу действия, команды микропроцессора, обеспечивающие организацию переходов в программе, можно разделить на три группы:
1. Команды безусловной передачи управления:
- команда безусловного перехода; jmp
- вызова процедуры и возврата из процедуры; call, ret
- вызова программных прерываний и возврата из программных прерываний. Int, iret
2. Команды условной передачи управления:
- команды перехода по результату команды сравнения cmp;
- команды перехода по состоянию определенного флага;
- команды перехода по содержимому регистра ecx/cx.
3. Команды управления циклом:
- команда организации цикла со счетчиком ecx/cx;
- команда организации цикла со счетчиком ecx/cx с возможностью досрочного выхода из цикла по дополнительному условию.
jmp адрес_перехода - безусловный переход без сохранения информации о точке возврата. Аналог goto.
jmp m1 m4:
… …
m1: jmp m4
Условные переходы
Команды условного перехода имеют одинаковый синтаксис:
jcc метка_перехода
Мнемокод всех команд начинается с “j” — от слова jump (прыжок), cc — определяет конкретное условие, анализируемое командой. Что касается операнда метка_перехода, то эта метка может находится только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается.
Для того чтобы принять решение о том, куда будет передано управление командой условного перехода, предварительно должно быть сформировано условие, на основании которого и будет приниматься решение о передаче управления. Источниками такого условия могут быть:
любая команда, изменяющая состояние арифметических флагов;
команда сравнения cmp, сравнивающая значения двух операндов;
состояние регистра ecx/cx.
Условные переходы по содержимому флагов
Название флага | Номер бита в eflags/flag | Команда условного перехода | Значение флага для осуществления перехода |
Флаг переноса cf | 1 | jc | cf = 1 |
Флаг четности pf | 2 | jp | pf = 1 |
Флаг нуля zf | 6 | jz | zf = 1 |
Флаг знака sf | 7 | js | sf = 1 |
Флаг переполнения of | 11 | jo | of = 1 |
Флаг переноса cf | 1 | jnc | cf = 0 |
Флаг четности pf | 2 | jnp | pf = 0 |
Флаг нуля zf | 6 | jnz | zf = 0 |
Флаг знака sf | 7 | jns | sf = 0 |
Флаг переполнения of | 11 | jno | of = 0 |
jcxz метка_перехода (Jump if cx is Zero) — переход, если cx ноль;
jecxz метка_перехода (Jump Equal ecx Zero) — переход, если ecx ноль.
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
model small
.stack 100h
.data
s1 db 'числа равны$'
s2 db 'числа не равны$'
.code
start:
mov ax,@data
mov ds,ax
mov ah,01h
int 21h ;ввели первое число
mov dl,al
mov ah,01h
int 21h ;ввели второе число
sub al,dl ;сравнили числа
jnz m1
mov dx, offset s1
jmp m2
m1: mov dx, offset s2
m2: mov ah,09h
int 21h ;выводим информационную строку
mov ax,4c00h
int 21h
end start
Команда сравнения cmp
cmp операнд_1,операнд_2 - сравнивает два операнда и по результатам сравнения устанавливает флаги. Команда сравнения cmp имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания sub. Единственное, чего она не делает — это запись результата вычитания на место первого операнда.
Алгоритм работы:
-выполнить вычитание (операнд1-операнд2);
-в зависимости от результата установить флаги, операнд1 и операнд2 не изменять (то есть результат не запоминать).
Условные переходы после команд сравнения
Типы операндов | Мнемокод команды условного перехода | Критерий условного перехода | Значения флагов для осществления перехода |
Любые | je | операнд_1 = операнд_2 | zf = 1 |
Любые | jne | операнд_1<>операнд_2 | zf = 0 |
Со знаком | jl/jnge | операнд_1 < операнд_2 | sf <> of |
Со знаком | jle/jng | операнд_1 <= операнд_2 | sf <> of or zf = 1 |
Со знаком | jg/jnle | операнд_1 > операнд_2 | sf = of and zf = 0 |
Со знаком | jge/jnl | операнд_1 => операнд_2 | sf = of |
Без знака | jb/jnae | операнд_1 < операнд_2 | cf = 1 |
Без знака | jbe/jna | операнд_1 <= операнд_2 | cf = 1 or zf=1 |
Без знака | ja/jnbe | операнд_1 > операнд_2 | cf = 0 and zf = 0 |
Без знака | jae/jnb | операнд_1 => операнд_2 | cf = 0 |
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
model small
.stack 100h
.data
s1 db 'числа равны$'
s2 db 'числа не равны$'
.code
start:
mov ax,@data
mov ds,ax
mov ah,01h
int 21h ;ввели первое число
mov dl,al
mov ah,01h
int 21h ;ввели второе число
cmp al,dl ;сравнили числа
jne m1
mov dx, offset s1
jmp m2
m1: mov dx, offset s2
m2: mov ah,09h
int 21h ;выводим информационную строку
mov ax,4c00h
int 21h
end start
Организация циклов
loop метка_перехода (Loop) — повторить цикл
Работа команды заключается в выполнении следующих действий:
- декремента регистра ecx/cx;
- сравнения регистра ecx/cx с нулем:
- если (ecx/cx) > 0, то управление передается на метку перехода;
- если (ecx/cx) = 0, то управление передается на следующую после loop команду
mov cx, количество циклов
м1: тело цикла
loop m1
loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0.
loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1
Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт).
Организация вложенных циклов
mov cх,n ; в сх заносим количество итераций внешнего цикла
m1:
push cx
…
mov cx,n1; в сх заносим количество итераций внутреннего цикла
m2:
тело внутреннего цикла
loop m2
…
pop cx
loop m1
Пример программы: Напишите программу подсчета у=1+2+3+…+n, n не более 10000.
model small
.stack 100h
.data
yb dd ?
ym dw ?
s1 db 'введите n',10,13,'$'
.code
start:
mov ax,@data
mov ds,ax
mov dx, offset s1
mov ah,09h
int 21h
mov cx,3
m: shl bx,4
mov ah,01h
int 21h вводим n в регистр bx
sub ax,130h
add bx,ax
loop m
mov cx,bx
xor dx,dx
xor al,al
m1: add dx,cx считаем у
jnc m2
mov al,1
m2: loop m1
cmp al,1
je m3
mov ym,dx
m3: mov yb,edx
mov ax,4c00h
int 21h
end start
Цепочечные команды
(Команды обработки строк символов)
Цепочка – это последовательность элементов, размер которых может быть байт, слово, двойное слово. Содержимое этих элементов может быть любое – символы, числа.
В системе команд микропроцессора имеется семь операций-примитивов обработки цепочек.
Каждая из них реализуется в микропроцессоре тремя командами, в свою очередь, каждая из этих команд работает с соответствующим размером элемента — байтом, словом или двойным словом.
Вместе с цепочечными командами обычно применяют префиксы повторений, которые ставятся перед командой в поле [метки]. Цепочечная команда без префикса выполняется один раз. С префиксом цепочечные команды выполняются циклично.
rep (REPeat) - команда выполняется, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса, этого не делает.
repe или repz (REPeat while Equal or Zero) - команда выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из этих условий нарушается, управление передается следующей команде программы
repne или repnz (REPeat while Not Equal or Zero) - команда циклически выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен нулю. При невыполнении одного из этих условий работа команды прекращается.
Формирования физического адреса операндов адрес_источника и адрес_приемника происходит следующим образом:
адрес_источника — пара ds:esi/si;
адрес_приемника — пара es:edi/di
Важный момент, касающийся всех цепочечных команд, — это направление обработки цепочки. Есть две возможности:
- от начала цепочки к ее концу, то есть в направлении возрастания адресов;
- от конца цепочки к началу, то есть в направлении убывания адресов.
Цепочечные команды сами выполняют модификацию регистров, адресующих операнды, обеспечивая тем самым автоматическое продвижение по цепочке. Количество байт, на которые эта модификация осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления df (Direction Flag) в регистре eflags/flags. Состоянием флага df можно управлять с помощью двух команд, не имеющих операндов:
cld (Clear Direction Flag) — очистить флаг направления df = 0, значение индексных регистров esi/si и edi/di будет автоматически увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов;
std (Set Direction Flag) — установить флаг направления df = 1, то значение индексных регистров esi/si и edi/di будет автоматически уменьшаться (операция декремента) цепочечными командами, то есть обработка будет идти в направлении убывания адресов.
Типовой набор действий для выполнения любой цепочечной команды:
Установить значение флага df в зависимости от того, в каком направлении будут обрабатываться элементы цепочки — в направлении возрастания или убывания адресов.
Загрузить указатели на адреса цепочек в памяти в пары регистров ds:(e)si и es: (e)di.
Загрузить в регистр ecx/cx количество элементов, подлежащих обработке.
Выдать цепочечную команду с префиксом повторений.
Пересылка цепочек
movs адрес_прием, адрес_источника (MOVe String)- переслать цепочку;
movsb MOVe String Byte) — переслать цепочку байт;
movsw (MOVe String Word) — переслать цепочку слов;
movsd (MOVe String Double word) — переслать цепочку двойных слов.
Команда копирует байт, слово или двойное слово из цепочки источника, в цепочку приемника. Размер пересылаемых элементов ассемблер определяет, исходя из атрибутов идентификаторов. К примеру, если эти идентификаторы были определены директивой db, то пересылаться будут байты, если идентификаторы были определены с помощью директивы dd, то пересылке подлежат двойные слова.
Для цепочечных команд с операндами типа movs адрес_приемника,адрес_источника, не существует машинного аналога. При трансляции в зависимости от типа операндов транслятор преобразует ее в одну из трех машинных команд: movsb, movsw или movsd.
Сама по себе команда movs пересылает только один элемент, исходя из его типа, и модифицирует значения регистров esi/si и edi/di. Если перед командой написать префикс rep, то одной командой можно переслать до 64 Кбайт данных. Число пересылаемых элементов должно быть загружено в счетчик — регистр cx (use16) или ecx (use32).
Пример проги. Пересылка строк командой movs
MODEL small
STACK 256
.data
source db 'Тестируемая строка','$' ;строка-источник
dest db 19 DUP (' ') ;строка-приёмник
.code
main:
mov ax,@data ;загрузка сегментных регистров
mov ds,ax ;настройка регистров DS и ES на адрес сегмента данных
mov es,ax
cld ;сброс флага DF — обработка строки от начала к концу
lea si,source ;загрузка в si смещения строки-источника
lea di,dest ;загрузка в DS смещения строки-приёмника
mov cx,20 ;для префикса rep — счетчик повторений (длина строки)
rep movs dest,source ;пересылка строки
lea dx,dest
mov ah,09h ;вывод на экран строки-приёмника
int 21h
mov ax,4c00h
int 21h
end main
Операция сравнения цепочек
cmps адрес_приемника,адрес_источника(CoMPare String) — сравнить строки;
cmpsb (CoMPare String Byte) — сравнить строку байт;
cmpsw (CoMPare String Word) — сравнить строку слов;
cmpsd (CoMPare String Double word) — сравнить строку двойных слов.
Алгоритм работы команды cmps заключается в последовательном выполнении вычитания (элемент цепочки-источника — элемент цепочки-получателя) над очередными элементами обеих цепочек. Принцип выполнения вычитания командой cmps аналогичен команде сравнения cmp. Она, так же, как и cmp, производит вычитание элементов, не записывая при этом результата, и устанавливает флаги zf, sf и of.
После выполнения вычитания очередных элементов цепочек командой cmps, индексные регистры esi/si и edi/di автоматически изменяются в соответствии со значением флага df на значение, равное размеру элемента сравниваемых цепочек.
Чтобы заставить команду cmps выполняться несколько раз, то есть производить последовательное сравнение элементов цепочек, необходимо перед командой cmps определить префикс повторения. С командой cmps можно использовать префикс повторения repe/repz или repne/repnz:
repe или repz — если необходимо организовать сравнение до тех пор, пока не будет выполнено одно из двух условий: достигнут конец цепочки (содержимое ecx/cx равно нулю) или в цепочках встретились разные элементы (флаг zf стал равен нулю);
repne или repnz — если нужно проводить сравнение до тех пор, пока: не будет достигнут конец цепочки (содержимое ecx/cx равно нулю) или в цепочках встретились одинаковые элементы (флаг zf стал равен единице).
Пример программы Сравнение двух строк командой cmps
MODEL small
STACK 256
.data
sov db 0ah,0dh,'Строки совпадают.','$'
nesov db 0ah,0dh,'Строки не совпадают','$'
s1 db '0123456789',0ah,0dh,'$';исследуемые строки
s2 db 10
s3 db 11 dup (0)
.code
main:
mov ax,@data ;загрузка сегментных регистров
mov ds,ax
mov es,ax ;настройка ES на DS
;вводим строку
mov ah, 0аh
mov dx, offset s2
int 21h
;поиск совпадающих элементов, сброс флага DF - сравнение в направлении возрастания адресов
cld
lea si,s1 ;загрузка в si смещения string1
lea di,s3 ;загрузка в di смещения string2
mov cx,10 ;длина строки для префикса repe
repe cmpsb ;сравнение строк (пока сравниваемые элементы строк равны)
;выход при обнаружении не совпавшего элемента
jcxz equal ;cx=0, то есть строки совпадают
lea dx, nesov
jmp exit ;выход
equal: lea dx, sov
exit: mov ah,09h
int 21h ;вывод сообщения
mov ax,4c00h
int 21h
end main ;конец программы
Операция сканирования цепочек
scas адрес_приемника (SCAning String) — сканировать цепочку;
scasb (SCAning String Byte) — сканировать цепочку байт;
scasw (SCAning String Word) — сканировать цепочку слов;
scasd (SCAning String Double Word) — сканировать цепочку двойных слов
Эти команды осуществляют поиск искомого значения, которое находится в регистре al/ax/eax. Принцип поиска тот же, что и в команде сравнения cmps, то есть последовательное выполнение вычитания
(содержимое регистра_аккумулятора – содержимое очередного_элемента_цепочки).
В зависимости от результатов вычитания производится установка флагов, при этом сами операнды не изменяются.
Так же, как и в случае команды cmps, с командой scas удобно использовать префиксы repe/repz или repne/repnz:
repe или repz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий: достигнут конец цепочки (содержимое ecx/cx равно 0) или в цепочке встретился элемент, отличный от элемента в регистре al/ax/eax;
repne или repnz — если нужно организовать поиск до тех пор, пока не будет выполнено одно из двух условий достигнут конец цепочки (содержимое ecx/cx равно 0)или в цепочке встретился элемент, совпадающий с элементом в регистре al/ax/eax.
Пример проги. найти количество * в строке
MODEL small
STACK 256
.data
s1 db 20
s2 db 21 dup ?
s3 db 'количество * в строке',0ah,0dh,'$'
.code
main:
mov ax,@data
mov ds,ax
mov es,ax ;настройка ES на DS
;вводим строку
mov ah,0ah
mov dx, offset s1
int 21h
;поиск *
mov al,'*' ;символ для поиска — `а`(кириллица)
cld ;сброс флага df
lea di, s2 ;загрузка в es:di смещения строки
inc di ;первый элемент в s3 это количество введенных символов, его игнорируем
xor bl ;обнуляем счетчик звездочек
mov cx,20 ;для префикса repne — длина строки
m1: repne scasb ;пока искомый символ и символ в строке не совпадут идет поиск, ;выход при совпадении
je found ;если равны - переход на обработку
;вывод количества звездочек в строке
mov ah,09h
mov dx,offset s3
int 21h ;вывод сообщения nochar
mov al,bl
aam
or ax, 3030h
mov dx,ax
xchg dh,dl
mov ah, 02h
int 21h
xchg dh,dl
int 21h
mov ax,4c00h
int 21h
;суммируем количество звездочек
found: inc bl
jmp m1
end main
Загрузка элемента цепочки в аккумулятор
lods адрес_источника (LOaD String) — загрузить элемент из цепочки в регистр-аккумулятор al/ax/eax;
lodsb (LOaD String Byte) — загрузить байт из цепочки в регистр al;
lodsw (LOaD String Word) — загрузить слово из цепочки в регистр ax;
lodsd (LOaD String Double Word) — загрузить двойное слово из цепочки в регистр eax.
Эта операция-примитив позволяет извлечь элемент цепочки и поместить его в регистр-аккумулятор al, ax или eax. Эту операцию удобно использовать вместе с поиском (сканированием) с тем, чтобы, найдя нужный элемент, извлечь его (например, для изменения).
Перенос элемента из аккумулятора в цепочку
stos адрес_приемника (STOre String) — сохранить элемент из регистра-аккумулятора al/ax/eax в цепочке;
stosb (STOre String Byte) — сохранить байт из регистра al в цепочке;
stosw (STOre String Word) — сохранить слово из регистра ax в цепочке;
stosd (STOre String Double Word) - сохранить двойное слово из регистра eax в цепочке.
Эта операция-примитив позволяет произвести действие, обратное команде lods, то есть сохранить значение из регистра-аккумулятора в элементе цепочки. Эту операцию удобно использовать вместе с операцией поиска (сканирования) scans и загрузки lods, с тем, чтобы, найдя нужный элемент, извлечь его в регистр и записать на его место новое значение.
Сложные структуры данных
Одномерные массивы
Все элементы массива располагаются в памяти последовательно
Описание элементов массива
mas db 1,2,3,4,5
mas dw 5 dup (0)
Доступ к элементам массива
mov ax,mas[si] ; в si номер элемента в массиве
mov mas[si], ax ; в di номер элемента в массиве
Используя команды i486 можно использовать адресацию с масштабированием, при размере элементов больше байта
Mov ax, mas[si*2] ;
Пример программы Найти в строке хотя бы один нулевой элемент
model small
.stack 100h
.data
bufer dw 25 ;формирую размер буфера для ввода строки
mas dw 25 dup (' ') ;формирую буфер
adr dw bufer ;описываю адрес
subj1 db ‘в строке найден нулевой элемент', '$'
subj2 db ‘в строке не найден нулевой элемент', '$'
.code
main:
mov ax,@data
mov ds,ax
mov ah,0ah
mov dx, adr
int 21h ; ввод строки с клавиатуры
;поиск нулевого элемента
xor si, si
mov cx, mas[si] ;загружаем в сх количество элементов в строке
mov ax, 030h ;в ax загружаем ASCII код нуля
m1: inc si либо inc si
inc si cmp ax, mas[si*2]
cmp ax, mas[si]
je m2 ;если в строке найдем нулевой элемент, то выходим из цикла на вывод subj1
loop m1
;нормальный выход из цикла означает что в строке нет нулевых элементов
mov ah,09h
lea dx, subj2
int 21h
jmp exit
m2: mov ah, 09h
lea dx,subj1
int 21h
exit: mov ax,4c00h
int 21h
end main
Двумерные массивов
!Специальных средств для описания двумерных массивов в ассемблере нет!
Двумерный массив описывается также как и одномерный массив, отличие заключается в трактовке расположения элементов. Пусть последовательность элементов трактуется как двумерный массив, расположенный по строкам, тогда адрес элемента [i,j] вычисляется так
База+колич_элем_строке*размер_элем*I+j
Для определения базы используют имя массива, для второго слагаемого регистр bx , для третьего si, это базово-индексная адресация.
Описание массива:
Mas1 db 10 dup (3 dup (?))
Mas2 db 1,2,3,4,5
3,4,5,6,7
4,7,9,2,0
Пример поиска максимального элемента в каждой строке однобайтного массива mas, размером 5*10, с занесением максимальных элементов в массив max (1*5). Инициализацию массива mas рассматривать не будем.
…
xor di, di ;обнуляем индексы массива max
xor bx, bx ;обнуляем индексы строк массива mas
xor si, si ;обнуляем индексы столбцов массива mas
mov cx,5 ;в cx количество строк, внешний цикл
m1: push cx
mov cx, 10 ;в сх количество столбцов, внутренний цикл
mov al, mas[si+bx];первый элемент из 1 строки mas в аl
m2: inc si
cmp al, mas[si+bx] ;сравниваем со следующим элем. строки
jb m3 ;если меньше на m3
mov al, mas[si+bx] ;иначе в аl заносим больший элемент
m3: loop m2 ;после выхода из цикла в ах максимальный элемент в данной строке
mov max[di],al ;кладем максимальный элемент в массив max
inc di
xor si,si ;обнуляем номер столбца
add bx, 10 ;переходим на следующую строку
pop cx ;достаем сх
loop m1
…
Структура – это тип данных, состоящий из фиксированного числа элементов разного типа.
Для использования структур в программе необходимо выполнить три действия:
Задать шаблон структуры. По смыслу это означает определение нового типа данных (схемы или шаблона), который впоследствии можно использовать для определения переменных этого типа. Память при этом не выделяется, это информация для транслятора о расположении полей и их значению по умолчанию.
Синтаксис описания шаблона структуры:
имя_структуры STRUC
<описание полей> ; последовательность директив описания данных dd,dw,db…
имя_структуры ENDS
Определить экземпляр структуры. Этот этап подразумевает инициализацию конкретной переменной заранее определенной (с помощью шаблона) структурой. В данном случае транслятору дается указание выделить память и присвоить этой области символическое имя.
Описать структуру в программе можно только один раз, а определить – любое количество раз.
Определение данных с типом структуры имеет следующий вид:
[имя переменной] имя_структуры <[список значений]>
Организовать обращение к элементам структуры.
Для того чтобы сослаться в команде на поле некоторой структуры, используется следующее выражение:
имя_переменной.имя_поля_структуры,
Фрагмент программы. Найти из списка студентов отличника по всем предметам.
Model small
.586p
Stud struc
Name db 20 dup (‘’)
Phisika db ?
Matem db ?
Stud ends
.data
Bufer Stud <””,’’,’’,’’> ;зарезервировали пустую структуру
S1 Stud <”Ivanov”,’5’,’5’,’5’>
S2 Stud <”Petrov”,’3’,’3’,’3’>
S3 Stud <”Сидоров”,’5’,’2’,’5’>
…
mov bx, offset s1
mov al, [bx].Phisika
cmp al, ‘5’
jne m2
mov al, [bx].Matem
cmp al, ‘5’
jne m2
;нашли одного из отличников, надо вывести его фамилию
m2: mov al, s2.Phisika ;ищем следующего отличника
mov ah, s2.Matem
cmp ax, ‘55’
jne m3
;нашли одного из отличников, надо вывести его фамилию
m3: ;ищем следующего отличника
Объединение - тип данных, позволяющий трактовать одну и ту же область памяти как имеющую разные типы и имена.
Описание объединений в программе напоминает описание структур, то есть сначала описывается шаблон, в котором с помощью директив описания данных перечисляются имена и типы полей:
имя_объединения UNION
<описание полей>
имя_объединения ENDS
Отличие
объединений
от структур
состоит, в частности,
в том, что при
определении
переменной
типа объединения
память выделяется
в соответствии
с размером
максимального
элемента. Обращение
к элементам
объединения
происходит
по их именам,
но при этом
нужно, конечно,
помнить о том,
что все поля
в объединении
накладываются
друг на друга.
Одновременная
работа с элементами
объединения
исключена. В
качестве элементов
объединения
можно использовать
и структуры.
Model small
.586p
st union
stu1 dw ?
stu2 db ?
stu3 dd ?
st ends
.data
q st <> ;пустое объединение
z st <12ffh> ;заполнили объединение значением
…
mov q.stu2, al ;в переменную положили содержимое регистра al
mov q.stu3, edx
mov bx, z.stu1
mov dx, offset q.stu1
Запись - структурный тип данных, состоящий из фиксированного числа элементов длиной от одного до нескольких бит. При описании записи для каждого элемента указывается его длина в битах и, что необязательно, некоторое значение. Суммарный размер записи определяется суммой размеров ее полей и не может быть более 8, 16 или 32 бит. Если суммарный размер записи меньше указанных значений, то все поля записи “прижимаются” к младшим разрядам
Использование записей в программе, так же, как и структур, организуется в три этапа:
Описание шаблона записи
имя_записи RECORD <описание элементов>
2. Для использования шаблона записи в программе необходимо определить переменную с типом данной записи, для чего применяется следующая синтаксическая конструкция (рис. 7):
3. Организация работы с записями. Обычные механизмы адресации бессильны, поскольку они работают на уровне байтов, а не отдельных битов.
каждому имени элемента записи ассемблер присваивает числовое значение, равное количеству сдвигов вправо, которое нужно произвести, для того чтобы этот элемент оказался прижатым к началу ячейки памяти;
размер элемента записи в битах можно узнать с помощью оператора width;
оператор mask позволяет локализовать биты нужного элемента записи;
все действия по преобразованию элементов записи производятся с помощью логических команд;
команда setfield устанавливает значение некоторого поля записи
setfield имя_элемента_записи регистр_ назначение, регистр_источник
команда getfield осуществляет выборку некоторого поля записи
getfield имя_элемента_записи регистр_назначение, регистр_ источник
Процедуры. Макрокоманды
Процедура, часто называемая подпрограммой, - это правильным образом оформленная совокупность команд, которая будучи однократно описана, при необходимости может быть вызвана в любом месте программы. Процедура представляет собой группу команд для решения конкретной подзадачи и обладает средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку. В простейшем случае программа может состоять из одной процедуры.
Описание процедуры может размещается в любом месте программы, но таким образом чтобы на нее случайным образом не попало управление:
в начале программы, до первой исполняемой команды;
в конце, после команды возвращающей управление операционной системе;
промежуточный вариант, тело процедуры располагается внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход процедуры командой jmp;
в другом модуле.
Синтаксис описания процедуры:
Имя_процедуры PROC заголовок
Команды, директивы тело процедуры
[ret] возврат из процедуры
[имя_процедуры] ENDP конец процедуры
Вызов процедуры осуществляется командой
CALL [модификатор] имя_процедуры
Команда call передает управление по адресу с символическим адресом имя_процедуры, с сохранением в стеке адреса возврата, команды следующей после команды call.
Возврат из процедуры осуществляется по команде
RET [число]
Команда ret считывает адрес возврата из стека и загружает его в регистры cs и ip/eip, возвращая таким образом управление команде, следующей за командой call. Число – необязательный параметр, обозначающий количество элементов, удаляемых из стека при возврате из процедуры. Размер элемента зависит от используемой модели сегментации 32 или 16 разрядной.
Передача аргументов из/в процедуру может осуществляться через регистры, переменные или стек.
Пример.
Model small .stack 100h .data w db 25 dup (?) .code vvod proc mov ah, 0ah lea dx, w int 21h ret vvod endp main: |
… Call schet Call vvod … exit: mov ax,4c00h int 21h schet proc .. ret schet endp end main |
Макрокоманда является одним из многих механизмов замены текста программы. С помощью макрокоманды в текст программы можно вставлять последовательности строк и привязывать их к месту вставки.
Макрокоманда представляет собой строку, содержащую некоторое имя – имя макрокоманды, предназначенное для того, чтобы быть замещенным одной или несколькими другими строками при трансляции.
Для работы с макрокомандой вначале необходимо задать ее шаблон-описание, так называемое макроопределение.
Имя_макрокоманды MACRO [список_формальных_аргументов]
<Тело макроопределения>
ENDM
Существует три варианта расположения макроопределений:
в начале исходного текста программы до сегмента кода и данных с тем, чтобы не ухудшать читабельность программы. В данном случае макрокоманды будут актуальны только в пределах этой программы;
в отдельном файле. Для того, чтобы использовать эти макроопределения в других программах, необходимо в начале исходного текста этих программ записать директиву
include имя_файла
в макробиблиотеке. Макробиблиотека создается в том случае, когда написанные макросы используются практически во всех программах. Подключается библиотека директивой include. Недостаток этого и предыдущего методов в том, что в исходный текст программы включаются абсолютно все макроопределения. Для исправления ситуации можно использовать директиву purge, в качестве операндов которой перечисляются макрокоманды, которые не должны включаться в текст программы.
Include macrobibl.inc ;в исходный текст программы будут вставлены строки из macrobibl.inc
Purge outstr, exit ;за исключением макроопределений outstr, exit
Активизация макроса осуществляется следующим образом:
Имя_макрокоманды список_ фактических_ аргументов
Model small Vivod macro rg Mov dl, rg Mov ah, 02h Int 21h endm .data .. .code .. vivod al .. |
Model small sravnenie macro rg, met cmp rg , ‘a’ ja met add rg, 07h met: add rg, 30h endm .data .. .code .. sravnenie al, m1 .. |
Функционально макроопределения похожи на процедуры. Сходство их в том, что и те, и другие достаточно один раз где-то описать, а затем вызывать их специальным образом. На этом их сходство заканчивается, и начинаются различия, которые в зависимости от целевой установки можно рассматривать и как достоинства и как недостатки:
- в отличие от процедуры, текст которой неизменен, макроопределение в процессе макрогенерации может меняться в соответствии с набором фактических параметров. При этом коррекции могут подвергаться как операнды команд, так и сами команды. Процедуры в этом отношении объекты менее гибки;
- при каждом вызове макрокоманды ее текст в виде макрорасширения вставляется в программу. При вызове процедуры микропроцессор осуществляет передачу управления на начало процедуры, находящейся в некоторой области памяти в одном экземпляре. Код в этом случае получается более компактным, хотя быстродействие несколько снижается за счет необходимости осуществления переходов.
Подключение процедур и макросов во внешнем файле
Внешний файл с расширением inc, а в файле которой использует процедуру или макрос присутствуют следующие строки
Model small
Include [NAME].INC
А вызов макросов и процедур как обычно.
Работа с портами ввода вывода
Адресное пространство памяти в любой микропроцессорной системе семейства х86 делится на пространство адресов памяти и пространство портов ввода/вывода. Это обусловлено архитектурной реализацией и исторической эволюцией процессоров х86.
Для обращения к пространству ввода/вывода используются команды in, out, ins, outs.
In регистр, номер порта – ввод данных из порта в регистр
Out номер порта, регистр – вывод данных из регистра в порт
Ins, Outs - работают с элементами строки памяти.
In ax, 064h ; запись слова в ах из порта 064h
Out 064,al ; запись байта в порт
In ax, dx ; косвенная адресация порта через регистр dx, применяется при использовании 16 разрядного адреса порта
Через порты ввода/вывода осуществляется программирование, контроль и отладка работы периферийных устройств. Зачастую один адрес памяти может служить портом ввода при чтении данных, и портом вывода при записи.
Распределением адресов управляет BIOS через регистры конфигурирования чипсета. Обычно для совместимости аппаратного и программного обеспечения распределение адресов стандартно для любых микропроцессорных систем семейства х86.
ВЫЧИСЛИТЕЛЬНЫЕ СИСТЕМЫ
Состав любой вычислительной системы одинаков: микропроцессор, электронная память подсистема ввода-вывода. Эти устройство объединяет системная шина, состоящая из следующих шин: данных, адреса и управления.
Каждый микропроцессор имеет определенное число элементов памяти, называемых регистрами, арифметико-логическое устройство и устройство управления. Регистры используются для временного хранения выполняемой команды, адресов памяти, обрабатываемых данных и другой внутренней информации МП. В АЛУ производится арифметическая и логическая обработка данных. Устройство управления реализует временную диаграмму и вырабатывает необходимые управляющие сигналы для внутренней работы МП и связи его с другой аппаратурой через внешние шины МП.
Структуры различных типов МП могут существенно различаться, однако наиболее важными параметрами являются архитектура, адресное пространство памяти, разрядность шины данных, быстродействие. Архитектуру МП определяет разрядность слова и внутренней шины данных МП. Первые МП основывались на 4-разрядной архитектуре. Первые ПЭВМ использовали МП с 8-разрядной архитектурой, а современные МП основаны на МП с 64- и 32-разрядной архитектурой.
Микропроцессоры используют последовательный принцип выполнения команд, принцип параллельной работы, или конвейерный метод выполнения команд.
Последовательный принцип, при котором очередная операция начинается только после выполнения предыдущей.
Принцип параллельной работы, при которой одновременно с выполнением текущей команды производятся предварительная выборка и хранение последующих команд.
В МП с 32-разрядной архитектурой используется конвейерный метод выполнения команд, при котором несколько внутренних устройств МП работают параллельно, производя одновременно обработку нескольких последовательных команд программы.
Адресное пространство памяти определяется разрядностью адресных регистров и адресной шины МП. Для выборки команд и обмена данными с памятью МП имеют шину данных, разрядность которой, как правило, совпадает с разрядностью внутренней шины данных, определяемой архитектурой МП.
Одним из важных параметров МП является быстродействие, определяемое тактовой частотой его работы, которая обычно задается внешними синхросигналами. Выполнение простейших команд (например, сложение двух операндов из регистров или пересылка операндов в регистрах МП) требует минимально двух периодов тактовых импульсов (для выборки команды и ее выполнения). Более сложные команды требуют для выполнения до 10—20 периодов тактовых импульсов. Если операнды находятся не в регистрах, а в памяти, дополнительное время расходуется на выборки операндов в регистры и записи результата в память.
Скорость работы МП определяется не только тактовой частотой, но и набором его команд, их гибкостью, развитой системой прерываний.
Электронная память
Содержит операнды и программу, которую выполняет МП. Используются два типа электронной памяти: постоянные запоминающие устройства (ПЗУ) и оперативные запоминающие устройства (ОЗУ).
В ПЗУ хранится информация, которую ЭВМ может использовать сразу же после включения питания. Она включает программы инициализации периферийных микросхем, программы ядра ОС и программы обработки прерываний.
Постоянное запоминающее устройство является энергонезависимой памятью: после выключения питания информация в нем сохраняется. Информация в ОЗУ разрушается при выключении питания.
В ОЗУ хранятся оперативные данные и программы, используемые МП. Поэтому микросхемы ОЗУ по быстродействию должны быть согласованы с МП, а емкость ОЗУ (вместе с ПЗУ) должна приближаться к пределу, определяемому адресным пространством МП.
Схемы ввода-вывода
Связь МП с контроллерами ПУ обычно осуществляется через порты ввода-вывода под непосредственным управлением МП или под управлением специализированных контроллеров. Связь МП с ПУ производится через стандартизованные интерфейсы ПУ.
Организация и быстродействие схемы ввода-вывода влияет на быстродействие всей вычислительной системы.
Микропроцессоры
Архитектура однокристального 16-ти разрядного микропроцессора К1810ВМ86.
Аналог I8086.
Ориентирован на параллельное выполнение выборки и команд, может быть условно разделен на две части, работающие асинхронно: устройство сопряжения с магистралью (БИ – интерфейсный блок) и блок обработки (БО).
Интерфейсный блок обеспечивает формирование 20-разрядного физического адреса памяти, выборку команд и операндов из памяти, организацию очередности команд и запоминание результатов выполнения команд в памяти.
БИ состоит из очереди команд, сегментных регистров, регистра адреса команд, сумматора адреса (SM) и управления машинными циклами.
Устройство сопряжения готово выполнить цикл выборки слова из памяти всякий раз, когда в очереди освобождаются, по меньшей мере, два байта, БО извлекает из нее коды команд по мере необходимости. Очередь организована по принципу «первым пришел — первого обслужили», а шесть ее уровней позволяют удовлетворять запросы БО в кодах команд достаточно эффективно, сокращая тем самым до минимума затраты времени МП на ожидание выборки команд из памяти. Выполнение команд происходит в логической последовательности, предписанной программой, поскольку в очереди находятся те команды, которые хранились в ячейках памяти, непосредственно следующих за текущей командой. При передаче управления в другую ячейку памяти ход выполнения программы нарушается. Устройство сопряжения очищает регистры очереди, выбирает команду по адресу перехода, передает ее УО и начинает новое заполнение этих регистров. При возврате из подпрограммы или из прерывания происходит восстановление очереди команд, адреса которых автоматически вычисляются в СМА. Если МП необходимо выполнить цикл чтения или записи, то выборка команд приостанавливается на время цикла.
Блок обработки предназначен для выполнения операций по обработке данных и состоит из блока микропрограммного управления (БМУ), АЛУ, восьми регистров общего назначения (РОН) и регистра флагов (F).
Команды, выбранные БИ из памяти и записанные в очередь команд, по запросам от БО поступают в БМУ. Это устройство, содержащее память микрокоманд, декодирует команды и вырабатывает последовательность микрокоманд, управляющую процессом обработки. В АЛУ выполняются арифметические и логические операции над 8- и 16-разрядными числами с фиксированной запятой.
Программно-доступными функциональными частями МП являются регистры общего назначения (для хранения операндов и результатов выполнения команд), сегментные (для хранения базовых адресов текущих сегментов памяти), адреса команд и регистр флагов.
Функциональное назначение выводов микропроцессора К1810ВМ86
Вход MN/MX служит для выбора режима функционирования, который предлагает пользователю выбор состава выходных управляющих сигналов в соответствии со степенью сложности проектируемой МП-системы.
В минимальном режиме (вывод MN/MX подключен к шине питания), ориентированном на малые вычислительные системы, МП выдает сигналы управления обменом с памятью и внешними устройствами, а также обеспечивает доступ к системной магистрали по запросу прямого доступа к памяти, используя сигналы HOLD и HLDA. Если вывод MN/MX подключен к шине «Земля» (общий), то МП находится в максимальном режиме и может работать в сложных одно- и многопроцессорных системах. При работе в этом режиме изменяются функции ряда выводов МП.
Обозначение выводов |
Функциональное назначение выводов |
AD0 .. AD15 | 16-разрядная двунаправленная мультиплексированная шина адреса/данных |
A16/S3 .. A19/S6 |
4-х разрядная выходная шина микропроцессора, по которой в такте Т1 передаются 4 старших разряда адреса памяти, а в тактах Т2, Т3, Т4, при выполнении операций обращения к памяти и области ввода/вывода – признаки состояния микропроцессора. S4, S3 – указывают номер одного из 4 сегментных регистров, который в данном цикле участвует в формировании исполнительного адреса. S5 – указывает состояние триггера разрешения прерывания S6 – всегда равен 0. |
BHE/S7 |
Выход, 0 на котором в Т1 указывает, что по шине адреса/данных передаются 8-разрядное слово. Сделано для совместимости со старым ПО. В тактах Т2, Т3, Т4 на этом выходе присутствует S7 – признак состояния МП. Если S7=1 – МП находится в состоянии захвата шин внешним устройством. |
RD | Чтение, выход, 0 на котором означает, что МП осуществляет чтение из памяти или портов ввода/вывода. |
RЕАDY | Готовность, вход для подачи сигнала окончания цикла работы устройств памяти или ввода/вывода. Используется для синхронизации более медленных памяти или ВУ. |
INTR | Вход маскируемых запросов на прерывание. Наличие запроса на этом входе анализируется в конце выполнения каждой команды |
TEST | Вход, проверяемый по команде WFT |
NMI | Вход немаскируемых запросов на прерывание |
RESET | Вход начальной установки микропроцессора |
CLK | Вход для подачи тактовых импульсов |
MN/MX | Вход для подачи сигнала переключения минимального/максимального режима. |
Минимальный режим | |
INTA | Подтверждение прерывания, выходной сигнал стробирующий ввод информации в МП из источника прерывания, вызвавшего переход в режим прерывания |
ALE | Строб адреса, выходной сигнал, стробирующий в такте Т1 передачу адресной информации с шин МП AD0 .. AD15 на другие элементы системы |
DEN | Разрешение обмена данными, выходной сигнал, управляющий выдачей информации из шинных формирователей при выполнении команд чтения/записи. |
DT/R | Ввод/вывод данных, выходной сигнал, указывающий на направление передачи. 1 – МП выдает информацию, 0 – МП принимает данные. |
M/IO | Память/внешнее устройство, выходной сигнал отличающий передачу данных для памяти или для внешнего устройства. |
WR | Запись, выходной сигнал указывающий на то, что МП выдает информацию для записи в память/ВУ. |
HLDA | Разрешение прямого доступа, подтверждение захвата шин МП внешним устройством. |
HOLD | Запрос прямого доступа (захвата шины) |
Максимальный режим | |
QS0, QS1 | Состояние очереди команд |
S0 .. S2 |
Тип цикла обмена, указывает на одну из возможных ситуаций: 000 – признак INTA 001 – ввод информации с ВУ 010 – вывод данных на ВУ 011 – останов 100 – выборка команды 101 – чтение из памяти 110 – запись в память |
LOСK | Сигнал блокировки, индицирующий, что другое устройство не может занять системную магистраль (запрет на захват системной шины) |
RQ/GT0, RQ/GT1 | Запрос/разрешение доступа к шине |
Шинные циклы К1810ВМ86
В максимальном режиме, управляющие сигналы системной шины вырабатываются системным контроллером по сигналам состояния процессора. Все сигналы управления (кроме ALE) активны по низкому уровню, что дает возможность раздельно управлять шиной несколькими устройствами.
Для обращения к устройствам ввода/вывода процессор имеет отдельные инструкции IN и OUT, результатом выполнения которых является формирование шинных сигналов IORD и IOWR. В циклах ввода/вывода используют только младшие 16 бит шины адреса, что позволяет адресовать до 64кбайт регистров ввода/вывода. Адрес устройства задается либо в команде, либо берется из регистра DX.
Циклы обращения к портам отличаются от циклов памяти использованием шины адреса. При обращении к портам линии адреса А16..А19 всегда содержат 0, а линии А8..А15 содержат старший байт адреса, только при косвенной адресации через регистр DX. При обращении по непосредственному адресу линии А8..А15 содержат 0.
Цикл подтверждения прерывания аналогичен циклу чтения порта но вместо сигнала IORD, активен сигнал INTA, а состояние шины адреса процессором в это время не управляется.
САМОСТОЯТЕЛЬНО
Организация систем ввода-вывода.
Ввод-вывод по прерываниям.
Программный ввод-вывод.
Прямой доступ памяти.
Контроллер прямого доступа памяти.
Прерывания.
Назначение и типы прерываний.
Механизм обработки программный прерываний.
Механизм обработки аппаратных прерываний.
Контроллер прерываний.
Память.
Сегментная организация памяти.
Виды памяти. ОЗУ. ПЗУ.
Типы ОЗУ: статическая память, динамическая память.
Типы ПЗУ.
Иерархия памяти.
КЭШ память.
Принципы действия КЭШ памяти.
Организация КЭШ памяти.
Распределение адресного пространства.
Новые виды памяти.
Построение вычислительных систем.
Организация аппарата программного автомата.
Способы повышения производительности ЭВМ.
Многомашинные и мультипроцессорные ВС.
Мультипрограммные ВС.
Тенденции развития ВС и средств ВТ.
Новые виды памяти.
FeRAM
Ферроэлектрическая память -- Ferroelectric RAM (FeRAM), это энергонезависимый тип памяти, аналогичный Flash памяти, что означает возможность хранения данных без использования источников энергии. Чипы FeRAM имеют маленькую емкость, на уровне килобит, но производство 1 Мбит чипов FeRAM уже не за горами, этим занимается компания NEC.
DRDRAM
Технология памяти Rambus основной архитектурой для изготовления системной памяти персональных компьютеров, в результате чего с 1999 года начнется вытеснение с этого рынка памяти типа SDRAM. Зная возможности Intel, можно с большой долей уверенности сказать, что так оно и будет. Специалисты корпорация Intel опробовали различные технологии памяти типа DRAM, прежде чем остановить свой выбор на технологии Rambus. Intel лицензировала архитектуру RDRAM у компании Rambus, после чего обе фирмы начали совместные разработки по созданию нового типа памяти, получившего наименование DRDRAM (Direct RDRAM). Кстати, компания Rambus выдала лицензии на свою технологию изготовления памяти семи крупнейшим производителям чипов DRAM и около 15 производителям контроллеров. Результатом выбора корпорацией Intel технологии Rambus может стать появление более быстрой и более совершенной памяти, которая будет применятся повсеместно.
DDR SDRAM
Новый тип памяти DDR SDRAM (Double Data Rate SDRAM), появился в следствии улучшений архитектуры SDRAM, поэтому другое название этого типа памяти - SDRAM II. Лидерство в разработке этого типа памяти принадлежит корпорации Samsung. В настоящее время многие крупные производители чипов памяти заявили о намерении продвигать эту архитектуру. Однако, в свете того, что Intel собирается продвигать другую архитектуру памяти - DRDRAM, будущее DDR SDRAM представляется туманным.
Память типа DDR SDRAM может передавать и принимать данные по восходящему и нисходящему уровню сигнала шины, в отличие от обычной памяти типа SDRAM, которая передает данные только по восходящему уровню сигнала. При этом команды и адреса в DDR SDRAM все равно передаются по верхнему фронту сигнала. Память типа DDR SDRAM имеет большую ширину полосы пропускания, но только в случае передачи длинных пакетов данных. Максимальная величина ширины полосы пропускания DDR SDRAM может достигать 1.6 Гб/сек при частоте шины 100MHz.
Осенью 1998 компания Fujitsu Microelectronics представит первые образцы модулей DIMM, созданных по технологии DDR SDRAM. Работает эта память на частоте 125 Мгц, с пропускной способностью около 200 миллионов операций в секунду, что примерно соответствует DRDRAM. При всех своих достоинствах, эта технология прекрасно работает с нынешними машинами, являясь эволюционным развитием DRAM, в отличие от совершенно новой технологии Rambus, для которой опять понадобятся новые чипсеты системных плат и т.д.
ESDRAM
Enhanced SDRAM (ESDRAM - улучшенная SDRAM) -- более быстрая версия SDRAM, сделанная в соответствии со стандартом JEDEC компанией Enhanced Memory Systems (EMS). С точки зрения времени доступа производительность ESDRAM в два раза выше по сравнению со стандартной SDRAM. В большинстве приложений ESDRAM, благодаря более быстрому времени доступа к массиву SDRAM и наличию кэша, обеспечивает даже большую производительность, чем DDR SDRAM.
Более высокая скорость работы ESDRAM достигается за счет дополнительных функций, которые используются в архитектуре этой памяти. ESDRAM имеет строку кэш-регистров (SRAM), в которых хранятся данные, к которым уже было обращение. Доступ к данным в строке кэша осуществляется быстрее, чем к ячейкам SDRAM, со скоростью 12 ns, т.к. не требуется обращаться к данным в строке через адрес в колонке. При этом скорость работы ячеек ESDRAM составляет 22 ns в отличие от стандартной скорости работы ячеек SDRAM, имеющей значения 50 - 60 ns.
При этом стоит заметить, что память ESDRAM полностью совместима со стандартной памятью JEDEC SDRAM на уровне компонентов и модулей, по количеству контактов и функциональности. Однако, чтобы использовать все преимущества этого типа памяти, необходимо использовать специальный контроллер (чипсет).
Увеличение производительности при использовании ESDRAM достигается за счет применения двухбанковой архитектуры, которая состоит из массива SDRAM и SRAM строчных регистров (кэш). Строчные регистры вместе с быстрым массивом SDRAM обеспечивают более быстрый доступ для чтения и записи данных по сравнению со стандартной SDRAM. ESDRAM может работать в режиме "упреждающего обращения" к массиву SDRAM, в результате следующий цикл записи или чтения может начаться в момент, когда выполнение текущего цикла не завершено. Возможность использовать такой режим напрямую зависит от центрального процессора, управляющего работой конвейера адресации.
С точки зрения применения в качестве системной (оперативной) памяти компьютера чипсет VCS-164 (Polaris) компании VLSI Technology поддерживает ESDRAM, правда, этот чипсет рассчитан для применения в системах на базе процессора Digital Alpha. ESDRAM полностью соответствует спецификации Intel PC-100 SDRAM, и соответственно, совместима с чипсетами Intel 440BX и Via Technologies MVP-3.
FCRAM
Fast Cycle Random Access Memory (FCRAM). Разработчик этого типа памяти - компания Fujitsu. В основу этого типа памяти легла принципиально иная концепция по сравнению с DRAM. Время выполнения цикла соответствует всего 20нс, т.е. в 3-4 раза меньше, чем у нынешних модулей DRAM. Это достигнуто благодаря двум принципиальным моментам. Во-первых, в отличие от современных чипов памяти, где сначала выясняется адрес строки (RAS), а потом, после некоторой задержки, адрес столбца (CAS), где находится нужная ячейка, в FCRAM мгновенно выясняются обе координаты. Во-вторых, существующая память типа DRAM имеет время выполнения цикла 70нс, из-за того, что после выполнения каждой операции над ячейкой должна пройти команда сброса. В FCRAM же встроена цепь автоматического сброса, благодаря чему возможна конвейерная обработка команд, где следующая команда начинает выполняться еще до окончания выполнения предыдущей. Итог - время выполнения цикла - 20нс. В результате мы получаем очень интересный гибрид. По скорости работы FCRAM более напоминает SRAM, а по объему - обычную память DRAM.
MRAM
MRAM - Magnetic random access memory. Разработчик - компания Toshiba. Уже есть пробный образец основной структуры чипа MRAM, воплощающего в себе новую технологию памяти, потенциально способную превзойти существующие типы DRAM и по скорости, и по объему, и по энергопотреблению. Уже этот тестовый образец демонстрирует выдающиеся скоростные качества - цикл чтения занимает всего 6 нс.
Согласно заявлению компании, технология хранения информации в чипе MRAM заключается в создании элемента с мелкими частицами платины и кобальта, находящихся между двумя магнитными слоями. Запись и чтение происходят путем изменения магнитной активности в контуре.