Воробьёвы

(-:

№2. Введение в курс. Система счисления и поднятие боевого духа

ЛИРИЧЕСКОЕ ПРЕДИСЛОВИЕ

Вы читали "Хроники Амбера" Роджера Желязны?

Там есть такой эпизод:

Главный герой находится в заточении. В абсолютной тьме.

У него были выколоты глаза, но за год они регенерировали и зрение постепенно к нему возвращается...

И однажды каким-то чудом в одной камере с ним оказывается загадочный Дворкин, создатель Лабиринта. Именно "чудом" - он просто появился неизвестно откуда.

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

Удивленный Корвин спрашивает его:

- Как ты оказался в моей камере? Ведь здесь нет дверей...

Дворкин отвечает:

- Двери есть везде. Просто нужно знать, как в них войти...

ВВЕДЕНИЕ В КУРС НИЗКОУРОВНЕВОГО ПРОГРАММИРОВАНИЯ

Попытаемся вас все же отговорить от "колупания" низкого уровня. Ну подумайте хорошенько - какого черта вам это нужно?! В delphi приложения за 5 минут ваяются, а на "асме" знаете сколько?!

У вас что, забот больше в жизни нет, кроме как искать приключений на собственную задницу? Хотите писать программы - пишите. В конце концов если есть задача - для ее решения любые способы хороши... И не имеет большого значения ни объем откомпилированной программы, ни ее требовательность к ресурсам - "машины" нонче знаете какие пошли?! Сплошная крутизна и мегагерцы!

А многочисленные среды для создания приложений!? (Ах, я таю, таю - тащите тазик...). Ни строчки кода! Сплошное кликанье мышкой! Ведь это так круто!

Прогу написать? В два счета! (Я крутой, крутой, крутой). Открываем форму. Небрежная пробежка по многочисленным панелям с компонентами... Кликаем на нужный, перетаскиваем на форму... готово! Объект Button1 типа TButton! Хотите - в виде звездочки будет выглядеть? Ща только 1st Class проинсталлю...

Готово! Окно программы, С КНОПКОЙ - за 5 сек! Полноценное окно и кнопка полноценная! А в окне даже менюшка выскакивает - если в левом вернем углу нажать! И все это - одним легким небрежным движением! Какой там ассемблер? Delphi - вот это вещь!

Бац-бац - и слобал какое-нить бухгалтерское приложение. Бац - и продал его подороже с умным видом какому-нибудь мелкому промышленному предприятию. (Только не признавайтесь никогда, что за вечер слАбали - не правильно поймут.) А бабки состриг - и на пиво есть, и на интернет тоже. Хорррошая жизнь! А коли жизнь хороша - можно и в арканоида с чистой совестью...

А ассемблер? Ну что такое ассемблер? Средневековому мракобесию сродни. Дьявольщина и сатанизм сплошной. Черная магия! Демонов каких-то из преисподней вызывать... Заклинания... call-jmp-mov-nop-ret, чур меня! (Крест животворящий целую, азъ есм иже еси!). А талмуды ассемблерные??? Ето же вообще еретические труды, чертями писаные! Гримуары окаянные, кои, душу сатане не продав, и в руки крещеные взять не можно!

Не, ребята! Не нужен вам asm, ой как не нужен! И страшно, и не пишет на нем уже никто давным-давно!

На улицу достаточно выйти, чтоб все понять. Где вы видели многоэтажный дом из кирпича? Из блоков все сделано - из бло-ков! Ну и что, что разваливается? Строителям тоже жить на что-то нужно! Ну прикиньте, что было бы, если б каждый выстроенный дом не нужно было обслуживать, ремонтировать, что-нить переподгонять, замазывать, маскировать, переделывать, перегре:бывать... А то и было бы, что строители б тогда без работы остались - а кому это нафик нужно?!

Понятна аналогия? Изучение ассемблера - это есть большая идеологическая ошибка. Асм, как язык программирования, должно предать забвению. А его же, но как сотояние души - на "костер" визуального программирования! И MMX-у туда побольше с 3DFX-ом... знаете как рванет???

И не нужно надеяться на то, что скоро будет достигнут "предел минимизации", когда уже нельзя будет на одной и той же площади расположить большее количество транзисторов... Тогда мол, железо будет уже невозможно совершенствовать - начнут совершенствовать софт. Оптимизировать процедуры, избавляться от балласта и все такое... И типа тут ваши знания и востребуются... Не верьте! Они мою сестру обманули! Говорили, что "предел" - это 0.18 микрон, а в газетах пишут, что уже по 0,15-микронной технологии дочерта чего делается!

Короче - намного интереснее на www.outpersonals.com, www.alt.com, www.friendfinder.com и прочие. Интереснее, и для организма полезнее. Идите лучше туда. Там приключения на ваше хм... мягкое место тоже найдуться - но они будут намного приятнее, чем те, которые вы найдете, связавшись с нашим "извращенцким" проектом...

1. КОМПЬЮТЕРНАЯ АРИФМЕТИКА

1.1. Система счисления (radix)

[1] Наверняка среди ваших знакомых есть "крутые" программисты или люди, таковыми себя считающие ;). Попробуйте как-нибудь проверить их "на вшивость". Предложите им в уме перевести число 12 из шестнадцатеричной в двоичную систему счисления. Если над подобным вопросом "крутой программист" будет думать дольше 10 секунд - значит он вовсе не так крут, как говорит...

[2] Система счисления (сие не подвластное человеческой логике определение взято из математической энциклопедии) - это совокупность приемов представления обозначения натуральных чисел. Этих "совокупностей приемов представления" существует очень много, но самая совершенная из всех - та, которая подчиняется позиционному принципу. А согласно этому принципу один и тот же цифровой знак имеет различные значения в зависимости от того места, где он расположен. Такая система счисления основывается на том, что некоторое число n единиц (radix) объединяются в единицу второго разрада, n единиц второго разряда объединяются в единицу третьего разряда и т. д.

[3] "Разрядам" нас учили еще в начальных классах школы. Например, у числа 35672 цифра "2" имеет первый рязряд, "7" - второй, "6" - третий, "5" - четвертый и "3" - пятый. А "различные значения" цифрового знака "в зависимости от того места, где он расположен" и "объединение в единицу старшего разряда" на тех же уроках арифметики "объяснялось" следующим образом:

   35672 = 30000 + 5000 + 600 + 70 + 2
   35672 = 3*10000 + 5*1000 + 6*100 + 7*10 + 2*1
   35672 = 3*10^4 + 5*10^3 + 6*10^2 + 7*10^1 + 2*10^0 (1) 

[4] Очень наглядно это отображают обыкновенные бухгалтерские счеты. Набранное на них число 35672 будет выглядеть следующим образом:

Чтобы набрать число 35672 мы должны передвинуть влево две "костяшки" на первом "прутике", 7 на втором, 6 на третьем, 5 на четвертом и 3 на пятом. (У нас ведь 1 "костяшка" на втором - это то же самое, что и 10 "костяшек" - на первом, а одна на третьем равна десяти на втором - и так далее...) Пронумеруем наши "прутики" снизу вверх - да так, чтобы номером первого был "0"... И снова посмотрим на наши выражения:

35672 = 3*10^4 + 5*10^3 + 6*10^2 + 7*10^1 + 2*10^0 --> это (если сверху вниз считать) сколько на каждом "прутике" "костяшек" влево отодвинуто;

35672 = 3*10^4 + 5*10^3 + 6*10^2 + 7*10^1 + 2*10^0 --> это номер прутика (самый нижний - 0), на котором отодвинуто определенное число костяшек;

35672 = 3*10^4 + 5*10^3 + 6*10^2 + 7*10^1 + 2*10^0 --> это на каждом прутике - по 10 костяшек нанизано, не все влево отодвинуты, но всего-то их - 10!

Кстати, красненькое 10 в последнем выражении соответствует основанию (radix) системы счисления (number system).

(медитируйте)

[5] Пальцев на руках у человека 10, поэтому и считать мы привыкли в системе счисления с основанием 10, то есть в десятичной. Если вы хорошо представляете себе счеты и немного поупражнялись в разложении чисел аналогично выражению 1, то перейти на систему счисления с основанием, отличным от привычной, особого труда для вас не составит. Нужно всего лишь представить себе счеты, на каждый прут которых нанизано не привычные 10 костяшек, а... скажем, 9 или 8, или 16 или 32 или 2 и... попробовать мысленно считать на них.

[6] Для обозначения десятичных чисел мы используем цифры от 0 до 9, для обозначения чисел в системах счисления с онованием менее 10 мы используем те же цифры: radix 9 - 0, 1, 2, 3, 4, 5, 6, 7, 8; radix 8 - 0, 1, 2, 3, 4, 5, 6, 7; radix 2 - 0, 1 и т. д. Если же основание системы счисления больше десяти, то есть больше, чем десять привычных нам чисел, то начинают использоваться буквы английского алфавита. Например, для обозначения чисел в системес числения с основанием 11 "как цифра" будет использоваться буква А: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A; в системе счисления с основанием 16 - буквы от A до F: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F. И так далее... Правда, при определенном основании (при каком?) буквы аглицкого алфавита закончатся... Но нам это пока что глубоко фиолетово, так как работать мы будем только с тремя radix-ами: 10 (ну естественно), 16 и 2. Правда, если кто на ДВК поизучать это дело собирается, тому еще и radix 8 понадобится.

[7] Числа в любой системе счисления строятся аналогично десятичной. Только на "счетах" не с 10, а с другим количеством костяшек.

Например, когда мы пишем десятичное число 123, то имеем в виду следующее:

   1 раз 100 (10 раз по 10) 
   + 2 раза 10 
   + 3 раза 1 

Если же мы используем символы 123 для предоставления, например, шестнадцатеричного числа, то подразумеваем следующее:

   1 раз 256 (16 раз по 16) 
   + 2 раза 16 
   + 3 раза 1

Короче - полный беспредел. Говорим одно, а подразумеваем другое. И последнее - не для красного словца сказано. А потому что так оно и есть...

Истина где-то рядом...

[8] Трудность у вас может возникнуть при использовании символов A, B, C и т. д. Чтобы решить эту проблему раз и навсегда, необходимо назубок вызубрить ма-а-аленькую табличку "соответствия" между употребляемыми в "компьютерном деле" систем счисления:

radix 10   0123456789101112131415
radix 16   0123456789ABCDEF
radix 2    0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111

Следуя этой таблице, число 5BC в шестнадцатеричном формате "строится" так:

   5 раз 256 (16 раз по 16) 
   + 11 раз 16 (10 - потому что по таблице B как бы равно 11) 
   + 12 раз 1

А теперь, если пораскинуть мозгами, с легкостью переведем 5BC из шестнадцатеричной в десятичную систему счисления:

   5*256 + 11*16 + 12 = 1468 

Вот и объединили цифры с буквами. Пространство со временем поучимся объединять немного позже - если не испугаетесь сложностей низкоуровневого программирования.

В общем-то решать вам. В Delphi тоже много чего объединять можно.

[9] Двоичная система по-компьютерному обзывается "bin", "родная" десятичная - "dec", а шестнадцатеричная - "hex". Это так компьютерщики обозвали те системы счисления, с которыми имеют дело... А обозвали потому, что у них ведь полный бардак в голове, оказывается!

Например, 10 - что это за число? Да это вообще не число! Палка и барабан - и только... А вот 10d или же 10_10 - уже понятно, что это - число, соответствующее количеству пальцев на обеих руках. И именно не обеих а не на двух. Почему не на двух? - А потому что на двух в какой системе? Ежели в двоичной, так это на десяти! То бишь 100, если в десятичной...

Вот и придумали программисты после числа буковку писать - b, d или h. А самые линивые еще и директиву специальную придумали: напишут в самом начале программы какай-нибудь .radix 16 и будут автоматически все числа, которые без этих букв, за шестнадцатеричные приниматься.

[10] Еще немного про перевод между "радиксами". (Вообще-то это плевое дело - конечно, если представляешь себе, что такое "совокупность приемов представления обозначения натуральных чисел").

Например, преобразование числа 42936 из десятичного в шестнадцатеричный формат проводится следующим образом (в скобках - остаток):

   42936/16 = 2683(8)         8 - младшая цифра
   2683/16 = 167(11)           B (11d=Bh по таблице)
   167/16 = 10(7)               7
   10/16 = 0(10)                 A - старшая цифра
   ----------------------------------------
   42936d=A7B8h

А вот и обратный процесс - перевод из HEX в DEC числа A7B8h:

   10*16=160 160+7=167 (10 - потому что Ah=10d)
   167*16=2672 2672+11=2683
   2683*16=42928 42928+8=42936
   ----------------------------------------
   A7B8h=42936d

Преобразования чисел в системы счисления с другим основанием проводятся аналогично... Счеты! Обыкновенные бухгалтерские счеты, только с "плавающим" числом "костяшек" на каждом "прутике"...

(медитируйте)

[11] Если чесна, то конкретный "рисунок" цифр - единица там палкой обозначается, двойка - лебледем - это все лишь историческая случайность. Мы запросто можем считать в "троичной" системе счисления с цифрами %, *, _ (где запятая - это знак препинания, а вовсе не число):

%, *, _, *%, **, *_, _%, _*, __, *%%, *%*, *%_, **%... 

Или использовать родные цифры в десятичной системе счисления, но по другому "вектору упорядоченных цифр" - 1324890576

   1, 3, 2, 4, 8, 9, 0, 5, 7, 6, 31, 33,34, 34,38, 39, 30, 35, 37... 

Правда, этим немножко затрудняется понимание происходящего? А ведь тоже десятичная система! И рисунок цифр как-бы знакомый :-)))

Или вообще считать в 256-ричной системе счисления, используя в качестве "рисунка цифр" таблицу ASCII-символов! (По сравнению с вами-извращенцами любой Биллгейтс будет девственником казаться!!).

[12] Теперь самая интересная часть Марлезонского балета.

Компьютер, как известно, считает только в двоичной системе счисления. Человеку привычна десятичная. Так нахрена еще и шестнадцатеричную какую-то знать нужно?

Все очень просто. В умных книжках пишут, что "шестнадцатеричная нотация является удобной формой представления двоичных чисел". Что это значит?

Переведите число A23F из шестнадцатеричной "нотации" в двоичную. (Один из возможных алгоритм приведен в п. 10.). В результате длительных манипуляций у вас долно получиться 1010001000111111.

А теперь еще раз посмотрите на таблицу в п. 8. (которую вы как бы уже и выучили) и попробуйте то же самое сделать в уме :

   Ah=1010b
   2h=0010b
   3h=0011b
   Fh=1111b

A23Fh = 1010 0010 0011 1111b 

Каждой шестнадцатеричной цифре соответствует тетрада (4 штуки) ноликов и единичек. Все, что потом нужно сделать - "состыковать" эти тетрады. Круто? Вас еще не то ждет!

[13] Кстати (наверняка вы это уже знаете):

00000123 = 123 но, 
123 <> 12300000 

... но это так... кстати...

[14] И, напоследок, еще несколько слов про HEX и BIN :). Зайдите в Norton Commander, наведите указатель на какой-нить файл и нажмите там F3. А когда он откроется - на F4. Там какие-то нездоровые циферки попарно сгруппированы. Это и есть "нолики и единички" (которыми в компьютере все-все-все описывается) но в шестнадцатеричном формате...

(медитируйте)

ПРЕДУПРЕЖДЕНИЕ

Следует основательно разобраться с системой счисления. Минимум, что должен вынести из этой главы юзвер, вступивший на скользкий путь низкоуровневого программирования - это научиться переводить числа между DEC, HEX и BIN... хе-хе... В УМЕ!

ПОДНЯТИЕ БОЕВОГО ДУХА

Прежде чем начать программировать на "низком уровне", необходима небОльшая теоретическая подготовка. Однако мы допускаем, что небольшое теоретизирование в самом начале курса отпугнет определенное количество дZенствующих программеров. А посему, прямо ща :) мы предлагаем вам написать вашу первую низкоуровневую программу.

Внимательно следуйте нижеследуемой инструкции и очень быстро достигните потрясающего результата!!! (R).

1. По "адресу" (предположительно) C:\WINDOWS\COMMAND\ находится одна замечательная программулька. DEBUG.EXE ее "имя собственное". Перекреститесь и запустите ее.

Все что у вас должно появиться на мониторе - это белый "-" на черном фоне. Только это не просто "минусик", а ПРИГЛАШЕНИЕ. Приглашение че-нибудь ввести.

2. Вот и вводим :) буковку "a" (аглицкое, регистр значения не имеет).

После нажатия на букву "Enter" :) на монитор должно вывалиться что-нибудь похожее на 119B:0100. Это "адрес памяти" (сегмент + смещение), в который мы сейчас запихнем нашу программу (первая часть адреса может быть любая).

3. Белым по черному пишем загадочную команду int 18. Жмем на Enter.

Вывалится что-нибудь вроде 119B:0102. Игнорируем и снова жмем на Enter. Должен снова появиться "-". Снова типа приглашение...

4. Вводим после "минусика" r cx. В ответ на это напечатается CX 0000. И ниже - ":". После этого самого ":" вводим цифру "2" и снова жмем на Enter. Снова появится приглашение - "-".

5. Дальше на "приглашение" вот что отвечаем: n reboot.com. Жмем на Enter. Снова "минусик" выскочил.

6. Последний шаг. Вводим букву (команду) "w" после минусика и жмем на Enter. Должно всплыть сообщение "Запись: 00002 байт". Если оно появилось - значит все нормально.

7. Вводим команду "q" (от аглицкого Quit), жмем на Enter и вываливаемся из этой программульки нафиг.

8. Теперь "по адресу" C:\WINDOWS\COMMAND\ у вас находится еще одна программулька - reboot.com объемом всего лишь в 2 байта (мы ее только что написали). Запустите ее из "_чистого_" DОSa и посмотрите чего будет...

(дZенствуйте до следующего понедельника)

АНОНС

В следующий понедельник - более детальное знакомство с debug.com. А также: регистры, адресация памяти, прерывания и т. д. и т. п.