Лекции 1 часть Баула (1110626), страница 6
Текст из файла (страница 6)
Компьютеры, архитектура которых ориентирована на какую-то одну предметную область, называются специализированными, в отличие от универсальных ЭВМ, которые более или менее успешно можно использовать во всех предметных областях. Мы в нашем курсе будем изучать архитектуру только универсальных ЭВМ.
Говорят, что компьютеры образуют семейство, если выполняются следующие требования:
-
одновременно выпускаются и используются несколько моделей семейства с различными производительностью и ценой (моделями называются компьютеры-члены семейства);
-
модели обладают программной совместимостью:
-
снизу-вверх – старшие модели поддерживают все команды младших (любая программа, написанная для младшей модели, безошибочно выполняется и на старшей);
-
сверху-вниз – на младших моделях выполняются программы, написанные для старших, если выполнены условия:
-
наличие у младшей модели достаточного количества ресурсов (например, памяти);
-
программа состоит только из поддерживаемых младшей моделью команд;
-
присутствует унификация устройств, то есть их аппаратная совместимость между моделями (например, печатающее устройство для младшей модели должно работать и на старшей);
-
модели организованы по принципу модульности, что позволяет в определённых пределах расширять возможности ЭВМ, увеличивая, например, объём памяти или повышая быстродействие центрального процессора;
-
стандартизировано системное программное обеспечение.
Большинство выпускаемых в наше время ЭВМ содержатся в каких-либо семействах. В нашем курсе для упрощения изложения будут рассматриваться в основном младшие модели семейства ЭВМ компании Intel. Соответственно все примеры программ должны выполняться для всех моделей этого семейства, поэтому мы ограничимся лишь архитектурой и системой команд самой младшей модели этого семейства [9].
Архитектура младшей модели семейства Intel
Память
Архитектура рассматриваемого компьютера является дробноадресной, поэтому адресуемая память состоит из регистровой и основной памяти. В младшей модели семейства основная память имеет объём 220 ячеек по 8 бит каждая.
Форматы данных
-
Целые числа.
Целые числа могут занимать 8 бит (короткое целое), 16 бит (длинное целое) и 32 бита (сверхдлинное целое). Длинное целое принято называть машинным словом (не путать с машинным словом в Учебной Машине!).
Как видим, в этой архитектуре есть многообразие форматов целых цисел, что позволяет писать более компактные программы. Для других архитектур это может оказаться несущественно, например, в некоторых современных супер-ЭВМ идёт работа с малым количеством целых чисел, поэтому вводится только один формат – сверхдлинное целое.
-
Символьные данные.
В качестве символов используются короткие целые числа, которые трактуются как неотрицательные (беззнаковые) числа, задающие номер символа в некотором алфавите. Заметим, что как таковой символьный тип данных (в смысле Паскаля) в Ассемблере отсутствует, а запись 'A' обозначает не символьный тип данных, а эквивалентна выражению языка Паскаль Ord('A').
-
Массивы (строки).
Массивы могут состоять из коротких или длинных целых чисел. Массив коротких целых чисел может рассматриваться как символьная строка. В машинном языке присутствуют команды для обработки элементов таких массивов, если такую команду поставить в цикл, то образуются удобное средство для работы с массивами.
-
Вещественные числа.
Чаще всего используются три формата вещественных чисел: короткие, длинные и сверхдлинные вещественные. Стоит отметить следующий важный факт. Если целые числа в различных ЭВМ по чисто историческим причинам имеют разное внутреннее представление, то на момент появления вещественных чисел уже существовал определённый стандарт и почти все современные машины этого стандарта придерживаются.
Рассмотрим представление короткого вещественного числа в этом стандарте
| E | M |
1 бит | 8 бит | 23 бита |
В отличие от целых, в представлении вещественных чисел используется симметричная числовая ось, то есть для любого положительного числа найдётся соответствующее ему отрицательное, и наоборот. Первый бит числа определяет его знак (знак «плюс» кодируется нулём, «минус» – единицей).
Остальная биты, отведённые под хранение вещественного числа, разбивается на две части: машинный порядок E и мантиссу M, которая по модулю меньше единицы. Каждое представимое вещественное число A (кроме числа 0.0) может быть записано в виде: A=1.M*2E–127. Такие вещественные числа называются нормализованными: первый сомножитель удовлетворяет неравенству 1.0 1.M < 2.0. Нулевое число представляется нулями во всех позициях, за исключением, быть может, первой.
Таков формат короткого вещественного числа. Согласно его виду, E изменяется от 0 до 255, следовательно диапазон порядков коротких вещественных чисел равен 2–127..2128 10–38..1038. Как и для целых чисел, машинное представление которых мы рассмотрим чуть позже, число представимых вещественных чисел конечно.
Некоторые комбинации нулей и единиц в памяти, отведённой под вещественное число, собственно числа не задают, а используются для служебных целей. В частности, E=255 обозначает специальное значение "не число" (not a number). При попытке производить арифметические операции над такими числами возникает аварийная ситуация. Например, значение "не число" может быть присвоено вещественной переменной при её порождении, если эта переменная не имеет начального значения (как говорят, не инициализирована). Такой приём позволяет избежать тяжёлых семантических ошибок, которые могут возникать при работе с неинициализированными переменными.
Отметим ещё две специальные комбинации нулей и единиц, которые будем обозначать . Эти значения присваиваются результату операции с вещественными числами, если этот результат не равен нулю, не непредставим в виде вещественного числа, то есть меньше самого маленького представимого положительного вещественного числа и больше самого большого отрицательного.
Аналогично существуют комбинации битов, задающие специальные значения . Эти значения выдаются в качестве результата, если этот результат такой болькой по абсолютной величине, что непредставим среди множества машинных вещественных чисел.
Центральный процессор "разумно" (по крайней мере с точки зрения математика) производит арифметические операции над такими "числами". Например, пусть A любое представимое вещественное число, тогда
A = A; * A = ; A * = ; и т.д.
При изучении архитектуры ЭВМ вещественные числа не будут представлять для нас большого интереса и поэтому (а также из-за недостатка времени) операции над вещественными числами мы изучать не будем.
Целые числа
Каждое хранимое в памяти целое число может трактоваться программистом как знаковое и беззнаковое (неотрицательное). По внешнему виду невозможно определить, какое число храниться в определённом месте памяти, только сам программист может знать, как от рассматривает это число. Таким образом, определены две машинные системы счисления, для представления знаковых и беззнаковых чисел соответственно.
Беззнаковые (неотрицательные) числа представляются в уже известной Вам двоичной системе счисления, такое представление называется прямым кодом неотрицательного числа. Например, десятичное число 13, хранимое в одном байте, будет записано как прямой код 00001101.
Если инвертировать прямой код (т.е. заменить все "1" на "0", а все "0" на "1"), то получим так называемый обратный код числа. Например, обратный код числа 13 равен 11110010.
Для представления отрицательных знаковых чисел используется так называемый дополнительный код. Например, получим дополнительный код числа –13.
Прямой код = 00001101
Обратный код = 11110010
Дополнительный код = 11110011
Итак, в знаковой системе счисления отрицательные числа представляются в дополнительном коде, а неотрицательные – в прямом коде. Заметим, что при знаковой трактовке целых чисел крайний правый бит определяет знак числа ("1" для отрицательных чисел). Этот бит называется знаковым битом целого числа.
Процесс перехода из прямого кода в дополнительный и обратно с технической точки зрения очень прост и может быть легко реализован в центральном процессоре.
Очень важно понять, что все арифметические операции над знаковыми и беззнаковыми целыми числами производятся абсолютно по одинаковым алгоритмам, что естественно, потому что центральный процессор "не знает", какие это числа "на самом деле". В то же время, с точки зрения программиста, результаты таких операций могут быть разными для знаковых и беззнаковых чисел.
Рассмотрим примеры сложения двух чисел длиной в байт. В первом столбике записано внутреннее двоичное представление чисел, а во втором и третьем – беззнаковое и знаковое десятичное представления этих же чисел.
-
Пример 1.
Б/з. | Зн. | |
11111100 | 252 | –4 |
00000101 | 5 | 5 |
1|00000001 | 1 | 1 |
Из этого примера видно, что для знаковой трактовки чисел операция сложения выполнена правильно, а при рассмотрении чисел как беззнаковые результат будет неправильным, так как мы получим девятизначное двоичное число, не "умещающееся" в один байт. Так как центральный процессор "не знает", как программист будет трактовать складываемые числа, то от "на всякий случай" сигнализирует о том, что при сложении беззнаковых чисел произошла ошибка. Для обозначения таких (и некоторых других) ситуаций в архитектуре введено понятие флагов. Каждый флаг занимает один бит в специальном регистре флагов (FLAGS). В данном случае флаг CF (carry flag) примет значение, равное единице (иногда говорят – флаг поднят). Рассматривая результат в знаковых числах, мы получили правильный ответ, в связи с чем соответствующий флаг OF (overflow flag) будет положен равным нулю (опущен).
-
Пример 2.
Б/з. | Зн. | |
01111001 | 121 | 121 |
00001011 | 11 | 11 |
10000100 | 132 | -124 |
В данном примере ошибка будет, наоборот, в случае со знаковой трактовкой складываемых чисел, поэтому флаги CF и OF принимают соответственно значения 0 и 1.
-
Пример 3.
11110110 | 246 | –10 |
10001001 | 137 | –119 |
101111111 | 383 | +127 |
В данном случае результат будет ошибочен как при беззнаковой, так и при знаковой трактовке складываемых чисел. Содержимое флагов: CF = OF = 1.
Представление отрицательных чисел в дополнительном коде не очень удобно для программистов, однако позволяет существенно упростить арифметико-логическое устройство. Заметим, например, что вычитание можно выполнять как сложение с дополнительным кодом числа.
Сегментация памяти
Память нашей ЭВМ имеет уже знакомую нам сегментную организацию. В любой момент времени для младшей модели определены четыре сегмента (хотя для старших моделей число сегментов может быть и больше). Это означает, что есть четыре сегментных регистра, которые указывают на определённые области памяти. Извлекать из памяти числа или команды можно только относительно одного из них этих регистров. Таким образом, физический адрес вычисляется по формуле A := (B + d) mod 220, где B – база, а d – смещение. Физический адрес берётся по модулю 220, чтобы он не вышел за максимальный адрес памяти.
В качестве мнемонических обозначений сегментных регистров выбраны следующие: кодовый сегментный регистр (CS), сегментный регистр данных (DS), сегментный регистр стека (SS) и дополнительный сегментный регистр (ES). Каждый из них может адресовать сегмент памяти длиной до 216 байт (напомним, что вся память состоит из 220 ячеек). Стоит отметить, что сегментные регистры являются специализированными, предназначенными только для хранения адресов сегментов, поэтому арифметические операции над их содержимым не предусмотрены. Так как адрес в приведённой формуле берётся по модулю 220, очевидно, что память «замкнута в кольцо». Таким образом, в одном сегменте могут находиться ячейки с самыми большими и самыми маленькими адресами основной памяти.
Мнемонические обозначения регистров
В силу того, что в ЭВМ все регистры имеют безликие адреса, аналогичные ячейкам основной памяти, программисты предпочитают использовать мнемонические обозначения регистров. Регистры общего назначения, каждый из которых может складывать, вычитать и просто хранить данные, а некоторые – умножать и делить, обозначают следующими именами: AX, BX, CX, DX. Для обеспечения многообразия форматов данных каждый из них разбит на две части по 8 бит каждая (биты нумеруются немного непривычно справа-налево, начиная с нуля):
15 | 7 | 0 | ||||
AX | AH | AL | ||||
BX | BH | BL | ||||
CX | CH | CL | ||||
DX | DH | DL | ||||
16 бит |
Каждый из регистров AH, AL, BH, BL, CH, CL, DH и DL может быть использован как самостоятельный регистр, на которых возможно выполнять операции сложения и вычитания.
Существуют также четыре регистра SI, DI, SP и BP, которые также могут использоваться для проведения сложения и вычитания, но уже не делятся на половинки:
15 0 | |
SI | |
DI | |
SP | |
BP | |
16 бит |
Кроме перечисленных выше регистров программист имеет дело с регистром IP (instruction pointer), который называется счётчиком адреса и содержит адрес (точнее, смещение относительно сегментного регистра CS) следующей исполняемой команды.
16 бит | |
IP |
И, наконец, как уже упоминалось, архитектурой изучаемой ЭВМ предусмотрен регистр флагов FLAGS. Он содержит шестнадцать одноразрядных флагов – например, ранее упоминавшиеся флаги CF и OF.
16 бит | |||||
FLAGS | … | CF | … | OF | … |
Все биты в регистрах пронумерованы: в шестнадцатибитных – от 0 до 15, в восьмибитных – от 0 до 7.