Понедельник
29.04.2024, 12:46
SamStudio
Вы вошли как Гость | Группа "Гости" | RSS
        
Каталог статей

SamStudio


Ցանկ

Мои статьи [10]


Փոքր-ЧАТ


Главная » Статьи » Мои статьи

Основные принципы работы компьютера
Основные принципы работы компьютера
1.1 Основы работы персонального компьютера.
Прежде чем программировать компьютер, мы должны понять, как он работает.
Как говорил какой-то полководец: «Нужно хорошо изучить своего врага!!!».
Возможно, это говорил и не полководец, но это не важно :). Кодинг – это
постоянная борьба с машиной. Нужно заставлять её делать то, что тебе нужно. Поэтому
любой программист просто обязан знать его внутренности.
Компьютер состоит из следующих основных компонентов: процессор, память,
видеокарта, винчестер (жёсткий диск) и различные разъёмы для подключения
дополнительных устройств. Все эти компоненты связаны между собой с помощью
шлейфов и шин.
Вся информация в компьютере хранится на винчестере. Когда ты запускаешь какую-
нибудь программу, то она сначала загружается в память и только потом процессор
начинает выполнять содержащиеся в ней инструкции. Чем больше программа, тем дольше
она загружается.
Результат работы программы выводится на экран через видеокарту. На любой
видеокарте есть чип памяти, в котором отображается всё содержимое экрана. Когда тебе
нужно вывести что-то на экран, ты просто копируешь эти данные в видеопамять, и
видеокарта автоматически выводит его содержимое на монитор.
Это всё, что необходимо знать о работе компьютера. Пока я описать только общие
черты, а в следующих разделах я опишу необходимые вещи более подробно. В основном
нас будет интересовать работа процессора, поэтому ему я уделю особое внимание.
Остальное пока достаточно знать в общих чертах.
1.2 Двоичная система работы процессора.
омпьютеры изобрели достаточно давно. В те времена электроникой даже и не
пахло. Первые компьютеры были ламповыми и занимали очень много места.
Для того, чтобы управлять такой махиной нужно было очень много
обслуживающего персонала.
Уже тогда был заложен принцип работы компьютера, который действует до сих пор.
А именно, данные передаются с помощью какого-то сигнала (для нас не имеет значения
какого, потому что мы не электронщики) методом «есть сигнал или нет» или по-другому
«включён или выключен». Так появился «бит» bit. Бит это единица информации, которая
может принимать значение или 0, или 1, т.е. «включён или выключен». Восемь бит
объединяются в байт, т.е. один байт равен 8 битам. Почему именно 8? Да потому что
первые компьютеры были восьми разрядными и могли работать одновременно только с 8-
ю битами, например, 010000111.
Немного позже ты узнаешь, что в один байт можно записать любое число до 255. Но
это очень мало, поэтому чаще используют более крупные градации:
1. Два байта = слово.
2. Два слова = двойное слово.
Итак, компьютер стал работать в двоичной системе исчисления. Но как же тогда
записать число 135, если у нас единица информации может быть только или 0 или 1.
Просто в двоичной системе. Давай разберёмся, как это работает.
П
К
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
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: vr_online@cydsoft.com
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 11 3
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: vr_online@cydsoft.com
11
Таблица 2. Таблица соответствия десятичных, двоичных и шестнадцатеричных чисел
На протяжении всей книги мы будем иногда встречаться с
шестнадцатеричной системой исчисления (без этого никуда не денешься),
поэтому, когда нужно будет показать, что число шестнадцатеричное, я
буду ставить перед ним знак решётки #, например, #13. В других языках,
например Assembler или C++ принято ставить в конце числа букву h,
например, 13h. Но эта книга о Delphi, поэтому я буду писать так, как
принято в этой среде разработки, чтобы потом не возникало никаких
проблем.
Но это всё целые числа. С числами с плавающей точкой совершенно другая история.
Если заранее предусмотрено, что число может быть отрицательным, то его длинна
сокращается ровно на один бит. Если неотрицательное целое число может быть 8-ми
битным, то число со знаком будет 7-и битным. Первый бит будет означать знак. Если
первый бит равен 1, то число отрицательное, иначе положительное.
В дробных числах один байт может быть отведён для целой части и один для
дробной. Никогда не смешивают целую и дробную часть в одно целое. За счёт этого,
дробные числа всегда будут занимать больше памяти, и операции с ними проходят
намного дольше.
На первый взгляд перевод чисел очень сложный, но вручную им пользоваться не
обязательно. Человек уже давно придумал для себя хорошего помощника - калькулятор. С
его помощью без проблем можно перевести число в любую систему.
Запусти встроенный в Windows калькулятор (Пуск -> Программы -> Стандартные ->
Калькулятор).Теперь выбери из меню «Вид» пункт «Инженерный». На рисунке ниже
показано окно, которое ты должен увидеть:
Внешний вид калькулятора
Для перевода числа в другую систему, просто набери его и потом выбери нужную
систему исчисления. На рисунке я обвёл красным цветом кнопки переключения системы
исчисления:
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
12
• Hex – шестнадцатеричная.
• Dec – десятичная.
• Oct – восьмеричная.
• Bin – двоичная.
Возникает вопрос – зачем я тогда так долго рассказывал о преобразованиях, когда
так легко воспользоваться калькулятором? Ответ прост – НАДО. Поверь мне. Если ты
будешь понимать, как происходит преобразование, то тебе потом легче будет работать с
этими числами.
Никогда не полагайся только на технику. Всегда полезно знать, как и зачем
она что-то делает. Если ты разберёшься с шестнадцатеричным
представлением данных, то сможешь простые преобразования делать в
уме. Ну а если ты ещё и собираешься стать хакером, то тебе просто
необходимо научится хорошо оперировать разными системами исчисления.
1.3 Машинный язык.
анные на диске также хранятся в двоичном виде. Даже текстовые файлы на
диске выглядят в виде нулей и единиц. Точно так же выглядит и любая
программа, только её называют машинным кодом. Давай с ним познакомимся
немного поближе.
Любая программа представляет собой последовательность команд. Эти команды
называются процессорными инструкциями. По этим инструкциям процессор определяет,
что и как ему нужно делать. Когда ты запускаешь программу, компьютер загружает её
машинный код в память и начинает выполнять. Наша задача, как программистов написать
эти инструкции, чтобы компьютер понял, что мы от него хотим.
Реальная программа, которую выполняет компьютер, представляет собой
последовательность единиц и нулей. Такую последовательность называют машинным
языком. Но человек не способен эффективно думать единицами и нулями. Для нас легче
воспринимается осмысленный текст, а не сумасшедшие числа в двоичной системе
измерения, с которой мы не привыкли работать. Например, команда складывания двух
регистров выглядит так: #03C3. Нам это мало о чём говорит, и запомнить такую команду
очень тяжело. На много проще написать «сложить число1+ число2».
Первое время программисты писали в машинных кодах, пока кому-то не пришла в
голову идея: «Почему бы не писать текст программы на понятном языке, а потом
заставлять компьютер переводить этот текст в машинный код?». Идея действительно
заслуживала внимания. Так появился первый компилятор – программа, которая
переводила текст программ в машинный код.
Вот тут, я думаю надо сделать паузу и рассказать тебе небольшую историю языков
программирования. Она достаточно интересна и поучительна. Ну а потом мы продолжим
изучения принципов работы компьютера и познакомимся с содержимым процессора и его
работой.
1.4 История языков программирования.
Д
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
13
ак мы уже выяснили, компьютер - примитивное существо, которое мыслит
нулями и единицами, из которых складываются числа. Так что все, что может
делать процессор, так это оперировать этими числами. Так и программы - это
тоже числа, которые воспринимаются процессором как команды к выполнению каких-то
действий.
Мы также выяснили, что первые программисты писали программы в машинных
кодах. Тогда еще не было компиляторов и приходилось все писать числами. Ты даже
представить себе не можешь, какой это адский труд. Постоянно держать в памяти таблицу
машинных кодов - это тебе не таблица умножения. Например, тебе понятно число 8BC3.
Нет? А это простая команда копирования между двумя ячейками регистров. Это просто
пример, потому что тогда регистры были другие и процессоры были на много проще.
Со временем компьютер стал умнеть. Он все так же оперировал числами, но делал
это намного быстрее. Но программист - это человек, а не железка и ему очень тяжело
создавать логику в числах. Намного легче работать с привычными словами. Например, все
ту же команду удобней записать словами типа "скопировать ebx в eax". Но что делать,
если компьютер не понимает слов, а только числа? Выход есть - написать такую
программу, которая будет превращать текст в машинные коды. Пусть компьютер сам
создает байт-код. Такую программу назвали компилятором. А язык, на котором писался
текст программы, назвали языком программирования.
Программа в машинных кодах и Assembler
И вот был написан первый компилятор. Эту программу назвали Assembler, что
переводится, как "сборщик". Писать на нем практически так же, как и в машинных кодах,
только теперь уже использовались не числа, а понятные человеку слова. Например, все та
же команда копирования регистров теперь выглядела так: "mov eax, ebx". То есть цифры
заменились на понятные слова.
Вроде все прекрасно и удобно, но почему-то среди программистов возникли споры и
разногласия. Кто-то воспринял новый метод с удовольствием. А кто-то говорил, что
машинные коды лучше. Любители языка Assembler хвалили компилятор за то, что
К
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
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: vr_online@cydsoft.com
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: vr_online@cydsoft.com
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: vr_online@cydsoft.com
17
Сегментные регистры - CS, DS, SS и ES. (есть ещё, но нас пока интересуют только
эти):
• Регистр CS - регистр сегмента кода, в нём хранится начальный адрес
сегмента кода.
• Регистр DS - регистр сегмента данных, в нём хранится начальный адрес
сегмента данных. В этом сегменте располагаются глобальные переменные.
• Регистр SS - регистр сегмента стека, в нём хранится начальный адрес
сегмента стека. Здесь располагаются локальные переменные.
• Регистр ES. Для использования дополнительного сегментного регистра.
Разницу между глобальными и локальными переменными мы рассмотрим чуть
позже, когда будем изучать сам язык программирование. Сейчас я ещё скажу только то,
что в сегменте сохраняются и переменные, которые передаются в процедуры и адрес
возврата из процедуры (куда нужно вернуться по окончанию выполнения кода
процедуры).
Регистры общего назначения EAX, EBX, ECX и EDX, все эти регистры 32-х
битные. В 16-разрядных процессорах, они были 16-разрядными и назывались AX, BX, CX
и DX. Они могут использоваться в программе по собственному усмотрению, но в
некоторых случаях им отведена определённая роль. В регистр EAX в основном
записываются результаты арифметических вычислений, а регистр EСХ используется в
качестве счётчика. Регистр EAX используется для хранения результатов вычисления.
Очень часто, прежде чем выполнить какую-то команду, процессор загружает
необходимые данные в регистры и только после этого выполняет необходимую
инструкцию. Но возможны варианты, когда вычисления идут напрямую с памятью.
Регистровые указатели ESP и EBP. ЕSP - это указатель стека, который
обеспечивает его использование в памяти. ЕBP – обеспечивает доступ к данным и
указателям на данные переданные через стек.
Индексные регистры ЕSI и ЕDI. Эти регистры используются при сложении и
вычитании, а так же для расширенной адресации.
Если ты собираешься писать простенькие утилиты или базы данных, то
эти знания ты не будешь использовать. Но если ты хочешь пойти дальше,
то желательно не просто знание, но и понимание процесса работы
процессора. Поэтому я сейчас попробую на пальцах (а точнее сказать на
примере) объяснить процесс его работы.
Итак, сейчас я опишу процесс выполнения программы более подробно. В любом
случае, это тебе пригодится.
При старте программы, исполняемый код загружается в сегмент кода. Регистр CS
сразу устанавливается в значение, указывающее на начало этого сегмента. Данные
программы загружаются в сегмент данных (это константы и любые другие
дополнительные данные). На этом же этапе происходит подготовка (инициализация) к
работе сегмента стека. Если программе переданы какие-нибудь значения, то они
автоматически заносятся в стек.
Сегменты кода содержит код только одной программы. В один сегмент не
может быть загружен код двух абсолютно разных программ. Точно так же
и сегмент данных, и сегмент стека. При каждом старте новой программы,
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
18
операционная система отводит её свои собственные сегменты кода, данных
и стека.
После этих подготовительных действий, ОС готова к выполнению кода. Напомню,
что регистр CS указывает на начало сегмента кода. Есть ещё один регистр, о котором я
ещё не сказал – EIP. Этот регистр указывает на текущую выполняемую команду в
сегменте кода.
Процессор последовательно выполняет все команды, находящиеся в сегменте кода.
Иногда необходимо перескочить не на следующую точку программы, а совершенно в
другое место. В этом случае происходит такой переход, и команды начинают
последовательно выполнятся, уже начиная с новой точки.
Я уже сказал, что любые операции, вычисления могут производиться с регистрами и
с памятью. Например, к значению регистра EAX прибавить значение EBX – это сложение
регистров. Можно складывать и значения находящиеся в оперативной памяти. Но надо
помнить, что вычисления с регистрами происходит намного быстрее, потому что регистр
– это та же оперативная память, только находящаяся в процессоре. Если ты собираешься
произвести с одним и тем же числом две операции, то намного эффективнее будет
располагать его в регистре.
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
19
Глава 2. Машинная математика.
о перестройки, в нашей стране практически не обучали программистов.
Большинство программистов были выходцами с кафедр математики, на
которых очень часто были какие-то предметы с уклоном в сторону
информатики. На этих курсах учили писать блок-схемы – это схема, описывающая логику
программы.
Я с блок-схемами познакомился на первом курсе института. Первое впечатление –
полное фуфло. Но со временем я понял их достоинства. Возможно, что тебе покажется это
слишком просто, но всё же желательно прочитать эту главу полностью. Здесь я расскажу
теорию всего процесса программирования. В дальнейшем нам останется только
познакомится с практикой, и мы на коне O.
2.1 Основы машинной математики.
а любом языке программирования можно выполнять математические
операции любой сложности. Delphi не исключение. Но пока что мы не будем
рассматривать все возможности, а остановимся только на основных. Вот
основные математические операции языка Delphi:
Математическая
операция
Описание
* Умножить
/ Разделить
Sqr Квадрат
Sqrt Квадратный корень
+ Сложение
- Вычитание
:= Присвоить значение.
Математические операции
В таблице перечислены основные математические операции языка
программирования Delphi. Они выполняются в том же порядке, в котором перечислены.
Например, в формуле 2+2*2 результатом будет 6, потому что сначала выполняется
операция умножения, а потом сложения. Если ты хочешь сначала выполнить сложение, а
потом вычитание, то как и в простой математике должен использовать скобки: (2+2)*2=8.
В этом случае результат уже будет совершенно другим.
Для изучения компьютерной математики ты должен знать следующие понятия:
Переменная – это память, в которую можно записывать различные значения. Чаще
всего этой памяти присваивается в соответствие имя. Например, я завожу переменную с
именем F. Ей я могу присваивать значения, например 5. Для этого мне нужно записать
F:=5. Знак двоеточие + равно означает операцию «присвоить».
Значения переменных можно копировать из одной в другую. Допустим, что у меня
есть ещё одна переменная G. Я могу присвоить ей значение переменной F с помощью
простого присваивания G:=F. После этого в переменной G у меня тоже будет значение 5.
Д
Н
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
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
(истина или ложь). Этот тип очень часто
используется для организации логики.
Основные типы данных в Delphi
Это только основные типы. Реально их намного больше. Когда мы перейдём к
программированию, я познакомлю тебя с большим количеством типов данных.
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
21
Строки – любые символы и наборы символов. В языке Delphi они выделяются
одинарными кавычками, например, ‘Привет’. Строки так же можно присваивать
переменным, как и любое другое значение.
Str – строковая переменная.
Str:=’Привет!!!’
На этом основные сведения о машинной математике подошли к концу. Пора
применить наши знания на практике.
2.2 Блок-схемы.
авай сразу зададим какой-нибудь простой пример, на котором попробуем
расписать логику его решения. Допустим, нам надо получить произведение
двух чисел. В человеческой логике мы должны выполнить следующие
операции:
1. Старт.
2. Ввести число.
3. Ввести число 2.
4. Умножить число 1 на число 2.
5. Вывести результат.
Простейшая и подробная логика, которой оперирует человек. Но машина немного
сложнее и в её логике нужно рассуждать немного по-другому. Для отображения
машинной логики удобней перечисления шагов не удобно, поэтому давай знакомится с
блок схемами на этом примере.
Блок схемы принято чертить различными квадратами, овалами и прямоугольниками.
Я особо не буду придерживаться стандартов, потому что это не особо имеет значения, но
некоторых особенностей буду придерживаться. Вот основные типы блоков используемых
мной:
Начало работы –
Данные -
Процесс -
Логика -
Ввод данных -
Запись/чтение с диска -
Д
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
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: vr_online@cydsoft.com
23
Это простая блок-схема, в которой нет ничего особенного, и ты даже не можешь
увидеть всех её преимуществ. Следующие примеры будут уже использовать логику,
поэтому блок-схемы будут более сложными, и ты сможешь ощутить всю прелесть
машинной математики.
2.3 Машинная логика и циклы.
любом языке программирования есть куча операций сравнения, которые
позволяют реализовать машинную логику. Что понимается под логическими
операциями? Это операции сравнения на «равенство», «больше» или
«меньше».
Математическая
операция
Описание
= Равно
> Больше
< Меньше
Давай рассмотрим простейшую логику компьютера на примере факториала.
Факториал – это произведение от 1 до какого-то числа. Например, 5 факториал равен
1*2*3*4*5=120. Факториал обозначается как знак восклицания «!».
Давай напишем алгоритм в виде блок-схемы:
В
Начало
F, R, Index
Index:=1; R:=1;
F
R
1
2
3
4
5 Index>F
Нет
6
Да
7
R := R * Index;
Index:=Index+1;
Автор: Horrific aka Фленов Михаил e-mail: vr_online@cydsoft.com
24
Представим, что мы не знаем число, факториал которого мы должны вычислить. Это
число будет вводить пользователь. Поэтому в общем случае формула будет выгладить,
как число F факториал (F!). Так что нам надо перемножить все числа от 1*2*3*4*…*F.
Всё это можно сделать последовательно. Умножить 1*1. Затем проверить, не превысили
ли мы число F, если нет, то результат прошлого вычисления * на 2. Снова проверить. Если
не превысили F, то снова умножить результат прошлого вычисления на 3. И так далее.
Теперь я постараюсь объяснить каж
Категория: Мои статьи | Добавил: Sam (01.06.2010)
Просмотров: 7790 | Комментарии: 2 | Рейтинг: 2.4/7
Всего комментариев: 2
2 Ублюдок  
0
сцука, захер так много? гори в аду!!

1 Elchik  
0
Молодец! Четко все описал applause

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Մուտք

Փնտրել

Հարցում

Գնահատեք ձեր համակարգչային գիտելիքները
Գնահատել է: 86


Տվյալներ

Онлайн всего: 1
Гостей: 1
Пользователей: 0


SamStudio © 2024
Хостинг от uCoz