Как процессор понимает язык программирования

Обновлено: 06.07.2024

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

Компьютерная программа (также обычно называемая приложением) – это набор инструкций, которые компьютер может выполнить для выполнения некоторой задачи. Процесс создания программы называется программированием. Программисты обычно создают программы, создавая исходный код (обычно сокращено говорят просто код), который представляет собой список команд, введенных в один или несколько текстовых файлов.

Набор физических компонентов компьютера, из которых состоит компьютер, и которые выполняют программы, называется аппаратным обеспечением. Когда компьютерная программа загружается в память и аппаратное обеспечение последовательно выполняет каждую инструкцию, это называется запуском или выполнением программы.

Машинный язык

Центральный процессор (CPU) компьютера не понимает язык C++. Ограниченный набор инструкций, которые CPU может понимать напрямую, называется машинным кодом (или машинным языком, или набором инструкций).

Вот пример инструкции машинного языка: 10110000 01100001 .

Когда были изобретены первые компьютеры, программистам приходилось писать программы непосредственно на машинном коде, что было очень трудно и отнимало много времени.

Как организованы эти инструкции, выходит за рамки данного введения, но интересно отметить две вещи.

  • Во-первых, каждая инструкция состоит из последовательности нулей и единиц. Каждый отдельный 0 или 1 называется битом (от «binary digit», или «двоичная цифра»). Количество битов, составляющих одну команду, может различаться – например, некоторые процессоры обрабатывают инструкции, которые всегда имеют длину 32 бита, тогда как некоторые другие процессоры (например, семейство x86, которое вы, вероятно, используете) имеют инструкции, которые могут быть переменной длины.
  • Во-вторых, каждый набор битов интерпретируется центральным процессором в команду для выполнения очень конкретной работы, например, сравнения этих двух чисел или помещения этого числа в эту ячейку памяти. Однако из-за того, что разные CPU имеют разные наборы инструкций, инструкции, написанные для одного типа процессоров, не могут использоваться процессором, который не использует такой же набор команд. Это означало, что программы, как правило, нельзя было портировать (переносить, использовать без серьезной доработки) между различными типами систем, и их приходилось переписывать заново.

Язык ассемблера

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

Вот та же инструкция, что и выше, но на языке ассемблера: mov al, 061h .

Это сделало разработку намного проще для чтения и записи, чем машинный код. Однако CPU не понимает ассемблер напрямую. Вместо этого программа на ассемблере, прежде чем она сможет быть выполнена компьютером, должна быть переведена на машинный код. Это делается с помощью программы, называемой ассемблером. Программы, написанные на языках ассемблера, обычно бывают очень быстрыми, и ассемблер всё еще используется сегодня, когда очень важна скорость выполнения программы.

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

Высокоуровневые языки

Чтобы решить проблемы удобочитаемости и переносимости, были разработаны новые языки программирования, такие как C, C++, Pascal (и более поздние языки, такие как Java, Javascript и Perl). Эти языки называются языками высокого уровня, поскольку они разработаны, чтобы позволить программисту писать программы, не беспокоясь о том, на каком компьютере будет выполняться программа.

Вот всё та же инструкция, что и выше, на C/C++: a = 97;

Как и программы на ассемблере, программы, написанные на языках высокого уровня, прежде чем их можно будет запустить, должны быть переведены в формат, понятный компьютеру. Это можно сделать двумя основными способами: компиляция и интерпретация.

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

Ниже показано упрощенное представление процесса компиляции:

Рисунок 1 – Пример сборки приложения

Рисунок 1 – Пример сборки приложения

Поскольку программы на C++ обычно компилируются, мы вскоре рассмотрим компиляторы более подробно.

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

Ниже показано упрощенное представление процесса интерпретации:

Рисунок 2 – Пример интерпретации

Рисунок 2 – Пример интерпретации

Дополнительная информация

Ни один из подходов не имеет перед другим явного преимущества – если бы один подход всегда был лучше, велика вероятность, что мы стали бы использовать его повсюду!

В целом, компиляторы имеют следующие преимущества:

  1. Поскольку они могут видеть весь исходный код заранее, при генерации кода они могут выполнять ряд анализов и оптимизаций, благодаря чему окончательная версия кода выполняется быстрее, чем простая интерпретация каждой строки по отдельности.
  2. Компиляторы часто могут генерировать низкоуровневый код, который выполняет эквивалент высокоуровневых идей, таких как «динамическое связывание» или «наследование» с точки зрения поиска в памяти внутри таблиц. Это означает, что итоговые программы должны помнить меньше информации об исходном коде, что снижает использование памяти сгенерированной программой.
  3. Скомпилированный код обычно быстрее, чем интерпретируемый код, потому, что выполняемые инструкции обычно предназначены только для самой программы, а не для самой программы плюс накладные расходы интерпретатора.

В целом, у компиляторов есть следующие недостатки:

  1. Некоторые языковые функции, такие как динамическая типизация, сложно эффективно скомпилировать, потому, что компилятор не может предсказать, что произойдет, пока программа не будет запущена. Это означает, что компилятор может генерировать не очень хороший код.
  2. Компиляторы обычно имеют длительное время «запуска» из-за затрат на выполнение всего анализа, который они делают. Это означает, что в таких окружениях, как веб-браузеры, где важно быстро загружать код, компиляторы могут работать медленнее, потому что они оптимизируют короткий код, который не будет запускаться много раз.

В целом, у интерпретаторов есть следующие преимущества:

  1. Поскольку они могут читать код в том виде, в каком он написан, и им не нужно выполнять дорогостоящие операции для генерации или оптимизации кода, они, как правило, запускаются быстрее, чем компиляторы.
  2. Поскольку интерпретаторы могут видеть, что делает программа во время ее выполнения, интерпретаторы могут использовать ряд динамических оптимизаций, которые компиляторы могут не видеть.

В целом, у интерпретаторов есть следующие недостатки:

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

Поскольку у интерпретаторов и компиляторов есть взаимодополняющие сильные и слабые стороны, в средах выполнения языка становится всё более обычным явлением сочетание элементов обоих методов. Хорошим примером этого является JVM – сам код Java компилируется и изначально интерпретируется. Затем JVM может найти код, который выполняется много-много раз, и скомпилировать его непосредственно в машинный код, что означает, что «горячий» код получает преимущества компиляции, а «холодный» – нет. JVM также может выполнять ряд динамических оптимизаций, таких как встроенное кэширование, для повышения производительности способами, которые обычно не выполняются компиляторами.

Многие современные реализации JavaScript используют аналогичные приемы. Большая часть кода JavaScript короткая и не так уж много чего делает, поэтому обычно начинают с интерпретатора. Однако если станет ясно, что код запускается неоднократно, многие JS-движки скомпилируют код (или, по крайней мере, скомпилируют его отдельные части) и оптимизируют его, используя стандартные методы. В конечном итоге код работает быстро при запуске (полезно для быстрой загрузки веб-страниц), а также быстрее работает и при дальнейшем выполнении.

И последняя деталь: языки не компилируются и не интерпретируются. Обычно код C компилируется, но доступны и интерпретаторы C, которые упрощают отладку или визуализацию выполняемого кода (они часто используются при вводном изучении программирования – или, по крайней мере, они использовались раньше). JavaScript считался интерпретируемым языком, пока некоторые JS-движки не начали его компилировать. Некоторые реализации Python являются чисто интерпретаторами, но вы можете найти компиляторы Python, которые генерируют нативный код. Некоторые языки легче компилировать или интерпретировать, чем другие, но ничто не мешает вам создать компилятор или интерпретатор для любого конкретного языка программирования. Теоретический результат, называемый проекциями Футамуры, показывает, что всё, что можно интерпретировать, можно и скомпилировать.

Большинство языков можно компилировать или интерпретировать, однако традиционно языки, такие как C, C++ и Pascal, компилируются, тогда как «скриптовые» языки, такие как Perl и Javascript, обычно интерпретируются. В некоторых языках, например в Java, используется сочетание этих двух методов.

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

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

Во-вторых, высокоуровневые языки требуют меньшего количества инструкций, чем низкоуровневые языки, для выполнения одной и той же задачи, что делает программы более краткими и легкими для понимания. В C++ вы можете сделать что-то вроде a = b * 2 + 5; в одну строку. На ассемблере для этого потребуется 5 или 6 разных инструкций.

В-третьих, программы можно компилировать (или интерпретировать) для многих различных систем, и вам не нужно изменять программу для работы на разных процессорах (вы просто перекомпилируете ее для конкретного процессора). В качестве примера:

Рисунок 3 – Пример портируемости приложения

Рисунок 3 – Пример портируемости приложения

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

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

Правила, рекомендации и предупреждения

По мере изучения этих руководств мы будем выделять важные моменты в следующих трех категориях:

Правило

Правила – это инструкции, которые вы должны выполнять в соответствии с требованиями языка. Несоблюдение правил обычно приводит к тому, что ваша программа не работает.

Лучшая практика

Лучшие практики – это то, что вам следует делать, потому что такой способ обычно считается стандартным или настоятельно рекомендуется. То есть либо так поступают все (а если вы поступите иначе, то вы будете делать не то, что ожидают), либо это лучше других альтернатив.

Предупреждение

Предупреждения – это то, чего делать не следует, поскольку они обычно приводят к неожиданным результатам.

Машинный язык

Процессор компьютера не способен понимать напрямую языки программирования, такие как C++, Java, Python и т.д. Очень ограниченный набор инструкций, которые изначально понимает процессор, называется машинным кодом (или «машинным языком»). То, как эти инструкции организованы, выходит за рамки данного введения, но стоит отметить две вещи.

Во-первых, каждая команда (инструкция) состоит только из определенной последовательности (набора) цифр: 0 и 1 . Эти числа называются битами (сокр. от «binary digit») или двоичным кодом.

Например, одна команда машинного кода архитектуры ×86 выглядит следующим образом:

Во-вторых, каждый набор бит переводится процессором в инструкции для выполнения определенного задания (например, сравнить два числа или переместить число в определенную ячейку памяти). Разные типы процессоров обычно имеют разные наборы инструкций, поэтому инструкции, которые будут работать на процессорах Intel (используются в персональных компьютерах), с большей долей вероятности, не будут работать на процессорах Xenon (используются в игровых приставках Xbox). Раньше, когда компьютеры только начинали массово распространяться, программисты должны были писать программы непосредственно на машинном языке, что было очень неудобно, сложно и занимало намного больше времени, чем сейчас.

Язык ассемблера

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

Например, вот вышеприведенная команда, но уже на языке ассемблера:

Высокоуровневые языки программирования

компиляция, которая выполняется компилятором;

интерпретация, которая выполняется интерпретатором.

Компилятор — это программа, которая читает код и создает автономную (способную работать независимо от другого аппаратного или программного обеспечения) исполняемую программу, которую процессор понимает напрямую. При запуске программы весь код компилируется целиком, а затем создается исполняемый файл и уже при повторном запуске программы компиляция не выполняется.

Проще говоря, процесс компиляции выглядит следующим образом:



Преимущества высокоуровневых языков программирования

Преимущество №1: Легче писать/читать код. Вот вышеприведенная команда, но уже на языке C++:

Преимущество №2: Требуется меньше инструкций для выполнения определенного задания. В языке C++ вы можете сделать что-то вроде а = Ь * 2 + 5; в одной строке. В языке ассемблера вам пришлось бы использовать 5 или 6 инструкций.

Преимущество №3: Вы не должны заботиться о таких деталях, как загрузка переменных в регистры процессора. Компилятор или интерпретатор берёт это на себя.

sxemagotovo33

Преимущество №4: Высокоуровневые языки программирования более портируемые под различные архитектуры (но есть один нюанс).Нюанс заключается в том, что многие платформы, такие как Microsoft Windows, имеют свои собственные специфические функции, с помощью которых писать код намного легче. Но в таком случае приходится жертвовать портируемостью, так как функции, специфические для одной платформы, с большей долей вероятности, не будут работать на другой платформе. Обо всем этом мы детально поговорим на следующих уроках.

Чем отличаются процессоры?

Рассмотрим важные моменты, касающиеся того, как работает процессор компьютера. Начнем с того, чем отличаются процессоры?

Различные процессоры могут иметь отличающийся набор команд, которые они могут исполнять. Чем больше команд может исполнять процессор, тем быстрее он обрабатывает информацию. Если же система команд более «бедная», то такой процессор должен делать бОльшее число более простых операций, чтобы выполнить обработку данных, по сравнению с процессором с более «богатой» системой команд.

Процессоры, у которых система команд отличается в большую сторону от остальных, называют процессорами с расширенной системой команд.

бездушный механизм

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

Если следующая команда отменяет предыдущую (к примеру, первая команда позволяет записать данные в регистр, а вторая команда удаляет данные из этого же регистра), то процессор будет выполнять такие команды, нисколько «не задумываясь» над бессмысленностью своих действий.

Еще хуже, если программа будет направлена не на созидание (обработку данных), а на разрушение (например, на удаление важных и нужных данных, или на выгрузку этих данных несанкционированным образом), то процессор безупречно и без всяких «угрызений совести» в точности выполнит все инструкции на уничтожение или кражу важных данных.


Этим пользуются разработчики вирусных программ. Создавая программы, направленные на выполнение несанкционированных действий (удаление или банальное воровство данных, внесение помех в обработку данных и т.п.), разработчики вирусов стремятся к тому, чтобы их программы были записаны в оперативную память компьютера, и чтобы процессору был дан сигнал на обработку записанной в памяти последовательности команд.

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

Наиболее просто попасть в оперативную память могут вирусы, записанные в файлах с расширением .exe, так как в них хранится набор команд практически пригодный без особой предварительной обработки или анализа для выполнения процессором.

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

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

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

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

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

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

Без исправного процессора – нет ПК. Процессор – это своего рода мозг компьютера, делающий его способным к обработке информации, что и обеспечивает выполнение компьютером всех возложенных на него задач.

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

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

Трансляторы бывают двух типов - Интерпретаторы и Компиляторы.

Интерпретатор переводит Вашу программу с языка высокого уровня (например, БЕЙСИКа) в машинный код последовательно строку за строкой. Он работает примерно так: прочитал строку, проверил, нет ли в ней ошибок, перевел ее в машинный код, выполнил команды машинного кода, запомнил, где нужно результат и перешел к следующей строке. Чтобы сделать, например, операцию

интерпретатор обращается к процессору несколько сот раз. Вам этого не видно, все равно результат появится на экране через доли секунды, но это так.

Если же Вам позже придется вернуться к этой строке (например, с помощью GO TO 10), то все эти действия будут повторены.

А ведь многие операции выполняются в циклах.

Таким образом, интерпретатор работает крайне медленно. Зато имеется возможность работы в диалоговом режиме. Так, на Бейсике, когда Вы набираете программу, каждая строка сразу же и проверяется на правильность синтаксиса и, если Вы сделаете ошибку, то строка не будет введена в программу нажатием клавиши ENTER до тех пор, пока Вы эту ошибку не устраните. Вы всегда можете прервать работу программы, внести изменения и стартовать опять, причем с той строки, с какой хотите. Работать с интерпретатором БЕЙСИКа настолько удобно для начинающих, что на многих моделях персональных ЭВМ, в том числе и на «ZX-Spectrum`е», он уже «зашит» в постоянное запоминающее устройство (ПЗУ) и служит не только языком программирования, но и выполняет функции операционной системы компьютера. При включении компьютера в сеть он сразу готов к выполнению команд БЕЙСИКа.

В отличие от интерпретатора, компилятор переводит Вашу программу с языка высокого уровня (например, Паскаля или Фортрана) в машинные коды всю целиком. После того, как программа написана, она компилируется в машинный код. Программа, написанная Вами на языке, называется исходным текстом (исходным модулем, исходным блоком, исходным файлом). То, что Вы получаете в результате компиляции, называется объектным кодом (модулем). Вы можете выгрузить объектный код на ленту, а потом снова загрузить. Можете запустить его на исполнение, но здесь у Вас уже нет возможности во время работы программы ее остановить, внести изменения и снова запустить с произвольно взятого места. Если такая необходимость возникает, надо заново загрузить исходный текст программы, внести изменения, а потом опять откомпилировать его в машинный код.

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

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

Итак, программирование в машинном коде (на Ассемблере) позволяет повысить скорость работы программы по сравнению с работой через интерпретатор в 50…200 раз и в 1,5…3 раза по сравнению с кодом, прошедшим компиляцию. Это бывает чрезвычайно важно, если в программе есть многочисленные вложенные друг в друга циклы, если многократно выполняются поиск и выбор данных из обширных областей памяти. Много времени занимают операции, связанные с обработкой графических изображений на экране. Эффект плавного и быстрого перемещения (и изменения формы) объектов в компьютерных видеоиграх практически всегда создается программированием в машинном коде.

Сравним расход памяти при работе на БЕЙСИКе и в машинных кодах. Программа на БЕЙСИКе размером в 30 строк занимает примерно 1К памяти.

Аналогичная ей, выполняющая те же задачи, программа в машинных кодах будет иметь примерно 150 строк (команд), но занимают они всего 200…250 байтов оперативной памяти.

В нашей стране есть еще две объективные причины, вызывающие повышенный интерес к программированию в машинных кодах.

Дело в том, что наибольшее число пользователей этого класса компьютеров у нас составляют радиолюбители и специалисты по электронике, самостоятельно собравшие компьютер. Обычно они не останавливаются на достигнутом результате. А развивают свое хобби дальше, ищут пути усовершенствования машины, пути подключения дополнительных устройств: интерфейсов принтера, дисковода, джойстика, светового пера, программатора, контроллеров бытовой аппаратуры, бытовых систем, систем управления различными моделями и т.д. Вплоть до систем управления технологическими процессами промышленных предприятий. В конце 80-х годов в Душанбе на базе этого компьютера была сделана система голосования республиканского парламента. Работают под управлением «Спектрума» и очень интересные системы управления сельскохозяйственными предприятиями (фермами и птицефермами). Интересны автоматизированные системы диагностирования автомобиля, системы контроля состояния спортсменов и многое другое. Поскольку процедуры, управляющие работой всех этих устройств (их называют драйверами), обычно пишутся в машинных кодах, то их надо знать и уметь с ними работать.

Другая особенность состоит в том, что основная масса программ для Синклер-компьютеров написана в Англии на английском языке. Желание адаптировать эти программы на русский язык во многих случаях упирается в необходимость понимания структуры программы, а большинство лучших программ написано именно в машинных кодах.

«ИНФОРКОМ» получает множество писем с вопросами по поводу переделки системы загрузки фирменных программ. Мы так понимаем, что многие уже обзавелись дисководом с Бета-диск интерфейсом, и теперь перед ними стоит задача переписывания программ на диск. При этом пользоваться "магической кнопкой" они не хотят, т.к. при этом любая, даже самая короткая программа будет занимать на диске 48К, а хотят ее переписать на диск блок за блоком и сопроводить загрузчиком с диска. На все эти вопросы ответ может быть только один. Поскольку разные фирмы в своих программах применяют разные системы загрузки, универсального решения здесь не существует. К каждой программе нужен индивидуальный подход. Надо прочитать загрузчик программы, понять куда какой блок загружается и в каком порядке они стартуют, а затем, если надо, внести в него свои изменения. Поскольку лучшие программы имеют при себе загрузчик в машинных кодах (обычно он следует после БЕЙСИК-загрузчика или организован внутри него в строке после оператора REM), то умение работать с машинным кодом Вам пригодится и здесь. Вот в основном те причины, которые могут побудить Вас к освоению программирования в машинных кодах или хотя бы их пониманию (что достигается гораздо быстрее, чем способность активного программирования, но имеет не меньше значения), хотя хотелось бы отметить еще два важных, на наш взгляд, обстоятельства.

Во-первых, «Спектрум» имеет ПЗУ объемом 16К. Эта память буквально насыщена множеством очень полезных системных процедур. Все они записаны в машинных кодах. Их можно смело применять в собственных программах, обращаясь к ним по мере необходимости. Это дает колоссальный выигрыш в расходе памяти и вообще очень упрощает программирование. Поскольку все содержимое ПЗУ записано в машинном коде, умение разбираться в нем является необходимым. Для использования системных программ, содержащихся в ПЗУ, Вам необходимо ознакомиться с основами программирования в машинных кодах.

Во-вторых, изучение программирования в машинном коде процессора Z-80 хоть и трудоемкий, но очень полезный шаг для Вашего будущего. Компьютерная техника непрерывно прогрессирует. Широко внедряются IBM-совместимые машины с процессорами 8088, 8086, 80286, 80386, 80486. Процессор Z-80 - "двоюродный брат" процессора 8088 и имеет определенные черты сходства со всей этой серией. Те из Вас, кто свяжут свою судьбу с профессиональной вычислительной техникой, еще не раз вспомнят добром свои первые шаги в освоении машинного кода Z-80.

Что же касается особой трудоемкости работ по программированию в машинных кодах, то и здесь есть ряд возражений.

· Нет необходимости сразу программировать. На первом этапе Вы уже сможете многого достичь, если будете просто разбираться в программах, а дальше все придет с набором опыта.

· Существуют ассемблирующие программы, которые имеют достаточный набор средств, чтобы освободить Вас от самой рутинной работы и снизить трудоемкость программирования.

· Как правило, нет никакой необходимости всю программу писать в машинных кодах. Всегда в ней можно выделить блок, который решающим образом влияет на быстродействие. Он может быть очень маленьким по размеру. Вот его-то и надо записать в машинных кодах, а остальную часть программы оставить, например, на БЕЙСИКе. Если Вы создаете программу "русско-английский словарь", то она вполне может быть написана на БЕЙСИКе и только процедура поиска перевода слова, занимающая много времени, должна быть записана в машинных кодах. Если же Вы создаете русско-китайский словарь, то еще одним узким местом станет рисование на экране иероглифов. Вам придется записать несколько процедур, которые смогут делать это быстро. Диалог с пользователем программа может вести и из БЕЙСИКа.

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

Конечно, если Вы делаете только первые шаги в машинных кодах, то у Вас нет еще такой библиотеки, но прочитав эту книгу, Вы уже можете покопаться в машинном коде некрупных фирменных программ. Там Вы найдете множество открытий. В этом Вам очень поможет какая-либо дисассемблирующая программа, например MONITOR 16/48. Для Вас открыты и другие книги «ИНФОРКОМа» и, самое главное, наши выпуски «ZX-РЕВЮ».

Читайте также: