Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы МП.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
2.07 Mб
Скачать

Арифметические действия в двоичной и десятичной

системах счисления [5, 15]

Числа в ЭВМ представляются в двоичной форме, в этой же форме выполняются и все 4 арифметических действия. Правила работы многоразрядных чисел в двоичной системе точно такие же, как и в десятичной, только 10 заменяется на 2.

Рассмотрим процесс сложения двух чисел:

6

+

543

2481

9024

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

  1. 3 плюс 1 равно 4;

  2. 4 плюс 8 равно 12. Записываем 2 и переносим 1,

  3. 1 плюс 5 плюс 4 равно 10. Записываем 0, переносим 1;

  4. 1 плюс 6 плюс 2 равно 9.

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

0+0 = 0 0−0 = 0 0×0 = 0

0+1 = 1 1−0 = 1 0×1 = 0

1+0 = 1 1−1 = 0 1×1 = 0

1+1 = 10 10−1 = 1 1×1 = 1

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

+

1010

110

10000

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

  1. 0 плюс 0 равно 0;

  2. 1 плюс 1 равно 10 (напоминаю, что 2 в двоичной системе представляется как 10). Записываем 0 и переносим 1;

  3. 1 плюс 0 плюс 1 равно 10. Записываем 0 и переносим 1;

  4. 1 плюс 1 равно 10. Поскольку это последнее действие, записываем 10. Точно так же, как сделали бы это в десятичной системе.

В примере стрелками (↓) показаны единицы переноса в старшие разряды. Для проверки правильности результата выполним следующее десятичное сложение: 10+6 = 16;

Преобразовав все эти три числа в двоичной форме, вместо 10(10) получим

1010(2), вместо 6−110(2) и вместо 16−10000(2) .

Следует заметить, что десятичное число можно иногда спутать с двоичным.

Выполняя сложение 10+6 = 16, мы предполагаем, что число 10 десятичное, а не двоичное. Чтобы не было путаницы, можно число заключить в скобки и приписать ему в виде индекса основание системы счисления − 10, а не 2, тогда 10(2) обозначает двоичное число 10, а 10(10) – десятичное.

Правила вычитания также одинаковы в двоичной и десятичной системах счисления.

Рассмотрим пример вычитания 174 и 197:

1

97

174

23

В двоичной форме вычитание представлено в следующем виде:

1

1000101

10101110

00010111

где: 00010111 = (1×24) + (0×23) + (1×22) + (1×21) + (1×20) = 16+0 + 4 + 2 + 1 = = 23(10), что абсолютно верно. Проверить правильность можно обратным действием, то есть сложением:

0

+

0010111

10101110

11000101

Умножение двоичных чисел производится с использованием умножения и сложения.

Пример умножения 23,625 на 2,75:

где: 23,625(10) = (1×24) + (0×22) + (1×21) + (1×20) + (1×2−1) + (0×2−2) + (1×2−3) = = 10111,101(2) .

Число 275 переводится аналогичным способом:

×

10111,01

10,11

+

1011101

1011101

1011101

111111,111

Деление двоичных чисел происходит с использованием двоичных таблиц умножения и вычитания.

Пример деления 430 на 10

1

10101110 1010

1010 101011(2)

1101

1010

1111

1010

1010

1010

0

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

Двоичная система счисления [5, 15]

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

Состояние электронной схемы, в которой протекает электрический ток, условно кодируется – 1, а противоположное состояние – 0.

Можно кодировать состояние электронной схемы по уровню напряжения на ее входах или выходах: высокий уровень напряжения – 1, низкий уровень напряжения – 0.

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

Одно из устойчивых состояний элемента соответствует цифре 0, а другое – цифре 1. В этом отношении двоичная система счисления имеет преимущества перед остальными системами и поэтому оказывается очень удобной для ее применения в вычислительных машинах.

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

Так, число N может быть представлено в виде следующей суммы:

Где коэффициенты ai при степенях основания могут принимать только 2 значения: 0 или 1.

Двоичные числа – это числа, состоящие только из единиц и нулей.

Двоичные числа можно рассматривать как некоторый код, вроде кода для секретных сообщений. Так число 111 представляет собой код числа 7; 1001 есть код числа 9.

Обычные числа, такие как 7 или 9, называют десятичными числами. Известная нам все десятичная система позволяет выразить числовые значения с помощью нескольких цифр (разрядов). Так,

3456(10) = 3000 + 400 + 50 + 6 = (3×1000) + (4×100) + (5×10) + 6 =

= (3×103) + (4×102) + (5×101) + (6×100) = 3456(10)

где показатели степени 10 расположены в порядке убывания (вспомним, что 101 = 10 и 100 = 1).

Двоичная система отличается от десятичной тем, что основание 10 заменяется на основание 2. Так в двоичной системе:

1001(2) = (1×23) + (0×22) + (0×21) + (1×20) = (1×8) + (0×4) + (0×2) + (1×1) =

= 8 + 1 = 9(10)

В таблице 3 представлены 16 двоичных чисел (вместе с 0).

Таблица 3

Первые 16 двоичных чисел

Числа десятичные

Числа двоичные

0

0

1

01

2

10

3

11

4

100

5

101

6

110

7

111

8

1000

9

1001

10

1010

11

1011

12

1100

13

1101

14

1110

15

1111

16

10000

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

Например:

9 :2 = 4 остаток 1

4 :2 = 2 остаток 0

2 :2 = 1 остаток 0

1 :2 = 0 остаток 1

1 0 0 1

Таким образом, 9(10) = 1001(2), потому что

1001(2) = (1×23) + (0×22) + (0×21) + (1×20) = 8 + 1 = 9(10)

Существует более сложный способ преобразования числа из десятичной системы в двоичную.

Чтобы выполнить такое преобразование, мы должны найти наибольшую степень двух, которая не превышает преобразуемое число. Возьмем, например, число 1600. Наибольшая степень 2, не превышающая 1600, есть 1024 (см. табл. 4).

Таблица 4

Степени 2

X

2

0

1

1

2

2

4

3

8

4

16

5

32

6

64

7

128

8

256

9

512

10

1024

11

2048

12

4096

13

8192

14

16384

15

32768

16

65536

Рассмотрим теперь каждую степень 2 в последовательности от 1024 до 1. Будем по очереди вычитать их, следя за тем, чтобы результат не получился отрицательным. Каждый раз, когда вычитание степени 2 возможно, записываем 1 в двоичное число.

Каждый раз, когда вычитание степени 2 невозможно, записываем 0.

1

600 1

1024

576 1

512

64

(256) 0

64

(128) 0

64

64 1

0

(32) 0

0

(16) 0

0

(8) 0

0

(4) 0

0

(2) 0

0

(1) 0

Ответ: 11001000000(2) = 1600(10)

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

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

1024 512 256 128 64 32 16 8 4 2 1

1 1 0 0 1 0 0 0 0 0 0

1024 + 512 + 64 = 1600(10)

Двоичный разряд носит название БИТ (1 или 0). Так двоичное число 11001000000 занимает 11 БИТ.

Шестнадцатеричная система [5]

Вспомним, что 2 – это основание двоичной системы. Это означает, что при записи любого числа используются всего две цифры − 0 и 1 и степени 2. Аналогично 10 – основание десятичной системы. Например, 5(10) = 101(2). Имеются и другие системы с основаниями, отличными от 2 и 10. Чаще других используется шестнадцатеричная система счисления с основанием 16.

В шестнадцатеричной системе используются 16 цифр – 0, 1, 2, …, 9, A, B, C, D, E и F. Числа в шестнадцатеричной системе образуются так же, как и в десятичной, но вместо 10 используется 16. Так, если в десятичной системе мы имеем:

3 × 103

3456 = + 4 × 102 = 3 × 103 + 4 × 102 + 5 × 101 + 6 × 100 =

+ 5 × 101

+ 6 × 100

= 3000 + 400 + 50 + 6 = 3456(10), то в шестнадцатеричной системе:

3 × 162 3 × 4096 12288

3456 = + 4 × 162 = + 4 × 256 + 1024

+ 5 × 161 + 5 × 16 + 80

+ 6 × 160 + 6 + 6

13369

Стало быть: 3456(10) ≠ 13369(16) .

В дальнейшем нам потребуется только четыре первые степени:

16:161 = 16; 162 = 256; 163 = 4096 и 164 = 65536(10)

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

  1. делим двоичное число с правой стороны на группы по четыре бита;

  2. преобразуем каждую группу в шестнадцатеричную цифру.

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

1. Выражаем каждую шестнадцатеричную цифру в виде четырех битов

Таблица 5

Преобразование двоичных чисел в шестнадцатеричные и обратно

Двоичные 1000101011010010

1000 1010 1101 0010

8 А D 2

Шестнадцатеричное 8АD2

Шестнадцатеричное 8АD2

8 А D 2

1000 1010 1101 0010

Двоичные 1000101011010010

Двоичные

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

1010

1011

1100

1101

1110

1111

Шестнадцатеричные

0

1

2

3

4

5

6

7

8

9

A

B

C

D

E

F

Как видно из таб. 5, преобразовать двоичное число в шестнадцатеричное или наоборот весьма просто. Посмотрим, почему так. Возьмем двоичное число 1000101011010010, для него можно написать:

1000101011010010(2) = (1×215 + 0×214 + 0×213 + 0×212) + (1×211 + 0×210 + 1×29 +

+ 0×28) + (1×27 + 1×26 + 0×25 + 1×24) + (0×23 + 0×22 + 1×21 + 0×20) =

= 212 × (1×23 + 0×22 + 0×21 + 0×20) +

+ 28 × (1×23 + 0×22 + 1×21 + 0×20) +

+ 24 × (1×23 + 1×22 + 0×21 + 1×20) +

+ 22 × (0×23 + 0×22 + 1×21 + 0×20) =

= 212 × 8 + 28 × 10 + 24 × 13 + 20 × 2 =

= (24)3 × 8 + (24)2 × 10 + (24)1 × 13 + (24)0 × 2 =

= 163 ×8 + 162 × 10 + 161 × 13 + 160 × 2 = 8АD2(16) ,

то есть шестнадцатеричное число 8АD2.

Таким образом, при преобразовании используется то обстоятельство, что 16 является целой степенью 2.

Шестнадцатеричная система очень широко используется при программировании на машинном языке. Объясняется это тем, что работать с большими двоичными числами очень неудобно. Записывая, например, двоичное число 1011011101001000 легко ошибиться из-за большого количества единиц и нулей, лучше все двоичные числа записать в шестнадцатеричной форме, если только в силу каких-то причин не требуется анализ отдельных битов. Например, изменение значения самого левого бита в шестнадцатеричном числе С8 сделает из него 48, поскольку С8 — это двоичное 11001000, и изменение значения левого бита дает 01001000, что в шестнадцатеричной форме составляет 48.

Шестнадцатеричное сложение и вычитание [5]

Не только двоичная и десятичная, но и все подобные системы счисления имеют схожие правила сложения и вычитания. Шестнадцатеричная система отличается от десятичной только тем, что 10 надо заменить на 16, в остальном правила те же. Пусть надо сложить шестнадцатеричные числа:

В

+

785

2С84

Е409

Сложение выполняется справа налево следующим образом:

  1. 5 плюс 4 равно 9 (как в десятичной системе);

  2. 8 плюс 8 равно 10 (чему в десятичной системе соответствует 8 + 8 = 16). Записываем 0 и переносим 1;

  3. 7 плюс С равно 13 (в десятичной системе этому соответствует 7 + 12 = 19. 13 + 1 (от переноса) равно 14, записываем 4 и переносим 1;

  4. В плюс 2 равно D, плюс 1 от переноса – Е (в десятичной системе 11 + 2 + 1 = =14).

Рассмотрим теперь пример с вычитанием:

8

34Е

2Е5А

54F4

На этот раз процедура такова:

  1. Е минус А равно 4 (в десятичной форме 14 – 10 = 4);

  2. 4 минус 5 требует занять 1, после чего 14 минус 5 равно F (не 9 – будьте внимательны!) (в десятичной форме 14 − 5 превращается в 20 − 5, то есть 15, что представляет собой шестнадцатеричное F);

  3. 3 минус Е требует занять 1, получается 13 минус Е, однако 1 из этого разряда была занята, следовательно, остается 12 минус Е что равно 4 (в десятичной форме 18 – 14 = 4);

  4. 8 минус 2, а с учетом занятой 1 (единицы), 7 минус 2 равно 5, как и в десятичной форме.

Выполняя сложение шестнадцатеричных чисел, не забывайте, что перенос возникает, только если сумма превышает F. Так в десятичной системе 25 + 25 = 50, но в шестнадцатеричной 25 + 25 = 4А, а не 5А (5 + 5 = А) без всякого переноса).

Некоторые шестнадцатеричные числа, например В5 или DEF7, напоминают по виду имена переменных, и следует позаботиться о том, чтобы не возникало путаницы. Например, система LISA требует записи шестнадцатеричного числа В5 в виде $ В5, чтобы отличить его от переменной с именем В5. Другие системы, например, программа-монитор Эпл, предполагают, что все величины даются в шестнадцатеричной форме и знак $ оказывается не нужным (и даже незаконным). Большинство систем программирования на Бейсике не используют шестнадцатеричных чисел, и В5 в Бейсике всегда обозначает имя переменной, а не шестнадцатеричную константу.

Двоичные и шестнадцатеричные числа можно умножать и делить. Дроби, например 1/2 также можно выразить в двоичной или шестнадцатеричной форме.

Двоичные и шестнадцатеричные дроби [5]

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

Как мы вычисляем значение десятичной дроби .738. Оно, несомненно, равно 738/1000, но почему деление производится на 1000, а не на 100 или 10000? Потому что в числе 738 три цифры, а 103 есть 1000. Мы можем применить ту же идею к двоичным числам.

Так .101 представляет 5 (то есть .101 в двоичной системе) деленное на 8 (представляет собой 23, поскольку в числе 101 три цифры), другими словами .101 = 5/8. Число .101 называется двоичной дробью (по аналогии с десятичными дробями) (см. табл. 7). Точка .101 носит название двоичной точки (по аналогии с десятичной точкой).

Таблица 6

Двоичные и шестнадцатеричные дроби

Двоичные

Простые

16-ричные

.0

0

.0

.0001

1/16

.1

.001

1/8

.2

• А*

.0011

3/16

.3

.01

1/4

.4

.0101

5/16

.5

.011

3/8

.6

.0111

7/16

.7

.1

1/2

.8

.1001

9/16

.9

.101

5/8

.1011

11/16

.11

3/4

.1101

13/16

.D

.111

7/8

.E

.1111

15/16

.F

1.0

1

1.0

Нам понятно, что некоторые десятичные дроби являются конечными, а другие – нет. Так 3/4 = 0,75, потому что 3/4 = 75/100; но 1/3 представляет собой бесконечную десятичную дробь 0.3333... и т.д. (до бесконечности). То же относится к двоичным дробям, например, двоичная дробь 0.010101 и т.д. (до бесконечности) представляет собой 1/3.

Данную бесконечную десятичную дробь, например: .736736736 (и т.д. до бесконечности), можно преобразовать в простую дробь делением повторяющейся части (в данном случае 736) на 10D-1, где D – количество цифр в повторяющейся части. В данном случае мы получаем 736/999 (вспомним, что просто .736 представляет собой 736/1000).

Аналогичные правила применимы и к двоичным дробям: .01 = 1/4 (то есть 1 деленная на вторую степень двух, поскольку в .01 две цифры), а .01010101 (и т.д. до бесконечности) равно 1/3, поскольку 3 = 22 – 1.

Почему мы не можем представить 1/3 в ЭВМ в виде двух целых 1 и 3, а затем складывать, вычитать, умножать и делить дроби в соответствии с правилами, которые мы изучаем в начальной школе? Потому что нам пришлось бы постоянно сокращать получающиеся дроби, а эта операция требует очень много машинного времени. Кроме того, многие числа, с которыми нам надо работать, например, π не выражаются через простые дроби. Некоторые дроби, являющиеся конечными в десятичной системе, оказываются бесконечными в двоичной. Например, 3/16 представляет собой .0011 в двоичной системе, и согласно приведенному выше правилу 3 / (16-1) или 3/15, равно .001100110011 и т.д. (до бесконечности), но 3/15 после сокращения дает 1/5, чему в десятичной системе соответствует конечная дробь 0.2 (поскольку 1/5 = 2/10).

В дополнение к десятичным дробям вроде 0.75 в десятичной системе имеются и смешанные числа, например: 3.25, для которых характерно наличие и целой, и дробно частей. То же справедливо и по отношению и целой и дробной частям. То же справедливо и по отношению к двоичной системе, например 11.01 представляет собой двоичное представление 3.25.

Пусть теперь мы хотим представить 11.01 в виде 16-разрядной величины Мы можем договориться, что первые 10 разрядов нашей 16-разрядной величины отводится для целых чисел, за ними стоит двоичная точка, а за ней – 6 разрядов для дробной части. Тогда число 11.01 представляется в виде 0000000011.010000.

При использовании такого представления всегда возникает вопрос, где расположить двоичную точку. Если двоичная точка стоит после первых десяти разрядов, как в приведенном примере, то мы можем выразить числа от 0 (то есть 0000000000.000000) до 1023 63/64 (1111111111.111111).

Если этот диапазон слишком велик, мы можем поставить десятичную точку в другом месте, скажем, после первых 7 разрядов. Это даст нам представление чисел от 0 до (почти) 128, и увеличит количество возможных дробей с соседними числами.

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

0

+

110010000.110010

0011010110.100111

1001100111.011001

0

100111011.011100

0001001101.101100

0011101101.110000

выполняется как с 16-разрядными целыми числами. Это, однако, возможно, если двоичные точки «выравнены», в противном случае нам пришлось бы сдвигать одно или другое число для выравнивания двоичных точек.

Описанное представление чисел носит название представление с фиксированной точкой.

В представлении с фиксированной точкой отрицательные числа записываются в виде их дополнений до двух. В этом случае диапазон чисел в нашем примере (с двоичной точкой после 10 цифр становится от -512 (то есть 1000000000.000000) до 511 63/64 (то есть 0111111111.111111)).

Существуют также шестнадцатеричные дроби, содержащие шестнадцатеричные цифры (причем .8 = 1/2; .С = 3/4 и т.д.).

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

Многобайтовые величины и дополнение до двух [5]

Может показаться странным, что при использовании 8-разрядных ячеек мы сталкиваемся с трудностью, поскольку в них можно хранить лишь числа от 0 до 255. Мы не можем записать в такую ячейку большое число (больше 255) или отрицательное число (менее 0). Для хранения в ЭВМ больших и отрицательных чисел используются специальные приемы

Таблица 7

Дополнение до 2-х целых чисел

Десятичные

Двоичные

Шестнадцатеричные

-5

11111011

FB

-4

11111100

FC

-3

11111101

FD

-2

11111110

FE

-1

11111111

FF

0

00000000

00

1

00000001

01

2

00000010

02

3

00000011

03

4

00000100

04

5

00000101

05

Для хранения больших чисел можно использовать несколько ячеек для каждого числа. Если взять 2 ячейки, то диапазон записываемых чисел увеличится до 216 – 1, или 65535. Пусть одна ячейка содержит число р, а другая – число d, тогда обе ячейки вместе содержат число 256 p+d. Если же использовать более 2 ячеек, например, n ячеек, то появится возможность хранить любые числа от 0 до 28n – l. Если, например, n = 4, то 28n – 1 = 232 – 1, что превышает 4000000000.

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

Первый заключается в том, что самый левый разряд отводится под код знака: 0 означает положительное число, а 1 – отрицательное. В 8-разрядной ячейке 10000011 будет представлять – 3: первая 1 означает, что число отрицательное, а остальная часть содержимого ячейки, 0000011, представляет собой 3 (с 5-лидирующими нулями). Такая запись называется знаковым представлением в прямом коде. Сейчас такой способ представления не используется.

Другой способ представления отрицательных чисел напоминает работу электрического 3-разрядного счетчика, используемого во многих магнитофонах. При обратной перемотке ленты счетчик считает назад; после 000 счетчик показывает 999, затем 998 и т.д. Точно также, если мы будем вычитать, то после 00000000 будет 11111111, затем 11111110 и т.д. В результате 11111111 можно считать представлением – 1, 11111110 – представлением – 2 и т.д.

Полученные таким образом представления чисел от -5 до +5 в десятичной, двоичной и шестнадцатеричной форме приведены в табл. 7 .

Представление -Х можно найти, вычтя Х из двоичного 100000000. Так, например, десятичному -45 соответствует двоичное 101101. Вычтя это число из 100000000, получим 11010011. Легче вычесть Х из двоичного 11111111, а затем добавить 1 к результату (это эквивалентно, поскольку 11111111+1= 100000000). Таким образом, возможны два пути:

1

) 100000000 либо 2) 11111111

101101 00101101

+

11010011 11010010

1

11010011

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

Таким образом, использование системы представления дополнением до двух даст возможность записывать в d-разрядном регистре отрицательные числа – х, как дополнение х до двух, или 2d − x. Как и в случае знакового представления в прямом коде положительные числа начинаются с 0, отрицательные − с 1. Если d = 8, то самое большое число в рассматриваемом представлении равно 01111111 (десятичное 127), а самое маленькое –10000000 (десятичное –128). В общем случае диапазон представленных чисел заключен от до ; числа в этом диапазоне называются числами со знаком. Число 45 в системе представления дополнением до двух есть 00101101; число – 45 в системе представления дополнением до двух есть 11010011 (другими словами, это есть дополнение до двух числа 45). Дополнение до двух отрицательного числа находится точно также: к обратному коду числа прибавляется (не вычитается!) 1; так обратный код числа 11010011 есть 00101100, и после прибавления 1 получаем 00101101.

Система представления чисел дополнение до двух используется практически во всех современных ЭВМ. Она удобна тем, что операции сложения чисел со знаком и без знака, выполняются одинаково (рис. 13).

Беззнаковое

представление

Двоичное

п редставление

Знаковое

представление

+

+

+

3 0 0 0 0 0 0 1 1 3

251 1 1 1 1 1 0 1 1 (-5)

254 1 1 1 1 1 1 1 0 - 2

Рис. 13. Операции сложения чисел со знаком и без знака

Заметим, что если код 11111011 выражает число без знака, то он не может обозначать – 5 и должен, следовательно, рассматриваться как 251; если код выражает число со знаком, он не может обозначать 251 (вспомним, что числа со знаком лежат в диапазоне от – 128 до 127) и должен, следовательно, рассматриваться как –5. Мы часто используем двоичное число для обозначения двух различных чисел (в приведенном примере 11111011 обозначает и 251, и − 5), и, как видно из примера, никакой путаницы не возникает. Однако мы должны помнить, какого рода данные представляют наши двоичные числа, потому что нет никакого способа определить, что хранится в регистре или ячейке: число со знаком, число без знака или еще какое-то данное, хотя в языках высокого уровня, например в Лисп, такая проверка возможна, но используется специальный прием. Процессор 6502 может также выполнять вычисления с дробями, но этот вопрос будет рассмотрен позднее.

Действительные числа и представление с плавающей точкой [5]

Представление с фиксированной точкой, не позволяет работать с очень большими и очень маленькими числами (такими, как 6.061×1023 или 6.626×10-27), встречающимися в вычислениях. Для того чтобы на ЭВМ можно было обрабатывать действительные числа, обычно используется другое представление, называемое представлением с плавающей точкой.

В основе представления чисел с плавающей точкой лежит то, что в общем случае для определения действительного числа (например. 6.626×10-27) требуется следующая информация:

  1. знак (положительный или отрицательный);

  2. порядок (т.е. показатель степени десяти, в данном случае -27, хотя в формате числа с плавающей точкой в действительности используется степень двух или иногда 16, а не 10);

  3. мантисса (т.е. число 6.626, выраженное в виде правильной дроби), для чего число 6.626×10-27 мы должны записать в виде .6626×10-26. Полученная мантисса .6626 представляет собой правильную дробь.

Указанной информации достаточно, чтобы выразить действительное число, поэтому все, что нам осталось сделать – это задать формат числа. Существуют различные форматы чисел с плавающей точкой; ниже описан «короткий формат», используемый на больших ЭВМ фирмы IBM например, серии 4300:

    1. Каждое действительное число занимает 4 байта.

    2. Левый разряд первого байта является знаковым; 0 означает плюс, а 1 – минус, как и у целых чисел.

    3. Оставшаяся часть первого байта является порядком.

    4. Остальные 3 байта представляют собой мантиссу.

    5. Порядок представляет собой степень 16 (это необычно; в большинстве форматов чисел с плавающей точкой это степень 2).

    6. Мантисса рассматривается как 6-разрядная шестнадцатеричная дробь, в пределах от .100000 до .FFFFFF (если мантисса меньше .100000, мы используем соотношение .0ххххх×16n = ххххх0×16n-1, если нужно – многократно, чтобы нормализовать мантиссу, то есть привести ее к указанному диапазону).

    7. Порядок, находящийся в пределах от -64 до 63, смещают, прибавляя к нему 64; реализующая величина лежит в пределах от 0 до 127. Таким образом, порядок е в действительности представлен числом е + 64. (Это напоминает смещение напряжения в электронных цепях путем прибавления к нему постоянного положительного напряжения, так что при любых флуктуациях напряжение остается положительным.)

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

На рис. 14 показано представление чисел 2, 48, -228 и 1/512 в описанном выше формате с плавающей точкой. Обратите внимание, как значение порядка изменяет фактическое положение двоичной (или шестнадцатеричной) точки, которая «плавает» по мантиссе (в том числе «доплывая» иногда до самого левого или до самого правого края), что и дало название этому формату.

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

Знак Смещение 2. 0 0 0 0 0

0 1000001 0100 0000 0000 0000 0000 0000

Порядок Мантисса f = .200000

е = 1 (смещенное) (шестнадцатеричное)

Число = 16е × f = 161 × .2 = 2

Знак Смещение 3 0. 0 0 0 0

0 1000010 0011 0000 0000 0000 0000 0000

Порядок Мантисса f = .300000

е = 2 (смещенное) (шестнадцатеричное)

Число = 16е × f = 162 × .3 = 30 (шестнадцатеричное) = 48 (десятичное)

Знак Смещение −1 0 0 0 0 0 0 0

0 1001000 0001 0000 0000 0000 0000 0000

Порядок Мантисса f = .100000

е = 8 (смещенное) (шестнадцатеричное)

Число = -16е × f = -168 × .1 = -10000000 (шестнадцатеричное)

.0 0 8 0 0 0 0 0

Знак Смещение

0 0111110 1000 0000 0000 0000 0000 0000

Порядок Мантисса f = .800000

е = -2 (смещенное) (шестнадцатеричное)

Число = 16е × f = 16-2 × .8 = .008 (шестнадцатеричное) = 1/512 (десятичное)

Рис. 14. Представление действительных чисел в формате с плавающей точкой

Операции с плавающей точкой [5]

Пусть мы подучили несколько чисел, представленных в формате с плавающей точкой. Что нам с ними делать? Работая с процессором 6502, мы вызываем подпрограммы, чтобы складывать, вычитать, умножать или делить эти числа, преобразовывать их в целые и наоборот, вводить и выводить. Умножение и деление чисел с плавающей точкой в действительности проще сложения и вычитания. Число с плавающей точкой, характеризуемое знаком s, порядком е и мантиссой f, может быть представлена в виде s×be×f, где b – база (b = 16), a s – знак, который принимается равным 1 для положительных чисел и -1 для отрицательных. Произведение на равно , причем можно выразить как . Отсюда, для умножения двух чисел с плавающей точкой достаточно перемножить знаки, сложить порядки и перемножить мантиссы. Результат может оказаться не нормализованным – например, мантисса .3, умноженная на самое себя, дает .09. Однако если результат не нормализован, процедуру нормализации следует принимать только один раз.

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

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

+

+

=

235.9 235.9

2.359 2.359

238.259

И вообще, при сложении двух десятичных дробей мы должны сдвигать одну из них до тех пор, пока не выровняются их десятичные точки. Из рис. 14 видно, что двоичная точка в числе с плавающей точкой «переплывает» на одну позицию вправо каждый раз, когда порядок увеличивается на 1. Поэтому, если разность между порядками составляет z, перед сложением меньшее число надо сдвинуть на z позиций вправо – в данном случае на z шестнадцатеричных разрядов, или 4z двоичных. То же справедливо в случае операции вычитания.

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

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

.

532684

.532271

.000413

дает дробь с тремя лидирующими нулями, так что процедуру нормализации следует применить три раза

Не надо забывать, что числа с плавающей точкой лишь приблизительно описывают действительные числа, и последовательность операций с плавающей точкой может легко уменьшить точность. Это в особенности касается вычитания, хотя на первый взгляд вычитание может показаться точной операцией (см. пример выше). Если первая мантисса в этом примере изменится на единицу младшего разряда, результат становится равным .000412, или .412000×163, то есть изменится на 1000 (шестнадцатеричное), а совсем не на 1. Сложение, умножение и деление чисел с плавающей точкой могут давать ошибочные результаты, даже если сами складываемые, умножаемые или делимые числа вполне точны.

Регистры, ячейки и байты [5]

Представим себе, что ЭВМ содержит большое количество коробочек для хранения чисел. В каждую коробочку помещается 8 бит, поэтому она может содержать любое число от 00000000 до 11111111 (при этом любое число в любой момент времени). Существует два вида коробочек. Одни называются регистрами, рассмотрим только А, Х, У. Другие называются ячейки, и все ячейки вместе взятые, образуют основную или оперативную память. Максимальное количество ячеек (правда, без привлечения специальных технических средств) составляет 65536 или 216. Каждый регистр или ячейка может содержать любое 2-х разрядное шестнадцатеричное число от 00 до FF.FF(16) = 255(10), поэтому каждый регистр или ячейка может содержать любое десятичное число, не превышающее 255. Заметим, что 255 = 256 – 1 = 28 − 1. Число 28 представляет в двоичной системе 100000000, то есть 1(ед.), за которой следует восемь нулей, поскольку вычесть 1 (ед.) = 11111111. Таков принцип двоичной системы: если имеется n бит (у нас n = 8), то можно записать любое число от 0 до 2n – 1 (у нас до 28 – 1).

Ячейки оперативной (основной) памяти имеют номера, называемые адресами, отсчет которых начинается с нуля. Например, ячейка 0, и т.д.; к этим ячейкам можно обратиться по адресу 0, 1 и т.д. Максимально возможный адрес = 65535 или 216 – 1 , поскольку максимальное число ячеек взятых с адресом 0 составляет 65536. Таким образом, любой адрес в пределах от 0 до 216 – 1 можно записать с помощью 16 бит или в двух ячейках (рис. 16).

Сигналы выборки

ячеек памяти

ИМС с формиров.,

с 3-мя состояниями

Ячейки памяти

(триггеры)

1

D Q

Входы

сигналов

выбора

Ø

0

1

D Q

1

D Q

2

D Q

3

D Q

4

Данные

D Q

5

D Q

6

D Q

7

Рис. 15. Выбор ячеки 5 (1 Ø 12); запись в ОЗУ

0

0

0

0

0

1

1

0

0

1

0

0

0

0

0

0

Рис. 16. 2-х байтовая ячейка

7 0 7 0

0

0

0

0

0

1

1

1

1

0

0

0

0

0

0

0

Регистр А Регистр Х

Рис. 17.

Пример: число 1600(10) = 11001000000. Теперь разместим их в двух ячейках (регистр А и X) (рис. 17). В регистре А число 6(10) , в регистра Х – 64(10). Bместе регистры содержат 1600, занимающее 16 двоичных разряда Для получения этого числа надо вычислить значение выражения: 256 × А + Х:

256 × 6 + 64 = 1536 + 64 = 1600

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

BASIC: FOR K = 1 TO 100

(следующие предложения)

NEXT K

Переменная К принимает значения от 1 до 100. Все эти значения можно хранить в ячейке с именем К, например, если К = 55, то в ячейке содержится число 55. Могут встречаться 8, 24, 36 разряда и т.д. 8 бит введено видимо фирмой IBM. 8 бит = 1 Байт. Для хранения байта требуется 2 ячейки оперативной памяти. Если говорим 65536 Байт памяти, 64 К, то есть, умножены на 1Кб (1024 байт). Кроме ОП ЭВМ содержит вспомогательную память. Магнитная дискета (105 Байт памяти), ее необходимо переписать в оперативную память.

Нельзя: путать адрес ячейки с содержащимся в ней числом. Например, ячейка с адресом 6 может содержать любое число от 0 до 255, и совсем не обязательно число 6. 6 – это просто шестая ячейка ЭВМ и ничего более.

На рис. 15 происходит выбор ячейки 5(101) с записью в ОЗУ.

Инкремент и декремент [5]

Любая ЭВМ предоставляет возможность сложения и вычитания. В программах для процессора 6502 при сложении и вычитании используются специальные приемы, но мы познакомимся с двумя простыми операциями: прибавление 1 (эта операция известна под названием инкремент) и вычитание 1 (так называемый декремент).

В процессоре 6502 предусмотрены 6 команд инкремента и декремента.

INC v Инкремент v

DEC v Декремент v

INX Инкремент регистра X

DEX Декремент регистра X

INY Инкремент регистра Y

DEY Декремент регистра Y

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

Выполним с помощью указанных команд предложение Бейсика K = L + 1. Для этого понадобятся 3 шага:

  1. Загрузка L в регистр.

  2. Инкремент регистра (+1 к его содержимому).

  3. Запись содержимого регистра в К

При использовании регистра X потребуется такая последовательность команд:

LDX L

INX

STX К

Точно так же можно выполнить операцию U = V – 1, используя, например, регистр Y:

LDY V

DEY

STY U

Если же надо выполнить операцию К = К + 1 (то есть прибавить 1 к К), мы можем ограничиться только одной командой:

INC К

Заметим, что последовательность команд

INC L

LDA L

STA К

также выполняет операцию K = L + 1. Однако такое решение не является наилучшим, так как одновременно с К изменяется L, хотя, записывая K = L + 1, мы предполагаем, что изменится только К.

Команды инкремента и декремента часто используются для прибавления или вычитания 2. Для того, чтобы выполнить операцию К = L + 2, надо написать

LDX L

INХ

INX

STX К

Выполнить К = К – 2 можно проще:

DEC К

DEC К

Таким образом, можно прибавлять или вычитать 3, 4 и т.д., но обычно для этого используются команды сложения и вычитания. Важно помнить, что команды INC К и DEC К не изменяют содержимое регистра А. Так последовательность команд INC К и STA L не сделают L равным К + 1.

Инкремент 255 дает 0, а декремент 0 дает 255. Действительно, если регистр X содержит 0 (двоичное число 00000000), то в результате выполнения команды DEX в регистре X теперь будет 11111111 (что представляет собой число без знака 255 или число со знаком -1).

Точно так же, если регистр Y содержит двоичное число 11111111, то в результате выполнения команды INY в регистре будет 0.

Стеки [5]

Или, проще говоря – стековая память. Фирмы-изготовители микропроцессоров в описании технических характеристик указывают, что «... микропроцессор работает со стековой памятью». Например, нам необходимо решить уравнение а2 + b2 = с2. Мы можем представить, что – а × а = a2, b × b = b2 и соответственно − с × с = с2. Запишем в виде подпрограммы, при решении сложной задачи, нам необходимо многократно обращаться к данной подпрограмме, ее расписывать, что крайне неудобно. Для упрощения решения задачи мы составим данную программу в виде подпрограммы и запишем ее на жесткий диск. При многократном использовании данного выражения, МП вызывает данную подпрограмму с жесткого диска, подставляет в решение задачи, а после выполнения – снова выгружает на жесткий диск. Экономится оперативная память и работать очень удобно. Рассмотрим рис. 18.

Р1 Р2

-

-

-

c all P2

-

α -

-

call P2

-

β -

-

call P2

-

Y -

-

RETURN

Рис. 18. Многократный вызов подпрограммы

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

Предложение вызова или перехода на подпрограмму (JSR P2, где JSR-(англ.) – переход на подпрограмму), очевидно, выполняет переход на Р2.

Предложение возврата RTS (RTS − возврат из подпрограммы), очевидно, выполняет на переход. Но куда? При первом обращении к Р2 предложение возврата вызовет переход в точку α. Во второй раз будет переход в точку β, в третий раз в точку Y.

Так же одна и та же команда может вызвать переход в три разные точки. Ответ заключается в механизме работы команды перехода на подпрограмму. Эта команда не только выполняет переход, но также вычисляет и сохраняет в памяти адрес возврата, который представляет собой адрес команды, следующей за JSR. При первом вызове Р2 адресом возврата является α; при втором вызове – β; при третьем –Y.

Команда возврата теперь может выполнить переход по адресу возврата, поскольку он хранится в памяти. Поэтому первый раз команда RTS вызовет переход на α, второй раз – на β; третий раз – на Y, как и требуется.

Следующий вопрос заключается в том, где хранить адрес возврата. В действительности команда JSR записывает адрес возврата в некоторую структуру данных, называемую стеком; команда RTS извлекает адрес возврата из стека и производит переход. Такой способ хранения адресов возврата является прогрессивной особенностью процессора 6502 (как и ряда других микропроцессоров) и приводит, как мы увидим, к значительной экономии времени и памяти. Чтобы понять, почему это так, мы должны рассмотреть, что представляют собой стеки. Стек представляет собой массив переменной длины. Назовем этот стек Н, а его размер (длину) – X. Тогда можно считать, что массив Н состоит из элементов от Н(0) до Н(Х-1).

Размер стека увеличивается, если Н(х) присвоить значение некоторой величины А, а затем к Н прибавить единицу. Такая операция называется проталкиванием А в стек (см. рис. 19).

из А

Н (Х)

Н (новое Х−1)

А (Х−1)

Н (Х−1)

Н (новое Х−2)

-

-

-

-

Добавление 1 к Х

-

-

-

-

-

Н (0)

Н (0)

Н (0)

Рис. 19. Проталкивание

в А

Н (новое Х)

А (Х−1)

Н (новое Х)

-

-

Вычитание 1 из Х

-

-

Н (новое Х −1)

Н (новое Х −1)

-

-

-

-

-

-

Н (0)

Н (0)

Н (0)

Рис. 20. Выталкивание

Мы можем уменьшить размер стека, вычитая 1 из X. При этом Н (X) снова попадет в А. Это обычно называется выталкиванием из стека.

И проталкивание, и выталкивание можно выполнить на Бейсике (рис. 19, 20):

Н(Х) = А Х = Х – 1

Х = Х + 1 А = Н(Х)

Проталкивание А Выталкивание А

Или на языке Ассемблера процессора 6502 с помощью регистров А и X

STA H, X DEX

INA LDA H.X

Проталкивание А Выталкивание А

Любой стек имеет максимальный размер, который мы будем обозначать max, так что всегда Х < mах. Для процессора 6502 обычно max = 256, так что максимальным допустимым значением (без знака) содержимого регистра Х при любых условиях являются Х < 256 или Х ≤ 255 (где 28-1 = 255-1, для 8-разрядной ЭВМ).

Теперь представим себе, что мы только протолкнули величины Р3, Р2 и Р1 (именно в этом порядке) в стек. Мы говорим, что Р1 находится на верхушке стека; Р2 представляет второй элемент стека (считая сверху вниз); Р3 – третий элемент сверху.

И если Р3, Р2 и Р1 загружены в такой стек, то

LDA Н  !1, Х загружает Р1 (верхушку стека);

LDA Н  !2, X загружает Р2 (второй элемент сверху);

LDA Н  !3, X загружает Р3 (третий элемент сверху),

и вообще LDA Н  !n, X загружает n-й элемент сверху.

Наличие в приведенных командах знака минус наводит на мысль о перевернутом стеке. В перевернутом стеке Н байты имеют обозначение на Н(0), Н(1), Н(2) и т.д., а Н(max – 1), Н(max – 2), Н(max – 3) и т.д. вниз до Н(Х + 1), причем Н(Х) по-прежнему представляет собой элемент над верхушкой стека. Теперь Х не характеризует размер стека. Размер стека равен Z, причем max – Z = X + 1 (или Z = max – (X + 1) = max – 1 – X). Если max = 256, то Z = 255 – Х; другими словами, текущий размер стека представляет собой дополнение до единицы содержимого регистра Х.

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

STA H, X IN X

DEX LDA H.X

Проталкивание А Выталкивание А

и если Р3, Р2 и Р1 загружены в такой стек, то

LDA Н + !1, Х загружает Р1 (верхушку стека);

LDA Н + !2, X загружает Р2 (второй элемент сверху);

LDA Н + !3, X загружает Р3 (третий элемент сверху),

и вообще LDA Н + !n, X загружает n-й элемент сверху, и мы заменили знаки минус на знаки плюс.

Стек можно использовать для сохранения и восстановления. Если мы сохраним несколько величин, протолкнув их в стек, то позже мы можем восстановить их, вытолкнув из стека

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

Команды, ориентированные на использование стека [5]

Рассмотрим механизм выполнения команд JSR и RTS и введение четырех новых команд.

Аппаратный стек процессора является перевернутым; для него выделены фиксированные адреса с 0100 и 01FF. Стек связан со специальным регистром, называемым указателем стека. Это регистр S, информация о котором появляется на экране в процессе пошагового выполнения.

Команда РНА (Push А – проталкивание А) проталкивает содержимое регистра А в аппаратный стек. Делается это следующим образом: содержимое регистра А записывается по адресу 0100 + S, а затем содержимое регистра S уменьшается на 1. Ранее объяснялось в предыдущих статьях, только в регистрах X используется указатель стека S.

Команда PLA (Pull А – выталкивание А) выталкивает содержимое регистра А из аппаратного стека путем увеличения на 1 содержимого регистра S и загрузки регистра А из ячейки с адресом 0100 + S. Это тоже совпадает с процедурой в предыдущей части «Стеки или стековая память», только вместо регистра Х используется указатель стека S.

Наконец, команда JSR проталкивает в аппаратный стек адрес возврата (минус 1 для упрощения аппаратных операций), а команда RTS выталкивает этот адрес из стека (и прибавляет к нему 1) и производит переход по этому адресу. Поскольку адреса представляют собой 16-разрядные величины, JSR проталкивает два байта (сначала старший байт, чтобы адрес записался в памяти, как обычно, с переставленными байтами), a RTS выталкивает 2 байта.

Как это происходит? [5]

Пусть для примера в стеке записаны 3 байта. Они находятся в ячейках 01FF, 01FE и 01ЕD, а указатель стека содержит FC. Если в ячейках 08В4, 08В5 и 08В6 хранятся 3 байта команды JSR, следующая за JSR команда начинается в ячейке 08В7, и 08В7 – это адрес возврата. После выполнения команды JSR в стеке будет 5 байт, в ячейках 01FF, 01FE, 01ED, 01FC и 01FB, а в указателе стека будет FA. Два новых байта в стеке – это 08 (в ячейке 01FС) и В6 (в ячейке 01FB), потому что 08В6 – это адрес возврата (08В7) минус 1. После выполнения команды RTS число 08B6 выталкивается из стека, и производится переход по адресу 08В6 + 1, то есть 08В7 (адрес возврата); теперь в стеке, как и прежде, 3 байта, и в указателе стека адрес FC (именно FC, а не 01FC – указатель стека 8-разрядный).

Команды РНА и PLA можно использовать для сохранения и восстановления содержимого регистра А. Содержимое регистров X и Y можно сохранить, предварительно переслав его в регистр А, и восстановить, переслав обратно. Если нужно сохранить содержимое всех трех регистров А, X и Y, можно в начале подпрограммы написать

РНА; Сохранить регистр А

ТХА; Переслать Х в А

РНА; (это сохраняет регистр X)

TYA; Переслать Y в А

РНА; (это сохраняет регистр Y)

а в конце перед командой RTS написать

РLА; Восстановить регистр Y

ТАY; Переслать назад в Y

РLА; Восстановить регистр Х

TAХ; Переслать назад в Х

РLА; Восстановить регистр А.

Таким образом, если мы сохраним содержимое регистров А, X и Y в таком порядке, то содержимое регистра Y оказывается на верхушке стека. При восстановлении сначала надо восстановить регистр Y, затем Х и, наконец, А.

Чтение из стека производится в обратном порядке по отношению к порядку записи в него.

Команды вызова и возврата типа JSR и RTS, ориентированные на работу со стеком, можно непосредственно использовать в том случае, если имеют несколько уровней подпрограмм.

Рассмотрим рис. 21, где подпрограмма Р1 вызывает подпрограмму Р2, а Р2 вызывает подпрограмму РЗ. Последовательность событий будет следующей:

  1. Р1 вызывает Р2, а α (минус 1) проталкивается в стек;

  2. Р2 вызывает РЗ и β (минус 1) проталкивается в стек;

  3. происходит возврат из РЗ в Р2. Адрес возврата выталкивается из стека, причем это β, потому что β сейчас находится на верхушке стека;

  4. после возврата из РЗ продолжается выполнение программы Р2, а затем происходит возврат в Р1. На этот раз из стека выталкивается адрес возврата α.

JSR P2

α

JSR P3

β

RTS

RTS

Р1 Р2 Р3

JSR P2

JSR P3

RTS

RTS

Начало: Р1 вызывает Р2, Р2 вызывает Р3, возврат из Р3, возврат из Р2

β (два

байта)

α (два

байта)

Возврат к β

α (два

байта)

α (два

байта)

Возврат к α

Стек Стек Стек Стек Стек

Рис. 21. Два уровня вызовов подпрограмм

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

Команда TSX пересылает содержимое указателя стека в регистр X. После того, как это было сделано, команда

LDA STACK + !1, Х загружает верхушку стека;

LDA STACK + !2, Х загружает второй элемент сверху,

LDA STACK + !3, X загружает третий элемент сверху,

и т.д., если в программе было определение STACK EQU и т.д.

Команда TXS пересылает содержимое регистра X в указатель стека. Это единственная возможность загрузки указателя стека: требуемая константа загружается в регистр X и выполняется команда TXS. Просто можно воспользоваться такой последовательностью команд:

TSX; переслать указатель стека в X;

DEX; уменьшить его на 1 и

TXS; восстановить указатель стека

Этим и заканчивается наше изучение команд пересылки процессора. Их всего 6: TAX, TAY, TXA, TYA, ТSХ и TXS.

МАШИННЫЙ ЯЗЫК И ЯЗЫК АССЕМБЛЕРА [8]

Язык, который понимает микропроцессор (МП), называется машинным языком (часто называют машинным кодом). Поскольку МП имеет дело только с цифровыми сигналами, команды машинного языка представляют собой двоичные коды (например, 00111100). МП конструируется так, чтобы обеспечивалось распознавание конкретной группы кодов, которая называется системой команд. Например: 00111100 – заменяется на 3С. Мнемоника – замена машинного кода на код высокого уровня.

3С обозначает (увеличить содержимого регистра А), выглядит как INRA. Поэтому нет смысла запоминать машинные коды

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

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

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

Существуют однопроходные и многопроходные компиляторы.

Однопроходные компиляторы осуществляют проход (выполнение программы) за один раз. Многопроходные – многократно.

Интерпретатор – транслятор, обеспечивающий перевод каждой конструкции алгоритмического языка в машинные команды и одновременное выполнение этой конструкции в ЭВМ. Интерпретатор представляет очень сложную систему, занимающую большие объемы памяти, характеризующуюся малой скоростью работы. Но обеспечивает удобную форму отладки программы пользователем. Например, интерпретатор с языка программирования Бейсик, просто производит отладку.

Можно сравнить с изготовлением торта, переводимый с итальянского языка на русский. Каждое предложение переводится, затем выполняется, но не запоминается.

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

Языковый процессор – это транслятор, который совмещает в себе функции компилятора, интерпретатора и ассемблирования.

Ассемблер – команды Let COUNT = 10 или PRINT COUNT

Таблица 8

Программа счета до 10, написанная на языке Бейсик

№ строки

Команда

Описание команды

1

Let Gount = 0

Сбросить счетчик в «0»

2

Let Gount = Gount +1

Дать приращение показания счетчика =10

3

IF Gount = 10 Then 1

Перейти к строке 1, если

показание счетчика = 10

4

GOTO 2

В противном случае перейти к строке 2

считать до 10

установить показание счетчика равным 0

увеличить показание на 1

показание = 10

да

нет

Рис. 22. Блок-схема программы счета до 10

Таблица 9

Программа счета до 10, написанная на языке Ассемблер

Метка

Команда

Комментарий

START:

MVI A, O

; Сбросить регистр А в «0»

LOOP:

INR А

; Дать приращение в регистре А

CPI 10

JZ Start

;Сравнить приращение регистра А с числом 10

;Вернуться к началу, если А = 10

JMP LOOP

; Повторить

Таблица 10

Программа счета до 10, написанная на машинном языке

Адрес ячейки памяти,

шестнадцатеричной

Содержимое ячеек памяти

в шестнадцатеричном

коде

в двоичном коде

07F0

07F1

07F2

07F3

07F4

07F5

07F6

07F7

07F8

07F9

07FA

3E

ØØ

3C

FE

ØA

CA

Ø7

C3

F2

Ø7

00111110

00000000

00111100

11111110

00001010

11001010

11110000

00000111

11000011

11110010

00011111

Характеристика языков программирования [3]

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

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

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

Физические принципы работы электронных устройств ЭВМ таковы, что компьютер может воспринимать только команды, состоящие из единиц и нулей, то есть машинный код. На начальной стадии развития ЭВМ человеку было необходимо составлять программы на языке, понятном компьютеру, в машинных кодах, то есть каждая команда представляла собой машинный код. В свою очередь, каждая команда состояла из кода операции и адресов оператора, выраженных в виде различных сочетаний единиц и нулей. Например, для выполнения сложения С = А + В машинный код представлял собой следующее:

0011 10011010 10001001 1010011

операция + адрес ячейки адрес ячейки адрес ячейки

операнда А операнда В результата С

Как показала в дальнейшем практика общения с компьютером, такой язык громоздок и неудобен. При пользовании им легко допустить ошибку, записав не в той последовательности 1 или 0. Программу очень трудно контролировать. Коме того, программирование в машинных кодах требует от программиста много времени, труда, повышенного внимания. Для сравнения приведем программу, написанную на языке BASIC.

10 Let A = 2

20 Let B = 2

30 Let С = A + B

40 PRINT С

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

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

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

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

Языки программирования

Машинно-ориентированные

Алгоритмические

(высокого уровня)

Машинный

Символического

кодирования

Для

профессиональных

программистов

Для

непрофессионалов

Рис. 23. Языки программирования

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

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

Как среди естественных языков нет совершенного языка, так и среди алгоритмических языков создать что-либо универсальное весьма проблематично. Всегда будут появляться такие задачи, где возможности языка не будут удовлетворять пользователя. Попытки в этом направлении делались, но нельзя сказать, что они оказались успешными. Примерами могут служить языки ПЛ/1 и АЛГОЛ-68.

Языки профессиональных программистов это основная и очень многочисленная группа разнородных, а подчас и похожих языков. К наиболее известным языкам, реализованным в ЭВМ разного класса можно отнести Фортран, АЛГОЛ, Кобол, ПЛ/1, Паскаль, Ада, Си, ЛИСП.

Фортран (FORmula TRANslator – транслятор формул) является первым алгоритмическим языком. Он создан в конце 50-х годов. Это язык очень близкий по форме к записи математических формул. Он и по сей день остается самым распространенным языком. Транслятор с языка Фортран имеет большинство ЭВМ. На нем создано большое количество программ, которые с успехом используются в соответствующих областях. Однако этому языку свойственен существенный недостаток: он не обеспечивает надежность программирования (защиты от ошибок) из-за своей громоздкости и несовершенства логических возможностей. Программирование на языке Фортран можно сравнить с ездой на телеге по автостраде с оживленным автомобильным движением.

Алгол-60 (ALGOrithmic Language – алгоритмический язык) появился в 1960 г. практически в то же время, что и Фортран. Это более совершенный язык, чем Фортран; он обладает большой гибкостью при проектировании программ, обеспечена более высокая надежность программирования. Однако Алгол-60 приобрел меньшую известность, чем Фортран, и в основном использовался на отечественных ЭВМ. После создания Алгола началось бурное развитие языков программирования. Он лег в основу таких языков, как ПЛ/1, Паскаль, Ада.

ПЛ/1 (Programming Language one – язык программирования №1) разработан в США для использования в больших ЭВМ фирмы IBM. Это очень большой и сложный для изучения язык; применяется он в основном для научных расчетов, обработки больших массивов информации.

Паскаль создан в 1970 г. в Швейцарии ведущим специалистом в области программирования Нойбертом Виртом и назван в честь математика и физика XVII века Блеза Паскаля. Это очень простой и компактный язык, его понятия близки к фундаментальным понятиям математики (множество, отображение, последовательность и т.д.). По своей структуре и синтаксису среди существующих языков он наиболее совершенен. Это определило его популярность. Обучение специалистов программированию принято начинать с изучения языка Паскаль, как наиболее полно отражающего базовые конструкции любой разновидности алгоритмических языков.

Ада – алгоритмический язык, разработанный по заданию Министерства обороны США в 1979 г. и названный в честь первой программистки Ады Лавлейс, дочери Дж. Байрона, которая еще в XIX веке создавала первые программы для Аналитической машины Чарльза Бэббиджа. В этом языке использовано много идеи из Паскаля и Алгола-68, а также заимствованы лучшие конструкции из других языков. Однако трансляторы с этих языков получились очень сложными и работают медленно. Скорее всего, этот язык займет то же самое место, что и ПЛ/1 или Алгол, то есть это универсальные языки, но далеко не идеальные.

Кобол (Common Business Oriented – язык, ориентированный на обработку коммерческой информации) создан в 1960 г. Из-за синтаксиса и основных конструкций, являющихся очень специфичными и громоздкими, он не используется в других областях.

Лисп (LIST Processing – обработка списков) разработан в конце 50-х годов и является самым популярным языком для работ по искусственному интеллекту.

Особенно широкое распространение получил язык Бейсик (дословно: универсальный код символических инструкций для начинающих). Первоначально он был разработан Джоном Келени и Томасом Куртцем из Дармурского колледжа (США) в 1965 г. и предназначался для вводного курса по информатике. Благодаря своей простоте и возможности работы в диалоговом режиме этот язык быстро завоевал признание среди пользователей – непрограммистов. Составлением программ на этих языках с удовольствием занимаются даже дети.

ИНФОРМАЦИЯ И ТЕХНИЧЕСКИЕ СРЕДСТВА ЕЕ ОБРАБОТКИ [6]

Общие сведения [6]

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

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

  1. управление (обеспечение заданных параметров процессов);

  2. оптимизация (обеспечение оптимального соотношения затрат и отдачи);

  3. индикация аварийных состояний;

  4. обеспечение нормального протекания процесса (контроль предельных параметров).

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

История автоматизации относится к античным временам. Так, Герон Александрийский с помощью простейших механизмов (разновесов, системы роликов, зубчатых колес и рычагов) создал автоматический кукольный театр (фигурки автоматически передвигались по сцене) и автомат, который при вложении в него соответствующей монеты наливал несколько капель священной воды. Дальнейшее развитие процесса автоматизации концентрировалось в области создания кукол-автоматов и механических музыкальных инструментов до тех пор, пока, наконец, автоматы не нашли своего практического применения преимущественно в промышленных целях. Наполеону Бонапарту, будучи в зените славы, придворные льстецы подарили «Аналитическую машину», которая «сама» играет в шахматы. Маленького человека спрятали внутри «машины», и он с помощью специальных рычагов, передвигал шахматные фигурки.

И Наполеон проиграл «Аналитической машине», и так до конца своей жизни и думал, что проиграл пресловутой «машине». Например, в 1784 г. Оливер Эван сконструировал мельницу, работающую без помощи человека. Благодаря удачной комбинации различных технических устройств (например, архимедовых червячных передач, цепи черпаков, водяных колес) обеспечивался весь процесс производства, в ходе которого сырье (зерно) перерабатывалось в готовую продукцию (муку).

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

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

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

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

Автоматизированные системы управления [3]

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

планирование

контроль

объект

управления

принятие

решения

анализ

Рис. 24. Автоматическое управление системами

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

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

По объектам управления АСУ можно классифицировать следующим образом: АСУ научных исследований и разработок (АСНИ); АСУ капитального строительства (АСУКС); АСУ управления производством (АСУП); АСУ транспортом (АСУТ); АСУ трудовыми ресурсами (АСУТР); АСУ энергетических систем (АСУЭС); АСУ здравоохранения (АСУЗ); интегрированные АСУ (ИАСУ).

Приведенный перечень далеко не исчерпывает области применения АСУ.

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

Подсистемы АСУ по своей роли в процессе управления объектом делятся на две группы – функциональные и обеспечивающие.

Функциональная подсистема решает совокупность автоматизированных задач, направленных на реализацию функций управления объектом. Наиболее типичными функциональными подсистемами АСУ предприятия являются подсистемы планирования, материально-технического снабжения, финансового и бухгалтерского учетов, кадров, сбыта и т.д. Число функциональных подсистем и их содержание обуславливаются как характером объекта управления, так и степенью развитости АСУ. Конечно, АСУ промышленного предприятия и АСУ городского отдела здравоохранения будут иметь различные функциональные подсистемы.

Обеспечивающими подсистемами являются средства и методы обеспечения работы АСУ, то есть технические решения функциональных задач.

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

Информационное обеспечение [3]

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

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

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

Программное обеспечение [3]

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

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

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

Техническое обеспечение [3]

Это комплекс технических средств, являющихся материальной базой АСУ и предназначенных для автоматизации сбора, передачи, обработки информации, проведения расчетов, накопления, хранения результатов расчетов и справочной информации.

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

Вычислительный центр может располагать большими ЭВМ с быстродействием от нескольких миллиардов операций до десятка миллиардов операций в секунду, оперативной памятью в сотни гигабайт, что позволяет накапливать большие объемы информации. Много это или мало? Оказывается, что один гигабайт по объему информации приблизительно равен расстоянию от Москвы до Владивостока, почти 10 тыс. км. Значит, в вычислительном центре может быть сосредоточена информация в объеме нескольких библиотек.

Организационное обеспечение [3]

Оно предназначено для организации эффективного функционирования всех подсистем и автоматизации системы управления объектом в целом, контроля, анализа и регулирования, организации процессов управления, оценки правильности и эффективности принятия решения. ACУ не является надстройкой к традиционным неавтоматизированным средствам управления. Поэтому состав группы управления АСУ возглавляет руководитель объекта или первый заместитель. Группа управления АСУ регулярно оценивает эффективность автоматизации управления объектом и определяет направление развития АСУ.