Ассемблерные языки, ассемблеры

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

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

Задача. Написать МиК-программу нахождения модуля (абсолютной величины) заданного числа a.

Решение.  Откажемся от словесной формулировки алгоритма решения выше приведённой задачи и от предварительного распределения памяти. Вместо этого, сразу  запишем алгоритм в системе команд МиК, но, используя при этом не числовые, а  символические  обозначения:

Адреса

Данные и команды

                         Комментарии

 

In

S:=a; {Ввод а}

 

Jm        L1

Если a<0, перейти на команду с адресом L1

 

Jmp      L2

{a >= 0 } перейти на команду с адресом L2

L1

St         W1

W1:=a;  {временно сохранить a<0   в  W1}

 

Lda       0000

S:=0;    { для перемены знака а}

 

Sub       W1

S:=0-a   {вычесть а  из нуля     }

L2

Out

Вывод (S )   {S=|a|}

 

Halt

Остановка

W1

?

Рабочая ячейка для сохранения  a

 Смысл использованных обозначений прост:

1) Вместо числовых кодов операций мы подставили их мнемонические имена;

2) Вместо фактических адресов команд и данных мы записали придуманные нами символические имена соответствующих ячеек памяти (L1, L2, W1).

Анализируя полученную запись, видим, что её структура в точности  соответствует структуре решающей поставленную задачу МиК-программы, но при этом,  проще, наглядней и понятней числовой её формы.

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

Для этого достаточно:

1) Выбрать адрес загрузки программы (такой выбор позволит, с учётом известных форматов команд, определить  абсолютные адреса всех  команд и данных, построив, тем самым, таблицу распределения памяти);

2) Заменить в командах все мнемонические коды операций соответствующими числовыми кодами;

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

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

Распределение памяти МиК ( таблица имён ) для решения задачи 3

         L1

          L2

         W1

       0707

         0716

        0718

Далее, выполнив шаги 2 и 3 выше описанной процедуры,  легко восстановить программный числовой код представляющий решение данной задачи на машинном языке МиК:

Адреса

Данные и команды

                         Комментарии

0700 

01

S:=a {Ввод а}

0701 

34   0707

Если a<0, перейти на команду с адресом L1

0704 

30   0716

{a >= 0 } перейти на команду с адресом L2

0707

22   0718

W1:=a    {временно сохранить a<0   в  W1}

0710 

23   0000

S:=0;     {для перемены знака а}

0713 

11   0718

S:=0-a    {вычесть а  из нуля }

0716

02

Вывод   {S=|a|}

0717 

99

Остановка

0718

?

Рабочая ячейка для сохранения  a

Следует отметить, что  в таблицу имён мы включили информацию только о тех именах (адресах памяти), на которые имеются ссылки из программы. Речь идёт о  метках  L1 и L2, помечающих   команды программы, на которые в соответствии с логикой алгоритма, передаётся управление командами переходов, а также о метке W1, именующей область оперативной памяти, в которой размещается данное.

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

 Резюмируя опыт решения выше приведённой задачи, сделаем следующие выводы.

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

2. Использование ЯСКа как ЯП позволяет разработчику, оставаясь в рамках низкоуровневого программирования, т.е. сохраняя полный контроль над командами процессора, сосредоточиться на логике своей программы, не отвлекаясь при этом на особенности её числового кодирования.

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

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

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

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

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

5
Your rating: Нет Average: 5 (17 votes)