16+
ComputerPrice
НА ГЛАВНУЮ СТАТЬИ НОВОСТИ О НАС




Яндекс цитирования


Версия для печати

Модуль поиска не установлен.

Вы и ваш компьютер (часть 1)

09.02.2009

Рустам Галеев

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

Хорошо, а много ли вещей вы можете сделать с помощью вашего компьютера? Если вы не очень опытный пользователь, этот вопрос может вызвать некоторое замешательство. Большинство смогут перечислить 3-4 приложения, с которыми обычно работают: ну, могу красиво составить документ, чтобы потом распечатать; ну, работаю с таблицами и диаграммами в Excel'е; ну, могу послать письмо знакомому в Америку, а еще "лазать" в WWW с помощью любимого NC (или IE). Более искушенные могут заявить: это зависит от программного обеспечения, установленного на компьютере. Программисты с гордостью (или снисхождением) скажут: а я сам пишу нужные мне программы. (Хакеры с ухмылкой подумают про себя: для меня вообще нет проблем ни с каким ПО).

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

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

Ну как, стало прохладнее? На самом деле все гораздо проще, чем может показаться, и вы сможете сейчас в этом убедиться (и удивиться). Нам понадобится всего одна вспомогательная программа, которая поставляется в составе ОС Windows 95/98 - debug.exe. Чтобы проверить ее наличие, вызовите окно DOS (кнопка Start (Старт) -> Programs (Программы) -> MS-DOS Prompt (Сеанс MS DOS)) и наберите debug - должно появиться приглашение debug (черточка). Чтобы выйти, наберите q , затем exit - и вы снова в Windows. Здесь не должно возникнуть проблем; далее мы на этом останавливаться не будем.

Итак, переходим к делу. Видеопамять - это та самая память, которая установлена на видеокарте вашего компьютера и которой постоянно оказывается недостаточно, потому что как только вы покупаете новую видеокарту, появляются программы, требующие еще больших возможностей (особенно это относится к игрушкам). Все, что выводится на экран монитора, должно быть сначала размещено в видеопамяти. Обычно эту задачу берет на себя операционная система или система программирования в сочетании с операционной системой, и вам бывает достаточно, скажем, записать что-нибудь типа print("Hello, world!"), чтобы на экране, к восторгу начинающего программиста, появилась эта фраза, нужного размера и на нужном месте. Нам же придется самим проделать всю необходимую работу.

Первая проблема, с которой нам придется столкнуться - формат данных. Допустим, мы хотим вывести эту пресловутую фразу "Hello, world!". Каким образом она должна быть записана? В кодах ANSI, или ASCII, или еще каких? А как быть, если надо вывести рисунок? И как вообще видеокарта узнает, что именно содержится в ее памяти? Чтобы решить эту проблему, было введено понятие видеорежима. И самое главное деление здесь - текстовые и графические режимы. Это и понятно, потому что если мы выводим в графическом режиме, мы кодируем цвет и яркость каждого отдельного пиксела на экране, и нам нет дела, какая кодировка у текста и вообще текст это или изображение. Зато значение имеет разрешение экрана и глубина цвета (т.е. количество битов, отводимое для кодирования цвета одного пиксела).

Графическими режимами мы, с вашего позволения, займемся как-нибудь в следующий раз, а сейчас сосредоточим наше внимание на текстовых режимах. В текстовом режиме вся поверхность экрана делится на участки равной величины - знакоместа. Число знакомест, на которое делится экран, определяется соответствующим режимом. Координатой становится не положение отдельного пиксела, а положение соответствующего знакоместа. Далее в памяти создается специальная кодовая таблица, в которой каждому значению кода приводится в соответствие определенная последовательность активных и неактивных битов, которые определяют, какие пикселы знакоместа должны отображаться, а какие - нет. Активные биты образуют "символ", а неактивные - "фон". Изменяя кодовую таблицу, вы изменяете шрифт. Именно это происходит, когда вы вписываете в файл "autoexec.bat" строку codepage select.

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

Таким образом, первое, с чего мы должны начать, - это установка видеорежима. Для этого воспользуемся сервисами BIOS - базовой системы ввода-вывода, которая представляет собой набор небольших обслуживающих программ, предусмотренных изготовителем и "вшитых" в постоянную память компьютера. Чтобы программы могли работать на компьютерах различных производителей, сервисы BIOS стандартизированы, так же как и большая часть видеорежимов, один из которых нам предстоит установить. Наиболее популярным текстовым режимом является режим VGA 80х25х16, т.е. экран поделен на 25 строк по 80 символов в каждой, причем в качестве цвета текста или фона возможно использование одного из 16 цветов. Этот режим имеет номер 3, что мы и должны сообщить BIOS (номера строк после точки с запятой не входят в код и приведены лишь для удобства):

mov ax,3 ;(1)

int 10h ;(2)

Здесь нам потребуется несколько "лирических отступлений". Первое "лирическое отступление" посвящается языку ассемблера.

Зачем нужен ассемблер?

Компьютер, к сожалению, не может понимать человеческой речи (по крайней мере, пока), так же как не может читать написанное человеком и т.п. Единственное, что он "понимает", - это последовательность чередующихся в определенном порядке моментов "высокого" (примерно в 2-3 вольта) и низкого напряжений - так уж он устроен, зато это он делает в совершенстве - со скоростью сотен миллионов импульсов в секунду (подставьте сюда тактовую частоту вашего компьютера). У человека подобный "способ общения" может вызвать разве что щекотку. Поэтому он ухищряется перевести все на привычные и любимые им способы, например, помечать все моменты высокого напряжения палочками, а низкого - кружочками. В результате получается такого рода писанина: 1100010110010001. Например, команда, которую нам нужно передать 'mov ax,3' для установления текстового режима © 3, выглядит, "с точки зрения компьютера" (но как видит это человек!) так: 10111000000000000-0000011. Много ли можно напрограммировать таким способом? Думаю, даже у тренированного человека после десятка подобных команд кружочки будут играть в чехарду с палочками, и что выдаст программа, написанная таким способом, одному богу известно.

Поэтому было решено, что палочки и кружочки на самом деле являются единицами и нулями, а их последовательности, таким образом, являются числами; следовательно, можно их записывать в более удобной форме, и вышеприведенная команда в виде числа в десятичной системе счисления выглядела бы так: 24 117 251 (если ваш покорный слуга не ошибся в расчетах). Однако у привычной нам всем с детства десятичной системы исчисления обнаружился один досадный недостаток: очень неудобно преобразовывать в нее числа из двоичной системы. Поэтому в информатике значительно чаще используются системы исчисления на основе двоичной - восьмиричная или, еще чаще, шестнадцатиричная. В последней для цифр не хватило символов, поэтому позаимствовали их из латинского алфавита: цифра 10 - это А, цифра 11 - В и т.д. до F. Наша команда в подобной записи приобретает вид: B8 00 03. Уже гораздо лучше, особенно если учесть, что эту запись при необходимости и при наличии некоторого навыка можно преобразовать обратно в двоичную даже в уме.

Но несмотря на все это, человек все равно не очень-то дружен с цифрами; зато он любит давать всему образные и не очень образные имена. Если в случае "чистых" чисел, например, номера, деваться некуда, то для обозначения команд он все же придумал имена. В нашем случае вы уже знаете, какое - это mov. Это не означает, что код B8 однозначно соответствует команде mov. Как это обычно бывает у человека, под одним именем скрывается целое семейство вещей, а в нашем случае под командой mov может скрываться и B8, и B9, и BA и т.д. (команда mov в этом отношении особенно показательна). Но не стоит беспокоиться по этому поводу. Программы, способные воспринимать команды в виде таких имен, автоматически находят нужные значения кодов и подставляют их без всяких ошибок. Набор таких команд-имен и правила построения из них программ и составляют язык ассемблера.

На самом деле, человек пошел еще дальше. Вместо команд, выполняющих элементарные действия (о которых мы будем говорить дальше), он стал придумывать все больше и больше команд, под которыми скрывались десятки и даже сотни элементарных действий. Таким образом возникли языки высокого уровня (одним из них является всем известный Бейсик, который проходят в школе). Вспомните: то, что мы собираемся сделать, можно на каком-нибудь языке программирования написать в одну строку: print(""). Зачем же тогда использовать ассемблер? Мы не будем здесь вдаваться в дискуссию по поводу преимуществ и недостатков языков программирования высокого уровня. Ассемблер является в некотором отношении пределом: каждая строка кода на языке ассемблера соответствует ровно одной машинной команде, независимо от точного "числового" выражения этой команды. Т.е. это "элементарное машинное действие", чего нельзя сказать о коде на языке высокого уровня. Поэтому программировать на языке ассемблера означает программировать "элементарные машинные действия", т.е. полностью осознавать, КАК исполняется ваша программа.

Вернемся к установлению текстового видеорежима № 3. Для этого, как вы уже знаете, мы использовали команды 'mov ax,3' и 'int 10h'. Первая команда на самом деле означает пересылку числа 3 (т.е. номера нужного нам видеорежима) в регистр АХ. Здесь нам понадобится второе "лирическое отступление", на этот раз о регистрах.

Что такое регистры?

Вообще говоря, регистр - это ячейка памяти, в которой хранится (поддерживается) определенный паттерн участков "высокого" и низкого напряжения, но раз уж мы условились называть эти паттерны числами, скажем, что в регистре хранятся двоичные значения. По числу разрядов хранимого двоичного числа регистры бывают 16- и 32-разрядные (раньше были еще 8-разрядные, а теперь - 64- и даже 80-разрядные); но здесь мы будем иметь дело только с 16-разрядными регистрами. Но точно таким же образом информация хранится и в оперативной памяти, причем объем ее неизмеримо больше, чем у регистров - зачем же понадобились еще и последние? Дело не только в том, что чипы оперативной памяти представлены отдельным блоком на системной плате, а регистры встроены в процессор (например, кэш-память тоже встроена в процессор, но от этого она не превращается в набор регистров). Дело скорее в том, что регистры являются "особами, приближенными к императору", и в качестве таковых они пользуются привилегией иметь собственные имена (и даже по нескольку имен, как вы сможете скоро убедиться).

Байты основной массы памяти просто нумеруются по порядку, как военнопленные в концлагере, и обращаются к ним по их порядковому номеру, который называют "адресом"; тогда как к регистрам обращаются почтительно по имени: AX, CS, DS, SI и т.д. Обретя таким образом свое "лицо", регистры могут позволить себе, в отличие от общей серой массы остальной памяти, роскошь обладать некими характерными особенностями. В результате они обычно исполняют определенный набор обязанностей, реализуемых аппаратно. Таким образом, регистры оказываются тем самым переходным звеном между "железом" и "софтом", благодаря которому программирование оказывается вообще возможным.

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

Регистры оказались удобным способом передавать нужную информацию, поэтому они стали широко использоваться не только при использовании машинных команд, но и сервисных подпрограмм, таких, как сервисы BIOS. В нашем случае такой сервис вызывается командой 'int 10h'. Строго говоря, int - это тоже машинная команда, но хитрая: она предполагает, что некий сервис уже кем-то написан и размещен заранее в определенной области памяти, причем адрес начала этой области располагается в специально отведенной для этой цели таблице векторов прерываний (в начале всей оперативной памяти). В этой таблице в каждой строке, которой соответствует собственный номер прерывания, записывается 4 байта адреса, указывающего на начало процедуры, которую необходимо исполнить. Таким образом, адрес для нужного нам сервиса находится в 16-й строке этой таблицы.

Но все это, опять-таки, реализовано аппаратно, и нам ломать голову над этим не нужно. Нам необходимо позаботиться лишь о том, чтобы перед вызовом нужного сервиса все необходимые для его исполнения данные находились в нужных регистрах, в данном случае, в регистре AX должно быть 3. Обо всем остальном позаботились производители соответствующего оборудования.

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

Вы и ваш компьютер (часть 2)
Вы и ваш компьютер (часть 3)



статьи
статьи
 / 
новости
новости
 / 
контакты
контакты