Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Питер Абель Весь текст 992.61 Kb

Ассемблер и программирование для IBM PC

Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 85
               Один операнд     INC     CX        ;Увеличить CX
               Два операнда     ADD     AX,12     ;Прибавить 12 к AX

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


     ДИРЕКТИВЫ
     ________________________________________________________________

     Ассемблер имеет ряд операторов, которые позволяют упpавлять процессом
ассемблирования  и  формирования  листинга.  Эти   операторы    называются
псевдокомандами  или  директивами.  Они  действуют  только   в    процессе
ассемблирования программы и  не  генерируют  машинных  кодов.  Большинство
директив показаны  в  следующих  разделах.  В  гл.24  подробно описаны все
директивы ассемблера и  приведено  более  чем  достаточно  соответствующей
информации. Гл.24 можно использовать в качестве справочника.


               Директивы управления листингом: PAGE и TITLE
              ----------------------------------------------
     Ассемблер содержит ряд директив,  управляющих  форматом  печати  (или
листинга).  Обе  директивы  PAGE  и  TITLE  можно  использовать  в   любой
программе.


     Д и р е к т и в а  PAGE.  В начале программы можно указать количество
строк,  распечатываемых  на  одной  странице,  и  максимальное  количество
символов на одной строке.  Для этой цели cлужит директива PAGE.  Следующей
директивой устанавливается 60 строк на страницу и 132 символа в строке:

                               PAGE 60,132

Количество строк на странице может  быть  в  пределах  от  10  до  255,  а
символов в строке - от 60 до 132. По умолчанию  в  ассемблере  установлено
PAGE 66,80.
     Предположим, что счетчик  строк  установлен  на  60.  В  этом  случае
ассемблер, распечатав 60 строк, выполняет прогон листа на начало следующей
страницы и  увеличивает  номер  страницы  на  eдиницу.  Кроме  того  можно
заставить ассемблер сделать прогон листа на конкретной строке, например, в
конце  сегмента.  Для  этого  необходимо  записать  директиву  PAGE    без
операндов.  Ассемблер автоматически  делает  прогон  листа  при  обработке
диpективы PAGE.


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

                              TITLE   текст

     Рекомендуется в  качестве  текста  использовать  имя  программы,  под
которым она находится  в  каталоге  на  диске.  Например,  если  программа
называется  ASMSORT,  то  можно  использовать  это  имя  и    описательный
комментарий общей длиной до 60 символов:

          TITLE ASMSORT - Ассемблерная программа сортировки имен

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


                            Директива SEGMENT
                           -------------------
     Любые ассемблерные программы содержат по крайней мере один сегмент  -
сегмент кода.  В некоторых программах используется  сегмент  для  стековой
памяти и сегмент данных для определения данных. Асcемблерная директива для
описания сегмента SEGMENT имеет следующий формат:

               Имя       Директива      Операнд
               имя       SEGMENT        [параметры]
                         .
                         .
                         .
               имя       ENDS

     Имя сегмента должно обязательно  присутствовать,  быть  уникальным  и
соответствовать  соглашениям  для  имен  в  ассемблере.  Директива    ENDS
обозначает конец сегмента.  Обе директивы  SEGMENT  и  ENDS  должны  иметь
одинаковые имена.  Директива SEGMENT может содержать три типа  параметров,
определяющих выравнивание, объединение и класс.

          1. В ы р а в н и в а н и е.  Данный параметр определяет  границу
     начала сегмента. Обычным значением является PARA, по которому сегмент
     устанавливается на границу параграфа.  В этом случае начальный  адрес
     делится  на 16 без остатка,  т.е.  имеет шест.  адрес nnn0.  В случае
     отсутствия этого операнда ассемблер принимает по умолчанию PARA.
          2. О б ъ е д и н е н и е.  Этот элемент определяет  объединяется
     ли данный сегмент с другими сегментами в  процессе  компановки  после
     ассемблирования  (пояснения  см.  в  следующем  разделе   "Компановка
     программы").  Возможны следующие  типы  объединений:  STACK,  COMMON,
     PUBLIC, AT выражение и MEMORY.  Сегмент стека определяется  следующим
     образом:
                       имя  SEGMENT   PARA   STACK

          Когда отдельно ассемблированные  программы  должны  объединяться
     компановщиком, то можно использовать типы: PUBLIC, COMMON и MEMORY. В
     случае, если программа не должна объединяться с другими  программами,
     то данная опция может быть опущена.
          3.  К л а с с.   Данный  элемент,   заключенный   в   апострофы,
     используется   для   группирования   относительных   сегментов    при
     компановке:

                  имя  SEGMENT   PARA   STACK   'Stack'

          Фрагмент программы на рис.3.1.  в следующем разделе иллюстрирует
     директиву SEGMENT и ее различные опции.


                              Директива PROC
                             ----------------
     Сегмент кода содержит выполняемые команды программы.  Кроме того этот
сегмент также включает в себя одну или  несколько  процедур,  определенных
директивой PROC. Сегмент, содержащий только одну процедуру имеет следующий
вид:
               имя-сегмента   SEGMENT   PARA
               имя-процедуры  PROC      FAR       Сегмент
                              .                   кода
                              .                   с
                              .                   одной
                              RET                 процедурой
               имя-процедуры  ENDP
               имя-сегмента   ENDS

     Имя процедуры должно обязательно присутствовать,  быть  уникальным  и
удовлетворять соглашениям по именам в ассемблере.  Операнд  FAR  указывает
загрузчику DOS, что начало данной  процедуры  является  точкой  входа  для
выполнения программы.
     Директива ENDP определяет конец процедуры и  имеет  имя,  аналогичное
имени в директиве PROC.  Команда RET завершает выполнение  программы  и  в
данном случае возвращает управление в DOS.
     Сегмент может содержать несколько процедур (см. гл.7).


                             Директива ASSUME
                            ------------------
     Процессор использует регистр SS для адресации стека, регистр  DS  для
адресации сегмента данных  и  регистр  CS  для  адресации  cегмента  кода.
Ассемблеру необходимо сообщить назначение каждого сегмента.  Для этой цели
служит директива ASSUME, кодируемая в сегменте кода следующим образом:

               Директива Операнд
               ASSUME     SS:имя_стека,DS:имя_с_данных,CS:имя_с_кода

     Например, SS:имя_стека указывает, что ассемблер должен  ассоциировать
имя сегмента стека с регистром SS.  Операнды могут  записываться  в  любой
последовательности.  Регистр  ES  также  может  присутствовать  в    числе
операндов.  Если программа не использует регистр ES, то его можно опустить
или указать ES:NOTHING.


                              Директива END
                             ---------------
     Как уже показано, директива ENDS завершает сегмент, а директива  ENDP
завершает процедуру.  Директива END в свою очередь полностью завершает всю
программу:

               Директива      Операнд
               END            [имя_процедуры]

     Операнд может  быть  опущен,  если  программа  не  предназначена  для
выполнения, например, если ассемблируются только определения  данных,  или
эта программа должна быть скомпанована с  другим  (главным)  модулем.  Для
обычной программы с  одним  модулем  oперанд  содержит  имя,  указанное  в
директиве PROC, которое было oбозначено как FAR.


     ПАМЯТЬ И РЕГИСТРЫ
     ________________________________________________________________

     Рассмотрим  особенности  использования  в  командах  имен,  имен    в
квадратных скобках и  чисел.  В  следующих  примерах  положим,  что  WORDA
определяет слово в памяти:

          MOV  AX,BX     ;Переслать содержимое BX в регистр AX
          MOV  AX,WORDA  ;Переслать содержимое WORDA в регистр AX
          MOV  AX,[BX]   ;Переслать содержимое памяти по адресу
                         ; в регистре BX в регистр AX
          MOV  AX,25     ;Переслать значение 25 в регистр AX
          MOV  AX,[25]   ;Переслать содержимое по смещению 25

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


     ИНИЦИАЛИЗАЦИЯ ПРОГРАММЫ
     ________________________________________________________________

     Существует  два  основных  типа  загрузочных  программ:  EXE  и  COM.
Рассмотрим требования к EXE-программам, а COM-программы будут представлены
в гл.6.  DOS  имеет  четыре  требования  для  инициализации   ассемблерной
EXE-программы:  1)  указать  ассемблеру,  какие cегментные регистры должны
соответствовать сегментам,  2) сохранить  в  стеке  адрес,  находящийся  в
регистре DS, когда программа начнет выполнение, 3) записать в стек нулевой
адрес и 4) загрузить в регистр DS адрес сегмента данных.
     Выход из программы и возврат в DOS сводится к  использованию  команды
RET.  Рис.3.1  иллюстрирует  требования  к  инициализации  и  выходу    из
программы:

          1. ASSUME - это ассемблерная  директива,  которая  устанавливает
     для  ассемблера  соответствие  между   конкретными    сегментами    и
     сегментными регистрами; в данном случае, CODESG - CS, DATASG -  DS  и
     STACKSG - SS.  DATASG и STACKSG не определены в этом примере, но  они
     будут представлены следующим образом:

          STACKSG  SEGMENT  PARA  STACK  Stack  'Stack'
          DATASG   SEGMENT  PARA  'Data'

          Ассоциируя сегменты с сегментными регистрами,  ассемблер  сможет
     определить смещения к отдельным областям в каждом сегменте. Например,
     каждая команда в сегменте  кодов  имеет  определенную  длину:  первая
     команда имеет смещение 0, и если это двухбайтовая команда, то  вторая
     команда будет иметь смещение 2 и т.д.
          2. Загрузочному модулю  в  памяти  непосредственно  предшествует
     256-байтовая (шест.100) область,  называемая  префиксом  программного
     сегмента  PSP.  Программа  загрузчика  использует  регистр  DS    для
     установки адреса  начальной  точки  PSP.  Пользовательская  программа
     должна сохранить этот адрес, поместив его в стек.  Позже, команда RET
     использует этот адрес для возврата в DOS.
          3.  В  системе  требуется,  чтобы  следующее  значение  в  стеке
     являлось нулевым адресом (точнее, смещением).  Для этого команда  SUB
     очищает регистр AX, вычитая его из этого же регистра  AX,  а  команда
     PUSH заносит это значение в стек.
          4.  Загрузчик  DOS  устанавливает  правильные  адреса  стека   в
     регистре SS и сегмента  кодов  в  регистре  CS.  Поскольку  программа
     загрузчика  использует  регистр  DS  для  других  целей,   необходимо
     инициализировать регистр DS двумя  командами  MOV,  как  показано  на
     рис.3.1. В следующем разделе этой главы "Исходная  программа.  Пример
     II" детально поясняется инициализация регистра DS.
          5. Команда RET обеспечивает выход из пользовательской  программы
     и возврат в DOS, используя для  этого  адрес,  записанный  в  стек  в
     начале программы командой PUSH DS. Другим обычно используемым выходом
     является команда INT 20H.
Предыдущая страница Следующая страница
1 ... 3 4 5 6 7 8 9  10 11 12 13 14 15 16 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама