(Справочное пособие) В пособии рассматривается язык макроассеблера для персональных ЭВМ типа IBM PC (язык MASM, версия 4.0) . Пособие состоит из 4 глав. В главе 1 рассмотрены особенности персональных компьютеров типа IBM PC и приведены начальные сведения о языке MASM. В главе 2 описывается система команд этих компьютеров. Глава 3 посвящена собственно языку MASM. В главе 4 приведены примеры фрагментов программ и полных программ на MASM для решения различных задач. В пособии не рассматриваются вопросы, связанные с обработкой двоично-десятичных чисел и работой арифметического сопроцессора 8087 или 80287. Под термином "ПК" в пособии понимается персональный компьютер типа IBM PC c микропроцессором 8088/8086,80186 или 80286. ГЛАВА 1. ОСОБЕННОСТИ ПК. ВВЕДЕНИЕ В MASM. 1.1. ОПЕРАТИВНАЯ ПАМЯТЬ. РЕГИСТРЫ. 1.1.1 Оперативная память Объем оперативной памяти ПК - 2^20 байтов (1 Мб) . Байты нумеруются начиная с 0, номер байта называется его адресом. Для ссылок на байты памяти используются 20-разрядные адреса: от 00000 до FFFFF (в 16-ричной системе) . Байт содержит 8 разрядов (битов) , каждый из которых может принимать значение 1 или 0. Разряды нумеруются справа налево от 0 до 7: ---------------- | | | | | | | | | ---------------- 7 6 5 4 3 2 1 0 Байт - это наименьшая адресуемая ячейка памяти. В ПК используются и более крупные ячейки - слова и двойные слова. Слово - это два соседних байта, размер слова - 16 битов (они нумеруются справа налево от 0 до 15) . Адресом слова считается адрес его первого байта (с меньшим адресом) ; этот адрес может быть четным и нечетным. Двойное слово - это любые четыре соседних байта (два соседних слова) , размер такой ячейки - 32 бита; адресом двойного слова считается адрес его первого байта. Байты используются для хранения небольших целых чисел и символов, слова - для хранения целых чисел и адресов, двойные слова - для хранения "длинных" целых чисел и т. н. адресных пар (сегмент: смещение) . 1.1.2 Регистры Помимо ячеек оперативной памяти для хранения данных (правда, кратковременного) можно использовать и регистры - ячейки, входящие в состав процессора и доступные из машинной программы. Доступ к регистрам осуществляется значительно быстрее, чем к ячейкам памяти, поэтому использование регистров заметно уменьшает время выполнения программ. Все регистры имеют размер слова (16 битов) , за каждым из них закреплено определенное имя (AX, SP и т.п.) . По назначению и способу использования регистры можно разбить на следующие группы: - регистры общего назначения (AX, BX, CX, DX, BP, SI, DI, SP) ; - сегментные регистры (CS, DS, SS, ES) ; - счетчик команд (IP) ; - регистр флагов (Flags) . (Расшифровка этих названий: A accumulator, аккумулятор; B - base, база; C - counter, счетчик; D - data, данные; BP base pointer, указатель базы; SI - source index, индекс источника; DI - destination index, индекс приемника; SP - stack pointer, указатель стека; CS code segment, сегмент команд; DS - data segment, сегмент данных; SS stack segment, сегмент стека; ES - extra segment, дополнительный сегмент; IP - instruction pointer, счетчик команд.) Регистры общего назначения можно использовать во всех арифметических и логических командах. В то же время каждый их них имеет определенную специализацию (некоторые команды "работают" только с определенными регистрами) . Например, команды умножения и деления требуют, чтобы один из операндов находился в регистре AX или в регистрах AX и DX (в зависимости от размера операнда) , а команды управления циклом используют регистр CX в качестве счетчика цикла. Регистры BX и BP очень часто используются как базовые регистры, а SI и DI - как индексные. Регистр SP обычно указывает на вершину стека, аппаратно поддерживаемого в ПК. Регистры AX, BX, CX и DX конструктивно устроены так, что возможен независимый доступ к их старшей и младшей половинам; можно сказать, что каждый из этих регистров состоит из двух байтовых регистров, обозначаемых AH, AL, BH и т.д. (H - high, старший; L - low, младший) : ----------- ----------- ----------- ----------AX | AH | AL | BX | BH | BL | CX | CH | CL | DX | DH | DL | --------------------- ----------- ---------- 15 8 7 0 Таким образом, с каждым из этих регистров можно работать как с единым целым, а можно работать и с его "половинками". Например, можно записать слово в AX, а затем считать только часть слова из регистра AH или заменить только часть в регистре AL и т.д. Такое устройство регистров позволяет использовать их для работы и с числами, и с символами. Все остальные регистры не делятся на "половинки", поэтому считать или записать их содержимое (16 битов) можно только целиком. Сегментные регистры CS, DS, SS и ES не могут быть операндами никаких команд, кроме команд пересылки и стековых команд. Эти регистры используются только для сегментирования адресов (см. 1.4) . Счетчик команд IP всегда содержит адрес (смещение от начала программы) той команды, которая должна быть выполнена следующей (начало программы хранится в регистре CS) . Содержимое регистра IP можно изменить только командами перехода. 1.1.3 Флаги И, наконец, в ПК имеется особый регистр флагов. Флаг - это бит, принимающий значение 1 ("флаг установлен") , если выполнено некоторое условие, и значение 0 ("флаг сброшен") в противном случае. В ПК используется 9 флагов, каждому из них присвоено определенное имя (ZF, CF и т.д.) . Все они собраны в регистре флагов (каждый флаг - это один из разрядов регистра, часть его разрядов не используется) : ------------------------------------------------ Flags | x| x| x| x|OF|DF|IF|TF|SF|ZF| x|AF| x|PF| x|CF| -----------------------------------------------15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Некоторые флаги принято называть флагами условий; они автоматически меняются при выполнении команд и фиксируют те или иные свойства их результата (например, равен ли он нулю) . Другие флаги называются флагами состояний; они меняются из программы и оказывают влияние на дальнейшее поведение процессора (например, блокируют прерывания) . Флаги условий: CF (carry flag) - флаг переноса. Принимает значение 1, если при сложении целых чисел появилась единица переноса, не "влезающая" в разрядную сетку, или если при вычитании чисел без знака первое из них было меньше второго. В командах сдвига в CF заносится бит, вышедший за разрядную сетку. CF фиксирует также особенности команды умножения. OF (overflow flag) - флаг переполнения. Устанавливается в 1, если при сложении или вычитании целых чисел со знаком получился результат, по модулю превосходящий допустимую величину (произошло переполнение мантиссы и она "залезла" в знаковый разряд) . ZF (zero flag) - флаг нуля. Устанавливается в 1, если результат команды оказался равным 0. SF (sign flag) - флаг знака. Устанавливается в 1, если в операции над знаковыми числами получился отрицательный результат. PF (parity flag) - флаг четности. Равен 1, если результат очередной команды содержит четное количество двоичных единиц. Учитывается обычно только при операциях ввода-вывода. AF (auxiliary carry flag) - флаг дополнительного переноса. Фиксирует особенности выполнения операций над двоично-десятичными числами. Флаги состояний: DF (direction flag) - флаг направления. Устанавливает направление просмотра строк в строковых командах: при DF=0 строки просматриваются "вперед" (от начала к концу) , при DF=1 - в обратном направлении. IF (interrupt flag) - флаг прерываний. При IF=0 процессор перестает реагировать на поступающие к нему прерывания, при IF=1 блокировка прерываний снимается. TF (trap flag) - флаг трассировки. При TF=1 после выполнения каждой команды процессор делает прерывание (с номером 1) , чем можно воспользоваться при отладке программы для ее трассировки. 1.2. ПРЕДСТАВЛЕНИЕ ДАННЫХ. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ Здесь рассматривается машинное представление целых чисел, строк и адресов. Представление двоично-десятичных чисел, используемых достаточно редко, не рассматривается. Что касается вещественных чисел, то в ПК нет команд вещественной арифметики (операции над этими числами реализуются программным путем или выполняются сопроцессором) и потому нет стандартного представления вещественных чисел. Кроме того, рассматриваются некоторые особенности выполнения арифметических операций. Шестнадцатиричные числа записываются с буквой h на конце, двоичные числа - с буквой b (так принято в MASM) . 1.2.1 Представление целых чисел. В общем случае под целое число можно отвести любое число байтов, однако система команд ПК поддерживает только числа размером в байт и слово и частично поддерживает числа размером в двойное слово. Именно эти форматы и будут рассмотрены. В ПК делается различие между целыми числами без знака (неотрицательными) и со знаком. Это объясняется тем, что в ячейках одного и того же размера можно представить больший диапазон беззнаковых чисел, чем неотрицательных знаковых чисел, и если известно заранее, что некоторая числовая величина является неотрицательной, то выгоднее рассматривать ее как беззнако