Справочник программиста на персональном компьютере фирмы IBM. Приложения - Основные сведения о языке ассемблера. Часть 2

ОГЛАВЛЕНИЕ



   На  первый  взгляд стек кажется достаточно неуклюжим  способом
хранения информации, но у него есть  два преимущества. Во-первых,
доступ к его содержимому намного быстрее, чем к переменным,  хра-
нящимся в памяти,  а,  во-вторых,  стек  может использоваться для
многих  целей.   Он может хранить адреса возврата  из  процедуры,
вложенной в другую  процедуру.  Впоследствии,  то же самое прост-
ранство  может использоваться программистом для хранения  данных,
которые должны сейчас  обрабатываться,  но для которых не хватает
места в регистрах микропроцессора. Программа выталкивает содержи-
мое регистра на стек командой PUSH, а позднее забирает его оттуда
командой POP.  В ассемблерных программах, приведенных в этой кни-
ге, Вы не раз встретитесь с  инструкциями  типа PUSH BX и POP DX.
Неправильный  порядок  обмена данными со стеком -  лучший  способ
привести ассемблерную программу к краху.
   После того как программист на  ассемблере  установил  три сег-
ментных регистра (CS, DS и SS) и загрузил данные в регистры  мик-
ропроцессора он имеет широкий  набор встроенных средств, которыми
процессор может помочь программисту на ассемблере.  Вот  наиболее
распространенные из них:

ADD AX,BX   Прибавляет BX к AX. Существует также инструкция вычи-
            тания (SUB), а также варианты обеих этих инструкций.

MUL BL      Умножает BL на AX.  Имеется также инструкция  деления
            (DIV), а также варианты обеих этих инструкций.

INC BL      Увеличивает BL на 1.  Имеется также инструкция умень-
            шения (DEC).

LOOP XXX    Возвращает  программу назад к строке помеченной  XXX,
            повторяя процесс столько  раз, какое число содержится
            в CX (аналогично инструкции FOR ..  TO .. NEXT в Бей-
            сике).

OR AL,BL    Выполняет  операцию  логического  ИЛИ  над содержимым
            регистров  AL и BL, причем результат помещается в AL.
            Имеются также инструкции AND, XOR и NOT.

SHL AX,1    Сдвигает все биты, содержащиеся в AX, на одну позицию
            влево.   Это эквивалентно умножению содержимого AX на
            2.  Другие инструкции  сдвигают  биты вправо или осу-
            ществляют циклический сдвиг. Все эти инструкции очень
            полезны для  битовых  операций,  таких  как установка
            точек экрана.
IN AL,DX    Помещает в AX байт, обнаруженный в порте, адрес кото-
            рого указан в DX. Имеется также инструкция OUT.

JMP         Передает управление  в  другое  место  программы, как
            инструкция GOTO в Бейсике.  JMP YYY передает управле-
            ние на строку программы, имеющую метку YYY.

CMP AL,BL   Сравнивает содержимое  AL  и  BL.  За инструкцией CMP
            обычно следует инструкция условного перехода.  Напри-
            мер, если за инструкцией CMP  следует инструкция JGE,
            то переход произойдет только если BL больше или равно
            AL.  Инструкция CMP достигает того же результата, что
            и  инструкция  IF ..  THEN в Бейсике (на  самом  деле
            инструкция IF ..   THEN  переводится  интерпретатором
            Бейсика в инструкцию CMP).

TEST AL,BL  Проверяет  есть  ли среди битов, установленных в  BL,
            такие,  которые  установлены  также  и  в AL. За этой
            инструкцией обычно следует команда условного  перехо-
            да, так же как за CMP. TEST очень полезен при провер-
            ке  статусных  битов (битовые операции  очень  просто
            реализуются в языке ассемблера).

MOVS        Пересылает строку, длина  которой  содержится в CX, с
            места, на которое указывает SI, на место, на  которое
            указывает DI. Имеется еще  несколько  других инструк-
            ций, связанных с пересылкой и поиском строк.

Язык ассемблера обеспечивает несколько вариантов этих инструкций,
а  также ряд других специальных инструкций.  Имеется также  целый
класс инструкций, называемых псевдооператорами, которые помещают-
ся в текст программы с целью указания ассемблеру как обрабатывать
данную программу. Например, один  из типов псевдооператоров авто-
матически  вставляет часто используемый кусок кода по всей  прог-
рамме. Такая порция кода называется макросом и именно это свойст-
во ассемблера дало ему название "макроассемблер".
   И,  наконец,  ассемблер  имеет возможность,  которой  завидуют
(или, по крайней мере, должны  завидовать)  все кто программирует
только на языках высокого уровня. Имеется ввиду возможность опти-
мальным образом  использовать  прерывания  операционной  системы.
Ведь  это ничто иное, как готовые процедуры.  Однако вместо того,
чтобы вызывать их по CALL, они вызываются инструкцией INT. INT21H
вызывает  прерывание с шестнадцатиричным номером 21.  Имеется ряд
таких прерываний, как в базовой системе ввода/вывода ПЗУ, так и в
операционной системе, причем некоторые из этих процедур необычай-
но мощны.  На самом деле некоторые из них настолько тесно связаны
с  системой,  что Вы практически не можете сами написать  эквива-
лентную процедуру.  Языки  высокого уровня позволяют использовать

многие из этих прерываний. Они используют их для вывода на экран,
приема ввода с клавиатуры и доступа к дискам.  Но многие действи-
тельно полезные прерывания игнорируются языками высокого  уровня,
например такие,  которые  позволяют  запустить из одной программы
другую.   Некоторые  трансляторы (такие как Lattice C  или  Turbo
Pascal) позволяют доступ к этим  прерываниям,  если Вы знаете как
их готовить и Вы можете использовать разделы среднего уровня этой
книги для этой цели.
   Перед  вызовом  прерывания  некоторая  информация  должна быть
помещена в регистры процессора.  Например, прерывание, верикально
сдвигающее экран, должно знать  размеры  сдвигаемого  окна, число
строк  на  которое его надо сдвинуть и т.д.  Эти  значения  часто
называют входными регистрами.  Снова  и снова Вы будете встречать
слова "при входе BX должен содержать ...", описывающие специфика-
цию входных  регистров.   Аналогично,  при возврате из прерывания
некоторые  регистры возвращают значения или статусную информацию.
Они называются  выходными  регистрами  и  мы описываем их словами
"при выходе AX содержит ...".  Зачастую одно прерывание  содержит
много функций. В частности, операционная система впихнула практи-
чески все свои возможности в прерывание 21H.  Поэтому при  вызове
прерывания необходимо  указывать  номер  функции.  Все прерывания
(как  BIOS  так и DOS) передают номер функции в AH  (иногда в  AL
содержится номер подфункции).