ОСНОВНЫЕ ПОНЯТИЯ МАШИННОГО ЯЗЫКА
ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ
Ч т о т а к о е Ц П ?
Если мы хотим обмениваться информацией с ЭВМ, то нам
необходимо знать какого типа команды она будет воспринимать и
на каком языке разговаривает мозг ЭВМ (ЦП).
Если мы не знаем, информацию какого типа
воспринимает ЦП, то мы не сможем как следует объяснить
ЭВМ,какие замечательные задачи она должна для нас решать - от
соперничества в шахматной игре до бухгалтера,следящего за
нашими счетами.
В ЦП нет ничего загадочного. Мне нравится
представлять ЦП в виде одинокого человечка, сидящего внутри
вашего "Спектрума", которого все время просят что-то делать.
В особенности - вычислять. Но у бедного человечка нет даже
карандаша и бумаги для записи происходящего. Как же он делает
это?
К о н с т р у к ц и я Ц П
Сейчас мне следует рассказать вам как конструкторы
Z80 представляют объекты и как ЦП полагается обрабатывать их.
ЦП сконструирован для выполнения очень простых заданий, но он
способен выполнять их очень быстро. Мы упомянули, что у ЦП
нет даже карандаша и бумаги, и именно так он сконструирован.
Любое число, которое он не может запомнить или найти, ЦП
должен положить в какой-нибудь ящик на хранение. Давайте
рассмотрим один пример. Вы хотите, чтобы ЦП определил время в
Нью-Йорке, зная время в Лондоне. Считая, что ЦП ничего не
знает, вам прежде всего придется сказать ему который час в
Лондоне. Скажем, 10 часов. ЦП негде запомнить эту информацию
и неизвестно, что вы попросите его делать дальше. Так что он
откладывает эту информацию в ящик, скажем, N1. Затем вы
должны сообщить ему разницу во времени между Нью-Йорком и
Лондоном, скахем, на пять часов раньше. Он откладывает ее в
ящик N2. Приходит время для вычислений. Он спешит к ящику N1,
достает число, идет к ящику N2, выполняет вычисления и
откладывает результат в ящик N3.
10 - 5 = 5
Ответ, конечно, 5 часов.
Вся эта беготня между ящиками, сложение , вычитание
и т. д. были бы очень утомительными, если бы ЦП нужно было
все делать в уме. Поэтому он поступает точно как и вы -
считает на пальцах рук и ног.
Руки и ноги ЦП называются регистрами.
Чип Z80 в вашем "Спектруме" отличается тем, что у
него масса рук и ног, но мы остановимся на этом позже.
Чтобы показать, как в точности ЦП вычисляет разницу
во времени в приведенном выше упражнении, давайте назовем
одну из рук ЦП "рука А". Как ЦП управляет содержимым ящика N1
и ящика N2? Приводимая ниже последовательность довольно точно
соответствует тому, что на самом деле делает ЦП при заданных
выше командах:
- отложить значение из ящика N1 на пальцах руки А;
- вычесть содержимое ящика N2 из того, что у него уже
отложено на пальцах;
- взять количество пальцев на руке А и поместить его в
ящик N3.
Итак, если именно так происходит, отсюда вытекают
довольно неожиданные выводы:
1.ЦП не сможет обрабатывать числа подобные 11,53 -
он может обрабатывать только целые числа.
2.ЦП в своих вычислениях будет ограничен числами,
которые он откладывает на своих пальцах.
Это, конечно, верно.
Есть, однако, утешение, что у ЦП масса рук и ног и
он может на всех из них считать по отдельности, и что он
может считать до 255 с помощью всего 8 пальцев на руке А.
В следующей главе мы подробнее рассмотрим почему ЦП
может считать больше, чем до 8 на каждой руке, тогда как мы с
помощью двух рук - только до 10. Пока достаточно сказать, что
на каждой руке можно считать до 255, а на каждой ноге - более
чем до 64000.
Упражнение с разницей во времени до сих пор не
представлено на чем-либо похожем на язык, воспринимаемый ЦП,-
мы только описали процесс.
Чтобы вы заранее получили представление о
захватывающих аспектах программирования на машинном языке,
давайте теперь применим мнемонику (сокращения), чтобы на
каждом шаге давать команду ЦП.
У с т а н о в к а:
LD (BOX N1), 10 1:LOAD BOX 1 WITH 10
LD (BOX N2), 5 2:LOAD BOX 1 WITH 5
1 - загрузить 10 в ящик N1; 2 - загрузить 5 в ящик N2
В ы ч и с л е н и я:
LD A, (BOX N1) 1:LOAD A WITH BOX 1 CONTENTS
SUB A, (BOX N2) 2:SUBTRACT CONTENTS OF BOX 2
1 - загрузить содержимое ящика N1 в А; 2 - вычесть
содержимое ящика N2
З а п о м и н а н и е р е з у л ь т а т а:
LD (BOX N3), A 1:LOAD BOX 3 WITH A VALUE
1 - загрузить значение А в ящик N3
Эти команды сначала могут показаться излишне
краткими, но, в конце концов, мнемоника есть мнемоника.
"LD" - сокращенное LOAD (загрузить), так что
LD A,1
означает загрузить 1 в А, т.е. отложить "единицу" на
пальцах руки А.
В этих мнемонических обозначениях используется также
довольно разумный образ, основанный на применении скобок:
скобки используются, чтобы показать, что мы хотим
использовать содержимое того, что стоит в скобках. Это
нетрудно запомнить с помощью наглядного представления,
поскольку скобки выглядят так, что напоминают контейнер.
Таким образом, проходя приведенные выше
мнемонические обозначения, мы загружаем в ящик N1 и N2 10 и
5, и т.д.... и получаем конечный результат, равный 5, в ящике
N3.
Все это достаточно просто для понимания и, я уверен,
вы понимаете, что пока вы выполняете вычисления, числа на
руке А используются для представления времени в Нью-Йорке.
Минутой позже они могут использоваться для представления
количества служащих в фирме, а в некоторый другой момент -
количества имеющихся у вас денег.
Если вы привыкли к понятию переменной, программируя
на языке "Бейсик", то при программировании на машинном языке
вы должны отказаться от него.
Пальцы на руке А - это не переменная в том смысле, в
котором она используется в программе на "Бейсике". Это просто
то, с помощью чего ЦП считает. Одно из существенных различий
между программированием на машинном языке и на языке "Бейсик"
- это отсутствие переменных.
Вы можете считать, что ящики, испльзуемые нами для
запоминания информации, аналогичны переменным "Бейсик", если
мы каждому дадим имя. Да, вы абсолютно правы, но это все-таки
не переменные. Они могут быть очень полезны и выполнять те же
функции хранения, что и переменные, но имейте ввиду, что эти
ящики - не более, чем ячейки памяти, отведенные для
конкретных целей.
Несколько иначе ЦП обрабатывает отрицательные числа,
но этот вопрос мы рассмотрим позднее.
Ч т о е с л и Ц П н е х в а т и т р у к?
Нужно сказать, что ЦП, встреть вы его на улице,
показался бы вам очень странным субъектом. На каждой из его
рук по 8 пальцев, а самих рук 8; у него только две ноги, но
на каждой по 16 пальцев и он ими очень живо перебирает.
Поэтому он хорошо подходит для большого количества
вычислений, для которых он предназначен, откладывая все числа
на пальцах рук и ног. Тем не менее возможно, что в некоторых
случаях у ЦП окажется недостаточно рук для выполнения
необходимых вычислений или по некоторым причинам программист
захочет остановить ЦП посреди вычислений, чтобы выполнить
что-то другое. ЦП Z80 выходит из положения , применяя стек,
т.е. одну из тех высоких колючих вещей, на которые вы
накалываете сначала один кусок бумаги, потом следующий и т.д.
Это удобная система хранения, если вам нужен только верхний
клочок бумаги, но очень неудобная, если нужен клочок из
середины, так как придется перерыть все бумаги в стеке.
Получилось, что это очень удобная система для ЦП, поскольку
ему всегда нужна верхняя порция информации. Каждый раз, когда
прерывание заставляет ЦП прервать вычисления, он "вталкивает"
всю информацию со своих рук в стек. А когда прерывание
закончено, "выталкивает" верхние порции информации и
продолжает свою работу. В терминологии ЭВМ мы называем иглу
стеком. Когда мы помещаем порцию информации в стек, мы
"вталкиваем" ее, а извлекая - "выталкиваем". Втолкнуть в стек
и вытолкнуть можно информацию любого типа, например, в
середине сложных вычислений ЦП может потребоваться запомнить
всю информацию с его многочисленных рук и ног и для этого
потребуется много отдельных "вталкиваний". По причинам, лучше
известным разработчикам Z80, наш ЦП предпочитает держать стек
кверху ногами. Это значит, что чем больше информации
"вталкивается" в стек, тем дальше вниз растет стек. Основное
преимущество применения стека для храниения временных порций
информации состоит в том, что ЦП не приходится запоминать в
каком ящике находится информация - он знает, что это
последняя порция информации "втолкнутая" в стек. Естественно,
требуется некоторый порядок, если нужно "вталкивать" и
"выталкивать" много порций информации.
Ч т о м о ж е т Ц П ?
Я думаю, на этом этапе стоит рассмотреть команды
какого типа разработчики посчитали полезным встроить в чип
Z80.
Поскольку ЦП должен иметь возможность отслеживать
все свои вычисления на пальцах рук и ног, есть только два
типа чисел, с которыми может работать ЦП:
- числа для одной руки - т.е. чмсла, которые можно
отложить на пальцах одной руки;
- числа для двух рук - т.е. числа, которые можно
отложить на пальцах двух рук;
- вам может оказаться трудно в это поверить, но ЦП
не может обрабатывать числа, превосходящие те,
которые он может отложить на двух руках;
- типы команд, которые может выполнят ЦП, так хе
ограничены;
- откладывание чисел на одной руке;
- откладывание чисел на двух руках;
- сложение, вычитание, увеличение, уменьшение или
сравнение чисел для одной руки;
- сложение, вычитание, увеличение, уменьшение чисел
для двух рук;
- различные преобразования чисел для одной руки,
например, изменение знака числа;
- указание ЦП перейти к другой части программы;
- попытка обмена числами для одной руки с внешним
миром.
Согласитесь, что это очень ограниченный набор
команд. И все же применяя такой ограниченный набор вы можете
заставить ЦП играть в шахматы и считать свою зарплату.
Обратите внимание, что нет даже таких простых команд, как
умножение. Если вам нужно перемножить два числа на машинном
языке, вам придется для этого писать программу. Именно
поэтому написание программ на машинном языке значительно
медленнее, чем написание программ на "Бейсике"- вы можете
добиваться результата только крохотными шажками.
В Ы В О Д Ы
Р е г и с т р ы
У ЦП имеются регистры, которые он может использовать
для вычислений. Восемь из них можно считать руками ЦП, а два
- его ногами. На каждой руке по 7 пальцев, а на каждой ноге -
по 16.
Я ч е й к и п а м я т и
ЦП может передавать информацию с одной своей руки на
другую, а также в память и из нее. Программист может отвести
конкретные ячейки памяти для представления конкретной
информации.
С т е к
ЦП может использовать стек для передачи информации,
которую программист хочет временно запомнить. Информация
передается в стек путем "вталкивания" в него, а извлекается
путем "выталкивания".
В о з м о ж н ы е к о м а н д ы
ЦП может выполнять только команды такого типа, как
простейшие передачи информации и простые арифметические
действия. Все программы должны быть составлены из
последовательности этих простейших команд.
К А К С Ч И Т А Е Т Э В М
ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ
Выше упоминали, что ЦП может считать до 255 с
помощью всего лишь 8 пальцев. Как это выходит, если с помощью
десяти пальцев нам удается считать только до 10?
Так получается, конечно, не потому , что ЭВМ умнее
нас , а потому, что информация в ЦП лучше организована.
Почему загнутый указательный палец имеет то же самое
значение, что и мизинец (=1)? Кажется очевидным, что при
желании вы таким способом могли бы представить два различных
числа. Это во многом похоже на понимание того, что число 0 0
1 отличается от числа 1 0 0. Простая истина состоит в том,
что люди не очень эффективно используют пальцы для счета. ЦП
понимает, что отсутствие пальца несет некоторую информацию, и
то, какой палец отогнут - ценная порция информации. С помощью
всего двух пальцев мохно разработать способ счета от 0 до 3
таким методом:
0 0 - 0 1.WE CAN INDICATE NOT HAVING A
FINGER RAISED AS "0"
0 1 - 1 AND HAVING A FINGER RAISED AS "1"
1 0 - 2 2.THIS DOES NOT MEAN 11 - 3
1 1 - 3 IT MEANS WE SHOSE TO LET THE
REPRESENTATION 11 (OR TWO
FINGERS) HAVE THE VALUE 3
1 - мы можем отмечать загнутый палец цифрой "0", а
поднятый палец - цифрой "1"; 2 - это не означает, что 1 1 =
3, просто мы решили, что комбинация 1 1 (или два пальца)
будет иметь значение 3. Так же просто мы могли бы выбрать и
другой способ обозначения.
Между этим представлением и двоичной системой
счисления имеется непосредственная связь. Пальцы ЦП - это
ячейки памяти и можно сделать так, чтобы они обозначали
"включено" и "выключено" (или "0" и "1", как требует система
обозначений).
Если бы в приведенном выше примере мы добавили
третий палец, то мы могли бы представить все числа от 0 до 7.
Три пальца на все числа от 0 до 7!
С помощью четырех пальцев можно представить все
числа от 0 до 15! Если вы этому не верите, то будет хорошим
упражнением выписать все возможные комбинации из 4 пальцев.
Чтобы упростить систему обозначений таких чисел и
избежать путаницы при попытке записать число одиннадцать так,
чтобы оно отличалось от установки двух битов, было принято
общее соглашение. Числа от 10 до 15 обозначаются буквами A -
F
десятичное 10 = A
11 = B
12 = C
13 = D
14 = E
15 = F
Это означает, что мы следующим образом записываем
десятичные числа от 0 до 15
0 1 2 3 4 5 6 7 8 9 A B C D E F
Не правда ли, просто?
Такой способ обозначения чисел называется
шестнадцатеричным форматом.
Чтобы избежать путвницы некоторые пишут "H" после
шестнадца- теричного числа (например, 10H). Это "H" не имеет
значения, а служит просто для напоминания пользователю о
шестнадцатеричной системе счисления. При программировании на
машинном языке удобно иметь дело с числами в
шестнадцатеричном формате.
Это только система обозначений и при желании вы
могли бы записать все ваши команды в обычном десятичном
формате. Нам удобно использовать шестнадцатеричный формат по
следующим причинам:
1. Из этой формы числа легко перевести в двоичный
формат, который говорит нам, что означает каждый бит (или
палец).
2. Он дает нам возможность легко определить, будет
ли число для одной руки или для двух рук, т.е.
восьмиразрядное или шестнадцатиразрядное.
3. Он дает стандартное представление всех чисел в
виде последовательности двухразрядных чисел.
4. Это общепринятая система обозначений и знакомство
с шестнадцатеричной системой позволит вам с большей легкостью
читать другие книги и ркуоводства.
5. Поскольку ЦП сконструирован для обработки
информации, представленной двоичными числами, которые людям
для чтения неудобны, требуется более удобочитаемое
представление.
Но это только система обозначений, а не священное
правило.
Шестнадцатеричная система, как отмечалось выше,
позволяет представлять числа от 0 до 15 с помощью всего 4
битов. Любая 8-разрядная ячейка памяти (или 8-разрядный
регистр) может быть описана как два набора по 4 бита. Нас
интересуют 8-разрядные ячейки памяти и 8-разрядные регистры
потому, что такова структура "ZX Спектрум". Все ячейки памяти
и все одинарные регистры имеют по 8 разрядов.
Продвигаясь постепенно, давайте познакомимся сначала
с комбинациями из 4 пальцев:
1 1 1 1 2**3 2**2 2**1 2**0
8 4 2 1
1. DECIMAL 15
2. F (IN HEXADECIMAL NOTATION)
1 -десятичное 15; 2- в шестнадцатеричной системе
обозначений имеющие склонность к математике могут заметить,
что представляемое каждым пальцем число каждый раз
увеличивается в 2 раза, если двигаться справа налево. Если
перенумеровать пальцы :
3 2 1 0
то значение каждого пальца равно "2 в степени N", где "N" -
номер пальца. Будем называть руку с 4 пальцами "ручонкой".
У п р а ж н е н и е
Какие десятичные и шестнадцатеричные значения
представляют следующие комбинации битов (или пальцев)?
десятичное шестнадцатеричное
0 0 1 0
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
Вам важно познакомиться с шестнадцатеричной системой
обозначений, и если это понятие вызвало у выс трудности,
прочтите еще раз несколько последних страниц прежде, чем идти
дальше.
Рассмотрим, что получится , если нам нужно число,
превышающее 15, скажем, 16. Мы используем следующий палец
слева так:
7 6 5 4 3 2 1 0
= 16 десятичное = 10Н (шестнадцатеричное)
причина, по которой мы пишем число в виде 10Н, состоит в том,
что мы делим руку на две "4-разрядные ручонки". Поэтому мы
легко можем обозначить каждую ручонку одной из
шестнадцатеричных цифр от 0 до 15 (0-9 и A-F).
Таким способом произвольную 8-разрядную руку можно
записать в виде ровно двух шестнадцатеричных ручонок:
____________________
| 7 6 5 4 3 2 1 0 |
_____|______ ____|______
| 3 2 1 0|| 3 2 1 0|
| |
ONE ONE
HEXADECIMAL HEXADECIMAL
DIGIT DIGIT
|____________|
|
TWO
HEXADECIMAL
DIGITS
1 - одна шестнадцатеричная цифра; 2 - две шестнадцатеричных
цифры.
Значение "ручонки" слева в 16 раз превышает значение
"ручонки" справа. Это во многом напоминает десятичную систему
счисления, где цифра в разряде "десятков" значит в 10 раз
больше, чем цифра в разряде "единиц".
Мы машинально преобразуем числа в десятичной
системе, такие как 15 к виду:
15 = (1*10) + 0
= 16 десятичное
Именно таким способом мы получаем возможность
считать до 255 с помощью всего 8 пальцев. Максимальное
значение получается, когда все пальцы подняты:
7 6 5 4 3 2 1 0
---------- ----------
|____________|
|
F F
FFH = (F*16) + F
= (15*16) + 15 (IN DECIMAL)
= 255 (DECIMAL) 1
1 - десятичное
Наименьшее число получается, когда все пальцы
согнуты:
00H = 0 десятичное
Обратите внимание, что все числа, от наименьшего до
наибольшего, требуют двух и только двух цифр, чтобы
определить число.
Возьмите сами произвольную комбинацию 8 двоичных
разрядов и попытайтесь преобразовать ее сначала в
шестнадцатеричную, а потом в десятичную систему счисления.
Сначала это может показаться странно и неудобно, но
вы скоро к этому привыкните.
Точно так же счет в шестнадцатеричной системе
происходит тем же способом, что и в десятичной:
десятичная 26 27 28 29 30 и т.д.
шеснадцатеричная 26 27 28 29 2A 2B 2C 2D 2E 2F 30 и т.д.
Значения чисел в приведенной выше десятичной и
шестнадцатеричной последовательностях, конечно, различны.
Обратите внимание, что после 29Н у вас идет 2АН, а не 30н.
Следующая программа на языке "Бейсик" позволит вам
ввести в ваш "Спектрум" десятичное число и преобразовать его
в шестнадцате- ричное значение.
1 0 0 REM DECIMAL TO HEXADECIMAL CONVERSION
1 1 0 PRINT "PLEASE INPUT DECIMAL VALUE"
1 2 0 INPUT N : PRINT N
1 3 0 LET S& -''': LET N2 = INT(N/16)
1 4 0 LET N1 - INT(N - N2*16)
1 5 0 LET S& - CHR& ((N1<=9)*(N1+48)+(N1>9)*(55+N1)+S&
1 6 0 IF N2 = 0 THEN PRINT : PRINT "HEXADECIMAL - 0" : S&
:"H": FOR I = 1 TO 200: NEXT I: RUN
1 7 0 LET N = N2 : GO TO 140
1 - преобразование десятичных в шестнадцатеричные;
2 - введите, пожалуйста, десятичное значение;
3 - знак заменен на знак &.
Попробуйте преобразовать в шестнадцатеричную систему
следующие числа и с помощью программы на языке "Бейсик"
проверьте свой ответ.
1. 16484 адрес начала дисплейного файла "Спектрум";
2. 22528 адрес начала файла атрибутов "Спектрум";
3. 15360 адрес начала набора литер "Спектрум";
4. 15616 адрес начала литер в коде ASCII "Спектрум".
В ы в о д ы
Десятичная система - это условные обозначения,
позволяющие записывать группами по десять единиц. Эти группы
представляются цифрами 0,1,2,3,4,5,6,7,8,9.
Шестнадцатеричная система - это условные
обозначения, позволяющие записывать группами по 16 единиц.
Эти группы представляются цифрами 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, A, B, C, D, E, F.
Иногда в конце шестнадцатеричного числа добавляется
литера "H" как напоминание о формате представления
числа,например,1800Н.
8- разрядные ячейки памяти
Конструкция "ZX Спектрум" такова, что в каждой
ячейке памяти содержится по 8 битов (пальцев). В каждой
ячейке памяти может храниться число от 0 до 255 (десятичное).
Его удобно представлять в шестнадцатеричном формате в виде
двухразрядного числа.