Цю статтю а точніше відрізок з книги біблія дельфі я вирішив розмістити щоб початківець в програмуванні познайомився з логікою комп’ютера.

Основні принципи роботи комп’ютера
1.1 Основи роботи персонального комп’ютера.
Перш ніж програмувати комп’ютер, ми повинні зрозуміти, як він працює.
Як казав якийсь полководець: «Треба добре вивчити свого ворога!!!».
Можливо, це говорив і не полководець, але це не важливо :). Кодинг це
постійна боротьба з машиною. Потрібно змушувати її робити те, що тобі потрібно. Тому
будь-який програміст просто зобов’язаний знати його нутрощі.
Комп’ютер складається з наступних основних компонентів: процесор, пам’ять,
відеокарта, вінчестер (жорсткий диск) і різні роз’єми для підключення
додаткових пристроїв. Усі ці компоненти пов’язані між собою з допомогою
шлейфів і шин.
Вся інформація в комп’ютері зберігається на вінчестері. Коли ти запускаєш яку-
небудь програму, то вона спочатку завантажується в пам’ять і тільки потім процесор
починає виконувати в ній містяться інструкції. Чим більше програма, тим довше
вона завантажується.
Результат роботи програми виводиться на екран через відеокарту. На будь –
відеокарті є чіп пам’яті, в якому відображається весь вміст екрану. Коли тобі
потрібно вивести на екран, ти просто копіюєш ці дані в відеопам’ять, і
відеокарта автоматично виводить його вміст на монітор.
Це все, що необхідно знати про роботу комп’ютера. Поки я описати тільки загальні
риси, а в наступних розділах я опишу необхідні речі більш докладно. В основному
нас буде цікавити робота процесора, тому йому я приділю особливу увагу.
Решта поки достатньо знати в загальних рисах.
1.2 Двійкова система роботи процесора.
омпьютеры винайшли досить давно. В ті часи електронікою навіть і не
пахло. Перші комп’ютери були ламповими і займали дуже багато місця.
Для того, щоб керувати такою махиною потрібно було дуже багато
обслуговуючого персоналу.
Вже тоді був закладений принцип роботи комп’ютера, який діє досі.
А саме, дані передаються за допомогою якогось сигналу (для нас не має значення
якого, тому що ми не електронники) методом «є сигнал чи ні» або по-іншому
«включений або вимкнений». Так з’явився «біт» bit. Біт це одиниця інформації, яка
може приймати значення або 0, або 1, тобто «включений або вимкнений». Вісім біт
об’єднуються у байт, тобто один байт дорівнює 8 бітам. Чому саме 8? Та тому що
перші комп’ютери були восьми розрядними і могли працювати одночасно тільки з 8-
ю бітами, наприклад, 010000111.
Трохи пізніше ти дізнаєшся, що в один байт можна записати будь-яке число до 255. Але
це дуже мало, тому частіше використовують більш великі градації:
1. Два байти = слово.
2. Два слова = подвійне слово.
Отже, комп’ютер став працювати в двійковій системі числення. Але як же тоді
записати число 135, якщо у нас одиниця інформації може бути тільки або 0 або 1.
Просто в двійковій системі. Давай розберемося, як це працює.
П
До
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
9
Для початку згадаємо, як працює наша десяткова система числення, до якої
ми звикли. Для цього розглянемо число 519578246. Я спеціально вибрав таке число,
щоб воно складалося з восьми розрядом. Тепер запишемо його, як на малюнку нижче:
Як бачиш, я пронумерував розряди, починаючи з нуля до восьми, і справа наліво.
Тепер уяви собі, що це не ціле число, а просто набір розрядів. 5, 1, 9, 5, 7, 8, 2, 4
і 6. Як з цих розрядів отримати ціле число? Напевно деякі скажуть, що треба
просто записати підряд. А якщо я запитаю, чому? Ось тут з’являється математика.
Потрібно кожен розряд помножити на 10 (ступінь обчислення) зведену на ступінь
номери розряду. Незрозуміло? Спробую оформити у вигляді формули:
Давай порахуємо по цій формулі, починаючи з нульового розряду. Виходить, що 6
потрібно помножити на 10 в нульовому 6*100=6. Потім додати 4*10 в 1 ступеня
4*101= 40 (разом вже 46). Потім 2*10 в другій ступені 2*102=200 (разом 246). Потім
8*10 в 3 ступеня 8*103= 8000 (разом 8246) і так далі. У підсумку вийде число
519578246.
А тепер розглянемо двійкову систему. Тут кожен розряд може бути або 0 або
1 (2 стану). До речі, в десятковій системі у нас кожен розряд міг бути від 0 до 9, то
є десять станів. Давай розглянемо наступний байт — 010000111. Запиши його на
аркуші паперу так, як показано на малюнку нижче.
Тут діє та ж сама формула, тільки потрібно зводити в ступінь не 10, а
двійку. Знову ж зробимо розрахунок, починаючи з нульового розряду, тобто справа наліво.
Виходить, що першу 1 ми повинні помножити на 2 нульової ступеня (1*20=1).
Наступну одиницю потрібно помножити на 21 виходить 2 (разом 2+1=3) і т. д. Ось як це
буде виглядати повністю:
(1*20)+(1*21)+(1*22)+(0*23)+(0*24) +(0*25) +(0*26) +(1*27) +(0*28)=135.
Ось так, виявляється, виглядає в двійковій системі число 135. Давай тепер
навчимося рахувати числа з десяткової системи в двійкову систему. Для цього
потрібно число 135 розділити на 2. Виходить 67 і залишок 1 (запам’ятаємо 1). Тепер ділимо 67
на 2, виходить 33 і залишок 1 (тепер дві одиниці, тобто 11). Тепер 33 ділимо на 2,
отримуємо 16 і залишок 1 (тепер три одиниці, 111). Тепер 16 ділимо на 2, отримуємо 8 і
залишок 0 (всього 0111). Тепер 8/2=4 і залишок 0 (00111). 4/2=2 і залишок 0 (000111).
Тепер 2/2=1 і залишок 0 (разом 0000111). 1 на два не ділиться, значить, просто дописуємо
її 10000111. Вийшло початкове число.
Ось так відбувається перетворення чисел. В двійкову систему числення. Таким
же чином можна перевести число в будь-яку систему (двійкова, вісімкова,
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
10
шістнадцяткова і т. д). Для більш повного закріплення матеріалу я вирішив привести
таблицю, в якій показано відповідності десяткових чисел двійковим. Спробуй сам
перевести пару чисел туди і назад.
Десяткове Двійкове
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
Таблиця 1. Таблиця відповідності десяткових і двійкових чисел
У комп’ютері прийнято вести розрахунок в двійковій або шістнадцятковій системі.
Друга увійшла в ужиток, коли комп’ютери стали 16-розрядними.
Шістнадцяткова система виглядає трохи по-іншому. Кожен розряд вже
містить 2 стану (як в двійковій) або десять (як у десятковій), а шістнадцять.
Тому один розряд може приймати значення від 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
Літера «A» відповідає 10, «В» відповідає 11 і т. д. Наприклад, число 1A у
шістнадцятковій, одно 26 дес. Чому? Та все те ж формулою. Тільки
тут потрібно зводити 16 ступінь номера розряду. «A» — це десять, потрібно помножити на
160 = 10. 1 перший розряд потрібно помножити на 161 =16. 10+16=26.
Десяткове Двійкове Шістнадцяткове
0 0 0
1 1 1
2 10 2
3 3 11
4 100 4
5 101 5
6 110 6
7 111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F
16 10000 10
17 10001 11
18 10010 12
19 10011 13
20 10100 14
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
11
Таблиця 2. Таблиця відповідності десяткових, двійкових і шістнадцяткових чисел
Протягом всієї книги ми будемо іноді зустрічатися з
шістнадцятковій системою обчислення (без цього нікуди не дінешся),
тому, коли потрібно буде показати, що шістнадцяткове число, я
буду ставити перед ним знак решітки #, наприклад, #13. В інших мовах,
наприклад Assembler або C++ прийнято ставити в кінці числа літеру h,
наприклад, 13h. Але ця книга про Delphi, тому я буду писати так, як
прийнято в середовищі розробки, щоб потім не виникало ніяких
проблем.
Але це всі цілі числа. З числами з плаваючою точкою зовсім інша історія.
Якщо заздалегідь передбачено, що число може бути негативним, то його довжина
скорочується рівно на один біт. Якщо невід’ємне ціле число може бути 8-ми
бітним, то число зі знаком буде 7-й бітовим. Перший біт буде означати знак. Якщо
перший біт дорівнює 1, то число від’ємне, інакше позитивне.
В дробових числах один байт може бути відведений для цілої частини і один для
дробової. Ніколи не змішують цілу і дробову частину в одне ціле. За рахунок цього,
дробові числа завжди будуть займати більше пам’яті, і операції з ними проходять
набагато довше.
На перший погляд переклад чисел дуже складний, але вручну їм користуватися не
обов’язково. Людина вже давно придумав для себе хорошого помічника — калькулятор. З
його допомогою без проблем можна перевести число в будь-яку систему.
Запусти вбудований калькулятор Windows (Пуск -> Програми -> Стандартні ->
Калькулятор).Тепер вибери з меню «Вид» команду «Інженерний». На рисунку нижче
показано вікно, яке ти повинен побачити:
Зовнішній вигляд калькулятора
Для переведення числа в іншу систему, просто набери його і потім вибери потрібну
систему числення. На малюнку я обвів червоним кольором кнопки перемикання системи
обчислення:
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
12
Hex шістнадцяткова.
Dec десяткова.
Oct вісімкова.
Bin двійкова.
Виникає питання навіщо я тоді так довго розповідав про перетвореннях, коли
так легко скористатися калькулятором? Відповідь проста ТРЕБА. Повір мені. Якщо ти
будеш розуміти, як відбувається перетворення, то тобі легше потім буде працювати з
цими числами.
Ніколи не покладайся тільки на техніку. Завжди корисно знати, як і навіщо
вона щось робить. Якщо ти впораєшся з шістнадцятковим
поданням даних, то зможеш прості перетворення робити в
розумі. Ну а якщо ти ще збираєшся стати хакером, то тобі просто
необхідно навчиться добре оперувати різними системами числення.
1.3 Машинний мову.
анний на диску зберігаються у двійковому вигляді. Навіть текстові файли
диску виглядають у вигляді нулів і одиниць. Точно так само виглядає і будь-яка
програма, тільки її називають машинним кодом. Давай з ним познайомимося
трохи ближче.
Будь-яка програма являє собою послідовність команд. Ці команди
називаються процесорними інструкціями. За цим інструкціям процесор визначає,
що і як йому потрібно робити. Коли ти запускаєш програму, комп’ютер завантажує її
машинний код в пам’ять і починає виконувати. Наше завдання, як програмістів написати
ці інструкції, щоб комп’ютер зрозумів, що ми від нього хочемо.
Реальна програма, яку виконує комп’ютер, являє собою
послідовність одиниць і нулів. Таку послідовність називають машинним
мовою. Але людина не здатна ефективно думати одиницями і нулями. Для нас легше
сприймається осмислений текст, а не божевільні числа в двійковій системі
вимірювання, з якої ми не звикли працювати. Наприклад, команда складання двох
регістрів виглядає так: #03C3. Нам це мало про що говорить, і запам’ятати таку команду
дуже важко. На багато простіше написати «скласти число1+ число2».
Перший час програмісти писали в машинних кодах, поки комусь не прийшла в
голову ідея: «Чому б не писати текст програми на зрозумілій мові, а потім
змушувати комп’ютер перекладати цей текст в машинний код?». Ідея дійсно
заслуговувала на увагу. Так з’явився перший компілятор програма, яка
перекладала текст програм в машинний код.
Ось тут, я думаю треба зробити паузу і розповісти тобі невелику історію мов
програмування. Вона досить цікава і повчальна. Ну а потім ми продовжимо
вивчення принципів роботи комп’ютера і познайомимося з вмістом процесора і його
роботою.
1.4 Історія мов програмування.
Д
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
13
як ми вже з’ясували, комп’ютер — примітивне істота, яка мислить
нулями та одиницями, з яких складаються числа. Так що все, що може
робити процесор, так це оперувати цими числами. Так і програми — це
теж числа, які сприймаються процесором команди до виконання якихось
дій.
Ми також з’ясували, що перші програмісти писали програми в машинних
кодах. Тоді ще не було компіляторів і доводилося все писати числами. Ти навіть
уявити собі не можеш, який це пекельна праця. Постійно тримати в пам’яті таблицю
машинних кодів — це тобі не таблиця множення. Наприклад, тобі зрозуміло число 8BC3.
Ні? А це проста команда копіювання між двома осередками регістрів. Це просто
приклад, тому що тоді регістри були інші процесори були на багато простіше.
Згодом комп’ютер став розумнішати. Він все так же оперував числами, але робив
це набагато швидше. Але програміст — це людина, а не залізка і йому дуже важко
створювати логіку в числах. Набагато легше працювати з звичними словами. Наприклад, усі
ту ж команду зручніше записати словами типу «скопіювати ebx в eax». Але що робити,
якщо комп’ютер не розуміє слів, а тільки числа? Вихід є — написати таку
програму, яка буде перетворювати текст в машинні коди. Нехай комп’ютер сам
створює байт-код. Таку програму назвали компілятором. А мова, на якому писався
текст програми, назвали мовою програмування.
Програма в машинних кодах і Assembler
І ось був написаний перший компілятор. Цю програму назвали Assembler, що
перекладається, як «складальник». Писати на ньому практично так само, як і в машинних кодах,
тільки тепер вже використовувалися не числа, а зрозумілі людині слова. Наприклад, все та
команда копіювання регістрів тепер виглядала так: «mov eax, ebx». Тобто цифри
замінилися на зрозумілі слова.
Начебто все чудово і зручно, але чомусь серед програмістів виникли суперечки і
розбіжності. Хтось сприйняв новий метод із задоволенням. А хтось казав, що
машинні коди краще. Любителі мови Assembler хвалили компілятор за те, що
До
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
14
програмувати стало простіше і швидше, а противники стверджували, що програма,
написана в кодах, працює швидше. Кажуть, що ці суперечки доходили до бійок і іноді
кращі друзі ставали ворогами. А в принципі, і ті й інші мали рацію. Мовою
Assembler дійсно програму писати легше і швидше, а в машинних кодах
програма працювала швидше.
Тоді ніхто не міг собі уявити, чим все може закінчитися. Але час
показало своє. З допомогою Assembler програми писалися швидше, а це один з
основних факторів успіху будь-якої програми на ринку. Люди починають користуватися тим
продуктом, який виходить на ринок першим. Навіть якщо більш пізній варіант краще,
людину важко переконати перейти на іншу версію. Тут відіграє велику роль
фактор звички. До того ж, до того моменту, коли програміст напише свою першу
версію в машинних кодах, програміст на мові Assembler випустить вже пару нових
версій свого шедевра.
Ось так і вийшло, що ті, хто програмував на мові Assembler перетворилися
у тікають вперед, а ті, хто програмував в машинних кодах перетворився на вічно
наздоганяючих. Зрештою, перші втекли на стільки, що другі не змогли наздогнати,
і змушені були або перейти на Assembler або відійти від програмування на зовсім.
Ось тут почався бум. Мови програмування стали з’являтися один за іншим.
Так з’явилися, ADA, FoxPro, Fortran, Basic, Pascal та інші. Деякі з них були
призначені тільки для дітей, а деякі і для професійних програмістів. І
тут спори перенеслися в іншу площину — яку мову краще. І ця суперечка триває вже
близько 30 років і кінця йому не видно. Деякі говорили, що це Pascal, інші
стверджували що З, ну а дехто стверджував, що це Visual Basic. Цей спір розділився на
дві частини:
1. Яку мову найкращий?
2. Що краще — мова високого або низького рівня?
Перший спір не може закінчитися досі. Кожен намагається довести, що його
мова програмування самий потужний, зручний і створює найшвидший код. Мені
здається, що цей спір не закінчиться ніколи. В принципі, мене це влаштовує, бо
що це своєрідна конкуренція. Завдяки їй відбувається розвиток і ми летимо вперед.
Так все ж, якою мовою краще? На це питання я дам відповідь, але тільки трохи пізніше.
Найбільш цікавим був спір: «Що краще — мова високого або низького рівня?».
Мова низького рівня це той, який найбільш наближений до команд процесора, то
є Assembler. До мов високого рівня відносять С, Pascal, Basic та ін Цей спір
проходив в тій же манері, як і суперечка між любителями Assembler і любителями
програмування в машинних кодах. Тільки тепер прихильники Assembler
стверджували, що їх код найшвидший, а любителі мов високого рівня стверджували,
що вони напишуть програму швидше, ніж найкращий програміст мовою
Assembler.
Суперечка тривав досить довгий час. І знову перемогла швидкість розробки
та зручність мови програмування. Любителям Assembler довелося відступити, бо
що тепер вони перетворилися в «наздоганяючих», і не змогли наздогнати мовами високого
рівня.
Звичайно ж, не можна сказати, що машинні коди і Assembler на зовсім пішли з
нашого життя. Вони використовуються до цих пір, але в дуже обмеженій кількості. Мова
Assembler використовується тільки в якості вставок для мов високого рівня, а
машинні коди використовуються для написання того, чого не можна зробити компілятором (так
і для написання самого компілятора вони потрібні). Пішли технології живуть, і будуть
жити, але рядовий програміст дуже рідко зустрічається з ними.
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
15
Наступною сходинкою стало об’єктно-орієнтоване програмування. Мова З
перетворився в С++, Pascal перетворився у Object Pascal і так тримати. І знову боротьба. І
знову швидкість розробки проти швидкості коду. Знову суперечки, бійки і образи.
Війна тривала кілька років. Скільки часу було витрачено у спорах, скільки
волосся на голові було вирвано в процесі доказів крутизни саме його коду. А
результат — перемогла швидкість і зручність розробки, тобто об’єктно-орієнтоване
програмування (ООП).
Останньою великою революцією відбувається в програмуванні я вважаю
перехід на візуальне програмування. Цей перехід відбувається прямо на наших
очах. Візуальність дає нам ще більш зручні засоби розробки для більш
швидкого написання коду, але програє ООП по швидкості роботи. Ось багато
початківці і стоять на перехресті, яку мову обрати.
Лідерів у візуальних мовах є Borland, а прихильником ООП залишається
Microsoft. Звичайно ж, Білл Гейтс намагається вбудувати в свої мови візуальність, але вона
примітивна порівняно з такими гігантами, як Delphi, Kylix або C++ Builder. Це
пов’язано з початковою дірою MFC, яка не може працювати візуально. Потрібна
глобальна переробка коду, яку чомусь не хочуть робити. Ось народ і стоїть на
двох атомних бомбах і чекає вибуху однієї з них. Як ти думаєш, яка бомба
рвоне? Що переможе — швидкість розробки або швидкість коду? Я не буду відповідати на це
питання. Історія говорить сама за себе, а ми почекаємо підтвердження цьому.
Я вважаю, що прогрес не буде стояти на місці і перехід на нові технології
програмування рано чи пізно відбудеться. Тому я вже перейшов на Delphi. Якщо ти
хочеш встигнути за прогресом, то ти теж зобов’язаний вступити в партію любителів Borland.
Вибирай будь-який з його компіляторів, і ти не помилишся. Для тебе є все, що завгодно
Delphi, JBuilder, Kylix або C++ Builder. Як бачиш у Бормана є візуальні варіанти
всіх мов, і вони дійсно кращі.
Я вже сказав, що найкраща технологія — візуальність. Твоя середовище розробки
просто зобов’язана бути візуальної, тому що за цим наше майбутнє. Якщо ти хочеш
отримати візуальність + міць розробки, то твоя середовище від Borland. З допомогою мов
цієї фірми можна зробити абсолютно все. Так що з цим ми покінчили. Вердикт
остаточний і оскарженню не підлягає.
Мені залишилося тільки відповісти на запитання: «Яку мову програмування краще?». Я
вже кілька років намагаюся відповісти на це питання, але остаточного рішення винести
не можу. Навіть у того ж Visual C++ від Microsoft є свої плюси. Як це не дивно, але
позитивні сторони є у всіх. Питання залишається лише за тим, що ти будеш
писати? Я можу дати приблизно таку градацію:
1. Якщо ти будеш писати бази даних, програми загального значення або утиліти, то
твій мова Delphi чи C++ Builder.
2. Якщо це ігри, то бажано Visual C++ або Watcome C плюс знання Assembler.
Але це не означає, що не можна використовувати Delphi чи C++ Builder. В цих середовищах ти
втратиш не набагато більше швидкості роботи, тому на більшості ігор можна не
звертати уваги на цю втрату.
3. Якщо це будуть драйвери і робота з залізом, то тут критичний розмір файлу
значить твій язик чистий або Assembler.
І все ж більшу масу програм посідають утиліти і бази даних. А тут
візуальність необхідна, якщо ти хочеш опинитися попереду. Візуальні мови
жити і за ними майбутнє. І протягом всієї цієї книги я буду тобі розповідати про
самий кращий (на мій погляд, і він може відрізнятися від інших) — Delphi.
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
16
1.5 Виконання машинних інструкцій.
режде ніж переходити далі, я повинен познайомити тебе з кількома
поняттями:
Сегмент це просто область пам’яті. Раніше, коли операційні
системи (ОС) були 16 біт, процесор не міг працювати з пам’яттю розміром більш 64
кілобайт (це максимум, що можна записати у два байти). Тому пам’ять ділилася на
сегменти за розміром і за призначенням. На даний момент ми використовуємо 32-ю ОС,
яка може адресувати до 4 Гбайт оперативної пам’яті. Тому можна сказати, що
пам’ять стала суцільною. Але поділ за призначенням все-таки залишилося. Існують
наступні сегменти пам’яті:
Сегмент коду в цю область пам’яті завантажується машинний код, який
буде потім виконуватися процесором.
Сегмент даних це область пам’яті для зберігання даних.
Сегмент стека область пам’яті для зберігання тимчасових (локальних)
даних і адреси повернення з процедур.
Кожній запущеній програмі відводиться свій сегмент коду, даних і стека.
Тому дані однієї програми не можуть перетинатися з даними або інший кодом
програми, якщо звичайно ж не стався збій.
Регістр комірка пам’яті в процесорі. Розмір комірок залежить від його розрядності. В
32-х розрядних процесорах осередку 32-бітні. Ми будемо говорити про 32-х розрядних
процесорах, а значить і про 32-х бітних регістрах. Таких осередків там декілька, і кожна з
них призначена для певних цілей. Один регістр складається з двох комірок, значить в
32-бітному процесорі регістр дорівнює 2*32=64 біт.
Коли комп’ютер був ще 16 бітним, всі регістри були теж 16-бітними. З
появою 32-ї платформи розмір чарунки регістра теж збільшився, до 32 біт. Але для
сумісності зі старими програмами вони ніби поділяються на дві частини (ті ж дві
клітинки). Перша це той старий регістр, а друга додаткові 32 біт. На словах не
зовсім зрозуміло, тому давай подивимося на малюнок.
На цьому малюнку показаний регістр EAX. Повна довжина 32 біта, але молодша
половина це регістр АХ (16 бітний варіант регістра). Тобто, якщо ми попросимо
процесор показати нам вміст регістра АХ, то ми побачимо половину регістра ЕАХ.
Іноді це дуже навіть зручно, особливо коли тобі треба прочитати тільки половину
числа з регістра.
Тепер реальний приклад. Припустимо, в регістрі ЕАХ знаходиться шістнадцяткове
число #21CD52B, тоді в регістрі АХ перебуватиме останні 16 біт, а саме
D52B.
Зараз я почну опис регістрів, і якщо його ім’я починається з букви «Е», то це
значить, що він 32-бітний і для нього існує і 16-бітний варіант без букви «Е».
П
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
17
Сегментні регістри — CS, DS, SS і ES. (є ще, але нас цікавлять тільки
ці):
Регістр CS — регістр сегменту коду, в ньому зберігається початковий адресу
сегмента коду.
Регістр DS — регістр сегмента даних, в ньому зберігається початковий адресу
сегменту даних. У цьому сегменті розташовуються глобальні змінні.
Регістр SS — регістр сегмента стека, в ньому зберігається початковий адресу
сегмента стека. Тут розташовуються локальні змінні.
Регістр ES. Для використання додаткового сегментного регістра.
Різницю між глобальними і локальними змінними ми розглянемо трохи
пізніше, коли будемо вивчати сама мова програмування. Зараз я ще скажу тільки те,
що в сегменті зберігаються і змінні, які передаються процедури та адреса
повернення з процедури (куди потрібно повернутися по закінченню виконання коду
процедури).
Регістри загального призначення EAX, EBX, ECX і EDX, всі ці регістри 32-х
бітні. У 16-розрядних процесорах, вони були 16-розрядними і називалися AX, BX, CX
і DX. Вони можуть використовуватися в програмі на власний розсуд, але в
деяких випадках їм відведена певна роль. В регістр EAX в основному
записуються результати арифметичних обчислень, а регістр ЕСХ використовується в
якості лічильника. Регістр EAX використовується для зберігання результатів обчислення.
Дуже часто, перш ніж виконати якусь команду, процесор завантажує
необхідні дані в регістри і тільки після цього виконує необхідну
інструкцію. Але можливі варіанти, коли обчислення йдуть безпосередньо з пам’яттю.
Реєстрові покажчики ESP і EBP. ЕЅР — це покажчик стека, який
забезпечує його використання в пам’яті. ЄВР забезпечує доступ до даних і
вказівниками на дані передаються через стек.
Індексні регістри ЕЅІ і ЕDI. Ці регістри використовуються при складанні і
відніманні, а так само для розширеної адресації.
Якщо ти збираєшся писати простенькі утиліти або бази даних,
ці знання ти не будеш використовувати. Але якщо ти хочеш піти далі,
то бажано не просто знання, але й розуміння процесу роботи
процесора. Тому я зараз спробую на пальцях (а точніше сказати на
прикладі) пояснити процес його роботи.
Отже, зараз я опишу процес виконання програми більш докладно. У будь-якому
випадку, це тобі придасться.
При старті програми, виконуваний код завантажується в сегмент коду. Регістр CS
відразу встановлюється значення, що вказує на початок цього сегмента. Дані
програми завантажуються в сегмент даних (це константи і будь-які інші
додаткові дані). На цьому ж етапі відбувається підготовка (ініціалізація) до
роботі сегмента стека. Якщо програмі передані які-небудь значення, то вони
автоматично заносяться в стек.
Сегменти коду містить код тільки однієї програми. В один сегмент не
може бути завантажений код двох абсолютно різних програм. Точно так само
і сегмент даних, сегмент стека. При кожному старті нової програми,
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
18
операційна система відводить її власні сегменти коду, даних
і стека.
Після цих підготовчих дій, ОС готова до виконання коду. Нагадаю,
що регістр CS вказує на початок сегменту коду. Є ще один регістр, про який я
ще не сказав EIP. Цей регістр вказує на поточну виконувану команду в
сегменті коду.
Процесор послідовно виконує всі команди, що знаходяться в сегменті коду.
Іноді необхідно перескочити не на наступну точку програми, а зовсім в
інше місце. В цьому випадку відбувається такий перехід, і команди починають
послідовно виконуватися, вже починаючи з нової точки.
Я вже сказав, що будь-які операції, обчислення можуть виконуватись з регістрами і
з пам’яттю. Наприклад, до значення регістра EAX додати значення EBX це додавання
регістрів. Можна складати й значення знаходяться в оперативній пам’яті. Але треба
пам’ятати, що обчислення з регістрами відбувається набагато швидше, тому що регістр
це та ж оперативна пам’ять, тільки знаходиться в процесорі. Якщо ти збираєшся
провести з одним і тим же числом дві операції, то набагато ефективніше буде
розташовувати його в регістрі.
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
19
Розділ 2. Машинна математика.
про перебудови, в нашій країні практично не навчали програмістів.
Більшість програмістів були вихідцями з кафедр математики, на
яких дуже часто були якісь предмети з ухилом в бік
інформатики. На цих курсах вчили писати блок-схеми це схема, що описує логіку
програми.
Я з блок-схемами познайомився на першому курсі інституту. Перше враження
повне фуфло. Але з часом я зрозумів їх гідності. Можливо, тобі здасться це
занадто просто, але все ж бажано прочитати цю главу повністю. Тут я розповім
теорію всього процесу програмування. Надалі нам залишиться тільки
познайомиться з практикою, і ми на коні O.
2.1 Основи машинної математики.
а будь-якій мові програмування можна виконувати математичні
операції будь-якої складності. Delphi не виняток. Але поки що ми не будемо
розглядати всі можливості, а зупинимося лише на основних. Ось
основні математичні операції мови Delphi:
Математична
операція
Опис
* Помножити
/ Поділити
Sqr Квадрат
Корінь Квадратний корінь
+ Додавання
— Віднімання
:= Присвоїти значення.
Математичні операції
У таблиці перераховані основні математичні операції мови
програмування Delphi. Вони виконуються у тому ж порядку, в якому перераховані.
Наприклад, у формулі 2+2*2 результатом буде 6, тому що спочатку виконується
операція множення, а потім додавання. Якщо ти хочеш спочатку виконати додавання, а
потім віднімання, то як і в простій математиці повинен використовувати дужки: (2+2)*2=8.
В цьому випадку результат буде зовсім іншим.
Для вивчення комп’ютерної математики ти повинен знати такі поняття:
Мінлива це пам’ять, в яку можна записувати різні значення. Частіше
всього цієї пам’яті присвоюється у відповідність ім’я. Наприклад, я заводжу змінну з
іменем F. Їй я можу присвоювати значення, наприклад 5. Для цього мені потрібно записати
F:=5. Знак двокрапка + означає операцію «привласнити».
Значення змінних можна копіювати з однієї в іншу. Припустимо, що у мене
є ще одна змінна G. Я можу присвоїти їй значення змінної F за допомогою
простого присвоювання G:=F. Після цього змінної G у мене теж буде значення 5.
Д
Н
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
20
Змінної можна присвоювати результати якихось обчислень, наприклад:
F:=10/2. Це досить простий приклад. А ось вже ціле вираз з використанням
змінних:
F:=5;
G:=10;
F:=G/2;
Ім’я змінної може складатися як з однієї літери, так і з декількох букв.
Наприклад, ім’я змінної може бути: Str, або MyPeremen. Єдине обмеження
ім’я повинно складатися з англійських літер і не повинно використовувати зарезервовані
слова (про зарезервованих словах трохи пізніше). Ти так само можеш імені
використовувати числа (бажано в кінці), наприклад Str1, Str2, Str3 і так далі.
Моя тобі порада, призначай змінним осмислені імена. Коли ти
почнеш писати великі програми, важко буде розібратися, що
означає змінна i або b. Бажано давати осмислені імена. В
протягом всієї книги я постараюся тебе до цього привчити.
Тип змінної тип значення, яке можна записати в змінну (в пам’ять).
Дуже часто використовують термін «Тип даних», тому що це дійсно тип даних
зберігаються в змінної. Він показує, якого типу інформація знаходиться в
конкретної змінної. У Delphi прийнято обов’язково вказувати типи змінних,
щоб одразу можна було побачити яку інформацію можна туди записати.
Існує кілька основних типів змінних:
Назва типу Опис Додаткова інформація
Integer Ціле число Змінна цього типу може приймати в
значення будь-які цілі числа, як
позитивні, так і негативні.
Real Дійсне число Змінна цього типу може приймати в
значення цілі і дробові числа з
знаком і без.
String Рядок Змінна цього типу може приймати в
значення усі символи та набори
символів.
Boolean Логічне значення Може приймати значення true або false
(true або false). Цей тип дуже часто
використовується для організації логіки.
Основні типи даних в Delphi
Це тільки основні типи. Реально їх набагато більше. Коли ми перейдемо до
програмування, я познайомлю тебе з великою кількістю типів даних.
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
21
Рядки будь-які символи та набори символів. У мові Delphi вони виділяються
одинарними лапками, наприклад, Привіт. Рядки так само можна присвоювати
змінним, як і будь-яке інше значення.
Str символьна змінна.
Str:=Привіт!!!
На цьому основні відомості про машинної математики підійшли до кінця. Пора
застосувати наші знання на практиці.
2.2 Блок-схеми.
авай одразу поставимо який-небудь простий приклад, на якому спробуємо
розписати логіку його рішення. Припустимо, нам треба отримати твір
двох чисел. В людській логіці ми повинні виконати наступні
операції:
1. Старт.
2. Ввести число.
3. Ввести число 2.
4. Помножити число 1, число 2.
5. Вивести результат.
Найпростіша і детальна логіка, якою оперує людина. Але машина трохи
складніше і в її логікою потрібно міркувати трохи по-іншому. Для відображення
машинної логіки зручніше перерахування кроків не зручно, тому давай знайомиться з
блок схемами на цьому прикладі.
Блок схеми прийнято креслити різними квадратами, овалами і прямокутниками.
Я особливо не буду дотримуватися стандартів, тому що це не особливо має значення, але
деяких особливостей буду дотримуватися. Ось основні типи використовуваних блоків
мною:
Початок роботи
Дані –
Процес –
Логіка –
Введення даних –
Запис/читання з диска –
Д
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
22
Висновок на екран –
Є й інші, більш збочені блоки, але я ними не буду користуватися.
Більшість блоків я буду оформляти, як просто прямокутник, бо від форми
блоку суть особливо не зміниться. Найголовніше (на мій погляд) виділити окремим видом
блоку початок блок-схеми і логіку. Все інше можна оформити одноманітно,
наочність від цього постраждає, але не сильно.
Отже, наша перша блок-схема, множення 2-х чисел буде виглядати так:
На перший погляд все дуже складно. Але це тільки на перший погляд. Реально тут
нічого складного немає, просто дуже громіздко і найпростіша операція множення
перетворюється в кілька операцій. Але все ж треба пояснити що відбувається
детальніше, щоб ми могли просунутися далі і розібратися з більш складними
прикладами.
Перший блок-це початок. Якщо ти зберешся будувати блок-схеми, то обов’язково
вказуй його, щоб одразу можна було побачити, початок логіки.
Другий блок перераховує змінні, які нам потрібні для обчислень. Я
використовую три змінні R, C1 і С2. В змінну R буде поміщений результат
обчислення. Змінні С1 і С2 використовуються для зберігання введених даних. Поки я
не вказую тип даних, що зберігаються в змінних, але розумію, що це будуть або
цілі числа або дійсні.
Третій блок тут показується, що треба ввести значення змінних С1 і С2.
Четвертий блок тут показується, на необхідність зробити множення С1
на С2 і результат записати в змінну R.
П’ятий блок виведення результату на екран.
Початок
R, C1, C2
R:= C1*C2
C1 і C2
R
1
2
3
4
5
Автор: Horrific aka Михайло Фленов e-mail: [email protected]
23
Це проста блок-схема, в якій немає нічого особливого, і ти навіть не можеш
побачити всіх її переваг. Наступні приклади буду?