Страница 6 из 21
На первый взгляд стек кажется достаточно неуклюжим способом хранения информации, но у него есть два преимущества. Во-первых, доступ к его содержимому намного быстрее, чем к переменным, хра- нящимся в памяти, а, во-вторых, стек может использоваться для многих целей. Он может хранить адреса возврата из процедуры, вложенной в другую процедуру. Впоследствии, то же самое прост- ранство может использоваться программистом для хранения данных, которые должны сейчас обрабатываться, но для которых не хватает места в регистрах микропроцессора. Программа выталкивает содержи- мое регистра на стек командой 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 содержится номер подфункции).
|