Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Voprosy_dlya_Internet_zanyatia_po_teme_vnutrenn...doc
Скачиваний:
8
Добавлен:
21.09.2019
Размер:
301.06 Кб
Скачать

Статья 3. Регистры процессора

В статье 1 при описании приведенной там программы упоминались регистры процессора, в частности, сегментные и общего назначения. Регистры процессора являются важнейшим инструментом программиста (между прочим, не только на языке ассемблера, но и на языках высокого уровня), и необходимо иметь четкое представление о составе регистров процессора, их названиях и применении. В примере 1.1 в явной форме использовались лишь три регистра процессора — AX (и его старшая половина AH), DS и DX; по мере чтения книги вы столкнетесь с примерами использования остальных регистров. Однако для того, чтобы читатель мог получить общее представление об этом важном средстве, ниже дан краткий обзор всей системы регистров процессора. Если в этом обзоре вам встретятся незнакомые понятия или неясные места — не огорчайтесь; в последующих статьях они будут описаны более подробно.

Строго говоря, приведенное ниже описание относится только к процессорам 8086 и 80286, для которых были характерны 16-разрядные регистры. В современных процессорах типа Pentium почти все регистры 32-разрядные, что существенно увеличивает возможности компьютера. Однако младшие половины регистров этих процессоров совпадают и по названиям, и по назначению с 16-разрядными регистрами процессора 8086. Поэтому программы, написанные для выполнения под управлением MS-DOS, то есть для 16-разрядного процессора, прекрасно работают и на 32-разрядном, хотя и не используют все его возможности. Поначалу мы ограничимся 16-разрядной архитектурой; особенности современных 32-разрядных процессоров будут описаны позже.

Процессор содержит двенадцать 16-разрядных программно-адресуемых регистров, которые принято объединять в три группы: регистры данных, регистры-указатели и сегментные регистры. Кроме того, в состав процессора входят счетчик команд и регистр флагов (рис. 3.1).

Рис. 3.1. Регистры процессора

В группу регистров данных включаются регистры AX, BX, CX и DX. Программист может использовать их по своему усмотрению для временного хранения любых объектов (данных или адресов) и выполнения над ними требуемых операций. При этом регистры допускают независимое обращение к старшим (AH, BH, CH и DH) и младшим (AL, BL, CL и DL) половинам. Так команда

mov BL,AH

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

Индексные регистры SI и DI так же, как и регистры данных, могут использоваться произвольным образом. Однако их основное назначение — хранить индексы (смещения) относительно некоторой базы (т.е. начала массива) при выборке операндов из памяти. Адрес базы при этом обычно находится в одном из базовых регистров (BX или BP). Примеры такого рода будут приведены ниже.

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

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

Регистры SI, DI, BP и SP, в отличие от регистров данных, не допускают побайтовую адресацию.

Четыре сегментных регистра CS, DS, ES и SS хранят начальные адреса сегментов программы и, тем самым, обеспечивают возможность обращения к этим сегментам.

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

Указатель команд IP «следит» за ходом выполнения программы, указывая в каждый момент относительный адрес команды, следующей за исполняемой. Регистр IP программно недоступен (IP — это просто его сокращенное название, а не мнемоническое обозначение, используемое в языке программирования); наращивание адреса в нем выполняет микропроцессор, учитывая при этом длину текущей команды.

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

Рис. 3.2. Регистр флагов

Флаг переноса CF (Carry Flag) индицирует перенос или заем при выполнении арифметических операций, а также служит индикатором ошибки при обращении к системным функциям.

Флаг паритета PF (Parity Flag) устанавливается в 1, если младшие 8 бит результата операции содержат четное число двоичных единиц.

Флаг вспомогательного переноса AF (Auxiliary Flag) используется в операциях над упакованными двоично-десятичными числами. Он индицирует перенос или заем из старшей тетрады (бита 4).

Флаг нуля ZF (Zero Flag) устанавливается в 1, если результат операции равен нулю.

Флаг знака SF (Sign Flag) показывает знак результата операции, устанавливаясь в 1 при отрицательном результате.

Флаг переполнения OF (Overflow Flag) фиксирует переполнение, т.е. выход результата операции за пределы допустимого для данного процессора диапазона значений.

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

dec AX

содержимое AX станет равно 0, и процессор сразу отметит этот факт, установив в регистре флагов бит ZF (флаг нуля). Если попытаться сложить два больших числа, например, 58000 и 61000, то установится флаг переноса CF, так как число 119000, получающееся в результате сложения, должно занять больше двоичных разрядов, чем помещается в регистрах или ячейках памяти, и возникает «перенос» старшего бита этого числа в бит CF регистра флагов.

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

jz zero

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

jnc okey

выполнит переход на метку okey, если предыдущая команда сбросила флаг переноса CF (или оставила его в сброшенном состоянии).

Управляющий флаг трассировки TF (Trace Flag) используется в отладчиках для осуществления пошагового выполнения программы. Если TF = 1, то после выполнения каждой команды процессор реализует процедуру прерывания 1 (через вектор прерывания с номером 1).

Управляющий флаг разрешения прерываний IF (Interrupt Flag) разрешает (если равен 1) или запрещает (если равен 0) процессору реагировать на прерывания от внешних устройств.

Управляющий флаг направления DF (Direction Flag) используется особой группой команд, предназначенных для обработки строк. Если DF = 0, строка обрабатывается в прямом направлении, от меньших адресов к большим; если DF = 1, обработка строки идет в обратном направлении.

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

Вернемся к примеру 1.1. Для того, чтобы инициализировать сегментный регистр DS сегментным адресом text нашего (единственного) сегмента, значение text загружается сначала в регистр общего назначения AX, а из него — в сегментный регистр DS. В принципе в качестве «перевалочного пункта» вместо регистра AX можно взять любой другой (например, BX или SI), однако некоторым трансляторам это может не понравиться, так что лучше все-таки использовать AX.

В предложении 5 в регистр AH заносится номер функции DOS, реализующей вывод на экран строки текста. DOS, получив управление с помощью команды int 21h, определяет номер требуемой функции именно по содержимому регистра AH, поэтому никаким другим регистром здесь воспользоваться нельзя. Функция DOS для вывода строки извлекает адрес выводимой строки из регистра DX, поэтому в строке 6 использование регистра DX также предопределено. В действительности дело обстоит сложнее. Функция 09h предполагает, что строка с выводимым текстом находится в сегменте, на который указывает вполне определенный сегментный регистр, а именно регистр DS. Поэтому перед вызовом функции 09h необходимо настроить этот регистр, что мы и сделали в предыдущих предложениях программы. Сведения о том, какие регистры требуется настроить для выполнения той или иной функции DOS, можно почерпнуть из справочника по функциям DOS, без которого, таким образом, практически невозможно писать программы с обращениями к системным средствам.

В предложениях 8...10 осуществляется вызов системной функции 4Ch, служащей для завершения текущей программы. По-прежнему номер функции заносится в регистр AH; кроме этого, в AL помещается код завершения программы, который в нашем примере равен 0.

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