



                             ЧАСТЬ V. ПРИЛОЖЕНИЯ



                        Приложение А.   СРЕДСТВА РАЗРАБОТКИ

              Использование командных файлов для автоматизации процес-
              са трансляции с языка Ассемблера
              Использование средства MAKE фирмы "Майкрософт"
              Использование шаблонов  для  создания программ с
              расширением ".COM" и ".EXE"
              Использование библиотечных стандартных программ



              В данном приложении описаны некоторые средства,  которые мо-
         гут упростить и повысить эффективность  использования  языка  Ас-
         семблера для разработки прикладных программ. Ниже приводится опи-
         сание:   автоматизации   процесса    разработки    программы    с
         использованием командных файлов; использование средства MAKE фир-
         мы "Майкрософт"; создание .EXE - и .COM-программ с помощью шабло-
         нов,  а также использование файлов "include" ("файлов включения")
         и библиотечных стандартных программ.

             Использование командных файлов для автоматизации процесса
                           трансляции с языка Ассемблера

              Процессор обработки команд MS-DOS - это часто одно из наиме-
         нее  ценимых  по достоинству средств данной операционной системы.
         Это средство,  однако, может оказаться очень полезным при исполь-
         зовании  вами  макроассемблера MASM.  В листингах A-1,  A-2 и A-3
         приводятся  исходные  тексты  программ  трех  командных   файлов:
         MASM2EXE.BAT, MASM2COM.BAT и MК.BAT.
              Командный файл MASM2EXE.BAT используется  для  автоматизации
         процесса  трансляции  с  языка ассемблера и редактирования связей
         .EXE - программ.
              Командный файл  MASM2COM.BAT  является  модификацией первого
         файла и включает процесс  преобразования  .EXE-  файлов  в
         .COM-файлы.
              Оба командных файла предназначены для работы с  макроассемб-
         лером  MASM  фирмы "Майкрософт" версий с 1.00 по 4.00 и большинс-
         твом версий редактора связей LINK.
              Значительно более  мощный  командный  файл разработки MК.BAT
         (листинг A-3) предназначен для  работы  с  макроассемблером  MASM
         версии  5.0  и  выше и редактором связей LINK версии 3.00 и выше.
         Командный файл MК.BAT может  использоваться  для  создания  .EXE,
         -.COM - или .ОВJ (объектных программ,  пригодных для редактирова-
         ния связей) - файлов с помощью заданных параметров строки команд.

             Использование командных файлов для макроассемблера  MASM
                                версий с 1.00 по 5

              Командные файлы MASM2EXE.BAT и  MASM2COM.BAT,  показанные  в
         листингах A-1 и A-2,  пригодны для использования с макроассембле-
         ром MASM версий с 1.00 по 4.00 и редактором связей LINK  версий с

                                      - П-2 -
         1.00 по 2.00.
              Модификации командных файлов для более поздних версий макро-
         ассемблера  MASM и редактора связей LINK приводятся в примечаниях
         к листингам.  Оба командных файла требуют наличия второго  файла,
         называемого AUTOLINK.  Этот файл содержит четыре команды возврата
         каретки и перевода строки и используются  для  решения  проблемы,
         касающейся редактора связей LINK (вплоть до версии 2.00): послед-
         ний не может воспринимать  пустые  (неопределенные)  параметры  в
         строке команды для опций распечатки (.МАР) и библиотек (.LIB).
              Инициирование файла AUTOLINK для редактора связей LINK  осу-
         ществляется путем добавления имени файла в строке команды с пред-
         шествующим ему знаком @.  Знак "@" используется для совместимости
         версий  2.00  операционной системы MS-DOS с предыдущими версиями,
         поскольку более  ранние  версии  не  поддерживают  переназначение
         строки команд.
              Использовать конкретный командный файл очень  просто. Просто
         введите  имя данного командного файла с последующим именем файла,
         подлежащего трансляции.  Не включайте расширение,  в то время как
         расширение .ASM допускается.  Если вы используете версию 2.00 или
         выше операционной системы MS-DOS,  и путь доступа PATH установлен
         корректно, то драйверы, на которых хранятся связанные с ними фай-
         лы, не должны указываться.

                         Листинг A-1. MASM2EXE.BAT
         ─────────────────────────────────────────────────────────────
              echo  off
              if not exist %1.asm goto NOFILLER
              rem
              masm %1 %1 nul nul
              rem
              rem Используйте вышеприведенные строки только с версиями
              rem MASM ниже 2.00
              rem Используйте "masm %1.asm,,;" для макроассемблера MASM
              rem версии 2.00 и выше
              rem
              Link %1 @a:autolink
              rem
              rem  Используйте вышеприведенные строки только с версиями
              rem  редактора связей LINK ниже 2.20;
              rem  Используйте "link %1.obj,,nul;" для редактора связей
              rem  LINK версии 2.20 и выше
              rem
              echo Удаление %1.obj
              del %1.obj >nul:
              echo Выполнено!
              dir %1.*
              goto END
              rem
              :NOFILERR
              echo Файл %1.asm не был найден.
              :END
         ─────────────────────────────────────────────────────────────



                                      - П-3 -
                          Листинг A-2. MASM2COM.BAT
         ─────────────────────────────────────────────────────────────
              echo off
              if not exist %1.asm goto NOFILERR
              rem
              masm %1 %1 nul nul
              rem
              rem Используйте вышеприведенные строки только с версиями
              rem MASM ниже 2.00
              rem Используйте "masm %1.asm,,;" для макроассемблера MASM
              rem версии 2.00 и выше
              rem
              link %1. @a:autolink
              rem
              rem  Используйте вышеприведенные строки только с версиями
              rem  редактора связей LINK ниже 2.20;
              rem  Используйте "link %1.obj,,nul;" для редактора связей
              rem  LINK версии 2.20 и выше
              rem
              echo Удаление %1.obj
              del %1.obj >nul:
              echo Создание %1.com из %1.exe (и удаление %1.exe)
              exe2bin %1.exe %1.com >nul:
              del %1.exe >nul:
              echo Выполнено!
              dir %1.*
              goto End
              rem
              :NOFILERR
              echo Файл %1.asm не был найден.
              :END
         ─────────────────────────────────────────────────────────────

              Отметим, что некоторые строки в листинге A-1 и A-2  заканчи-
         ваются параметрами переназначения вывода. Если вы используете бо-
         лее раннюю  версию  по  сравнению  с  2.00  операционной  системы
         MS-DOS, то эти параметры должны быть удалены.

             Использование  командных файлов для макроассемблера MASM
                                  версий 5 и выше

              Если вы  используете макроассемблер MASM версии 5 и редактор
         связей LINK версии 3 или выше,  можно использовать командный файл
         МК.BAT,  показанный  в листинге A-3.  Командный файл МК.BAT может
         быть использован для создания или .EXE,  -.COM, - или .OBJ - фай-
         лов путем указания корректного параметра в строке команды.
              К примеру, если вы хотите оттранслировать с языка ассемблера
         файл,  называемый TEST1.ASM.  для создания файла TEST1.EXE просто
         введите "МК TEST1.EXE".  Наоборот,  если  целевым  является  файл
         TEST1.COM,  введите  "MK  TEST1.COM" или введите "МК ТEST1.OBJ" с
         целью создания .ОВJ файлов объектных программ,  пригодных для ре-
         дактирования связей.
              Командный файл MK.BAT, кроме того, использует коды возврата,
         генерируемые макроассемблером MASM и редактором связей LINK . Ес-
         ли код возврата, отличный от "0", возвращается или макроассембле-
         ром  MASM  или  редактором связей LINK,  то командный файл МК.BAT
         приостанавливает обработку и выдает сообщение об ошибке.

                                      - П-4 -
              Обнаружение ошибки в командном файле МК.BAT полезно,  к при-
         меру, в случае обнаружения ошибки макроассемблером MASM в процес-
         се  трансляции  с  языка ассемблера,  в результате чего командный
         файл МК.BAT лишается продолжения процесса  редактирования  связей
         до тех пор,  пока не будет зафиксирована ошибка в исходном файле.
                           Листинг A-3. MK.BAT
      ─────────────────────────────────────────────────────────────
      @ECHO off
      REM Используйте вышеприведенную строку для предотвращения вывода
      REM на экран строки "ECHO off", но только в случае работы  с
      REM версией 3.3 и выше операционной системы DOS. В других случаях
      REM используйте  следующие две строки с загруженным ANSI.SYS
      REM ("^[" = Символ EScape (переход) в коде ASCII*).
      REM Выключить режим вывода на экран исполняемых команд
      REM (ECHO off)
      REM ECHO ^[[s^[[1A^[[K^[[u
      REM
         IF (%1)==() goto : NOPARM
         IF not exist %1.asm goto :NOFILE
         SET F1=%1
         IF (%2)==()  : ASKTYPE
         SET TYPE=%2
         IF (%3)==() goto :CHKTYPE
         SET MASMS=
         SET LINKS=
         IF (%3)==(m) SET MASMS=%4
         IF (%3)==(M) SET MASMS=%4
         IF (%3)==(mo) SET MASM=%4
         IF (%3)==(mO) SET MASM=%4
         IF (%3)==(Mo) SET MASM=%4
         IF (%3)==(MO) SET MASM=%4
       rem
         IF (%3)==(l)  SET LINKS=%4
         IF (%3)==(L)  SET LINKS=%4
         IF (%3)==(lo)  SET LINK=%4
         IF (%3)==(lO)  SET LINK=%4
         IF (%3)==(Lo)  SET LINK=%4
         IF (%3)==(LO)  SET LINK=%4
       rem
         IF (%5)==(m) SET MASMS=%6
         IF (%5)==(M) SET MASMS=%6
         IF (%5)==(mo) SET MASM=%6
         IF (%5)==(mO) SET MASM=%6
         IF (%5)==(Mo) SET MASM=%6
         IF (%5)==(MO) SET MASM=%6
       rem
         IF (%5)==(l) SET LINKS=%6
         IF (%5)==(L) SET LINKS=%6
         IF (%5)==(lo) SET LINK=%6
         IF (%3)==(lO) SET LINK=%6
         IF (%3)==(Lo) SET LINK=%6
         IF (%3)==(LO) SET LINK=%6
       rem
         GOTO :CHKTYPE
       :ASKTYPE
         ECHO ^H
         ANSWER Наберите имя файла,  подлежащего созданию: OBJ, COM

                                      - П-5 -
                или EXE и нажмите клавишу ENTER
        ECHO ^H
      :CHKTYPE
        IF (%TYPE%)==(o)   SET TYPE=OBJ
        IF (%TYPE%)==(O)   SET TYPE=OBJ
        IF (%TYPE%)==(ob)  SET TYPE=OBJ
        IF (%TYPE%)==(Ob)  SET TYPE=OBJ
        IF (%TYPE%)==(oB)  SET TYPE=OBJ
        IF (%TYPE%)==(OB)  SET TYPE=OBJ
        IF (%TYPE%)==(obj)  SET TYPE=OBJ
        IF (%TYPE%)==(Obj)  SET TYPE=OBJ
        IF (%TYPE%)==(oBj)  SET TYPE=OBJ
        IF (%TYPE%)==(obJ)  SET TYPE=OBJ
        IF (%TYPE%)==(OBj)  SET TYPE=OBJ
        IF (%TYPE%)==(oBJ)  SET TYPE=OBJ
        IF (%TYPE%)==(OBJ)  goto :DOASM
      rem
        IF (%TYPE%)==(e)   SET TYPE=EXE
        IF (%TYPE%)==(E)   SET TYPE=EXE
        IF (%TYPE%)==(ex)  SET TYPE=EXE
        IF (%TYPE%)==(Ex)  SET TYPE=EXE
        IF (%TYPE%)==(eX)  SET TYPE=EXE
        IF (%TYPE%)==(EX)  SET TYPE=EXE
        IF (%TYPE%)==(exe) SET TYPE=EXE
        IF (%TYPE%)==(Exe) SET TYPE=EXE
        IF (%TYPE%)==(eXe) SET TYPE=EXE
        IF (%TYPE%)==(exE) SET TYPE=EXE
        IF (%TYPE%)==(EXe) SET TYPE=EXE
        IF (%TYPE%)==(eXE) SET TYPE=EXE
        IF (%TYPE%)==(EXE) goto :DOASM
      rem
        IF (%TYPE%)==(c)   SET TYPE=COM
        IF (%TYPE%)==(C)   SET TYPE=COM
        IF (%TYPE%)==(co)  SET TYPE=COM
        IF (%TYPE%)==(Co)  SET TYPE=COM
        IF (%TYPE%)==(cO)  SET TYPE=COM
        IF (%TYPE%)==(CO)  SET TYPE=COM
        IF (%TYPE%)==(com) SET TYPE=COM
        IF (%TYPE%)==(Com) SET TYPE=COM
        IF (%TYPE%)==(cOm) SET TYPE=COM
        IF (%TYPE%)==(coM) SET TYPE=COM
        IF (%TYPE%)==(COm) SET TYPE=COM
        IF (%TYPE%)==(cOM) SET TYPE=COM
        IF (%TYPE%)==(COM) goto :DOASM
      rem
        GOTO :ASKTYPE
      :DOASM
      IF (%MASM%)==() SET MASM=/S/P/V/L%MASM%
      IF not (%MASM%)==() ECHO MASM командная строка переключается в: %MASM%
      ECHO on
      MASM %F1%.asm;
      @ECHO off
      IF errorlevel 1 goto :NOASSEM
      REM
      IF (%TYPE%)==(OBJ) goto :LSTFILES
      IF (%LINK%)==() SET LINK=/I/CP:1%LINKS%
      IF not (%LINK%)==() ECHO Link командная строка переключается в: %LINK%

                                      - П-6 -
      ECHO on
      LINK %F1%.obj,%F1%.exe;
      @ECHO off
      IF errorlevel 1 goto : NOLINK
      IF exist %F1%.obj DEL %F1%.obj >nul:
      REM
        IF (%TYPE%)==(COM) EXE2BIN %F1%.exe %F1%.com >nul:
        IF (%TYPE%)==(COM) goto :DEL_EXE
        GOTO :LSTFILES
      :DEL_EXE
        IF exist %F1%.exe DEL %F1%.exe >nul:
      :LSTFILES
        IF exist %F1%.bak DEL %F1%.bak >nul:
        DIR %F1%.*
        GOTO :END
      :NOPARM
        ECHO Параметр не указан!
        GOTO :END
      :NOFILE
        ECHO Файл "%F1%.ASM" не существует!"
        GOTO :END
      :NOASSEM
        ECHO Ошибка ассемблера при трансляции!
        GOTO :END
      :NOLINK
        ECHO Ошибка при редактировании связей!
      :END
        SET F1=
        SET TYPE=
        SET MASM=
        SET LINK=
        SET MASMS=
        SET LINKS=
      ─────────────────────────────────────────────────────────────
              Отметим, что командный файл МК.BAT использует некоторые  не-
         печатаемые в коде ASCII символы: ESC (переход) в коде ASCII пока-
         зан, как ^[, а BS (возврат) в коде ASCII показан, как ^H.
              В процессе создания командного файла МК.BAT программа-редак-
         тор и программа  текстовой  обработки,  которые  вы  используете,
         должны  обеспечить  возможность  вставки  этих  символов в данный
         текст.
              Начало  листинга  показывает  использование  команды
         @  ECHO off операционной системы MS-DOS версии 3.3, результа-
         том которой  является выключение режима вывода на экран исполняе-
         мых команд,  при этом и сама строка ECHO off на экран  выводиться
         не будет.
              Однако если вы работаете с более ранней версией операционной
         системы MS-DOS,  то можно использовать управляющую последователь-
         ность стандарта ANSI, показанные в нескольких последующих строках
         листинга.
              Управляющая последовательность стандарта  ANSI  используется
         только  тогда,  когда  драйвер  устройства ANSI.SYS загружается в
         процессе первоначальной загрузки системы.
              Символ возврата  в коде ASСII используется с целью отображе-
         ния операционной системой MS-DOS пустой строки в процессе  выпол-
         нения  данного  файла:  результатом  оператора  "ECHO^H" является
         отображение пустой строки во всех версиях операционной системы MS

                                      - П-7 -
         -DOS.
              Командный файл МК.BAT использует программу общего  пользова-
         ния,  называемую ANSWER.COM. Эта программа используется для отоб-
         ражения приглашения операционной системы MS-DOS,  означающего го-
         товность  операционной  системой к приему команд;  в ответ на это
         приглашение любой вводимый текст назначается переменной окружения
         ANSWER.
              Ввод в ответ на запрос может быть затем проверен в командном
         файле путем использования в операторе %ANSWER%.


                  Использование средства MAKE фирмы "Майкрософт"
                  ──────────────────────────────────────────────

              Утилита сопровождения программы фирмы "Майкрософт", называе-
         мая MAKE,  может использоваться с целью  значительного  повышения
         уровня автоматизации разработки программ.
              Утилита MAKE используется для автоматического обновления го-
         тового к выполнению файла всякий раз,  когда вносятся изменения в
         один или более ее исходных объектных файлов; кроме того с помощью
         этой утилиты можно обновлять любой файл всякий раз, когда вносят-
         ся изменения в другие смежные файлы.
              Чтобы использовать  утилиту  MAKE,  необходимо создать "файл
         описаний", содержащий команды для утилиты MAKE по построению дан-
         ного проекта.
              К примеру,  если вы хотите создать с  помощью  утилиты  MAKE
         программу, называемую TEST1.EXE, файл описания утилиты MAKE может
         содержать операторы, показанные в листинге A-4.

               Листинг A-4. Пример файла описания утилиты MAKE
         ─────────────────────────────────────────────────────────────
             # Стандартная строка команды с текстом макроопределений
             f1=test1               # имя файла, подлежащего созданию
             msm=masm /S /P /V /L   # переключатели  (операторы выбора)
                                    # строки команд макроассемблера MASM
             lnk=link /CP:1 /I      # переключатели (операторы выбора)
                                   # строки команд редактора связей LINK
             #
             # Перечень файлов ASM
             $(f1).obj: $(f1).asm
                 $(msm) $(f1).asm;
             #
             $(f1).exe: $(f1).obj
                 $(lnk) $(f1).obj,$(f1).exe;
                 DEL $(f1).obj
         ─────────────────────────────────────────────────────────────

              Файл описания утилиты MAKE обычно имеет то же имя, что и го-
         товый к выполнению файл,  но без расширения.  Таким образом, если
         готовый к выполнению файл называется ТЕSТ1.EXE,  то файл описания
         утилиты MAKE,  используемый для создания программы ТЕSТ1.EXE, на-
         зывается просто ТЕSТ1.
              Чтобы создать или обновить программу ТЕSТ1.EXE,  просто вве-
         дите "MAKE ТЕSТ1".

              Файл описания утилиты MAKE, показанный в листинге A-4, имеет
         следующие характеристики:

                                      - П-8 -
              - Любой текст, который начинается с символа #, является ком-
                ментарием и игнорируется утилитой MAKE в процессе обработ-
                ки;
              - "Техt="  представляет  макротекст,  который  присваивается
                строке с текстом,  что позволяет отображать этот  текст  в
                символическом виде по всему файлу описания. Пример, приве-
                денный в листинге A-4, показывает, что макротексту присва-
                ивается значение f1 в качестве имени файла программ, кото-
                рый должен обрабатываться.  Далее значение f1 используется
                на  протяжении остального файла описания с целью представ-
                ления данного файла программ в виде $(f1).  Если вам необ-
                ходимо  изменить имя данного файла программ,  оно меняется
                только в одном месте, где значение f1 впервые присваивает-
                ся;
              - $(f1).OBJ - это имя первого  целевого  файла,  называемого
                "выходным файлом", а $(f1).ASM (который в данном примере в
                "test1.ASM") - это имя исходного файла, называемого "вход-
                ным  файлом".  Входной файл - это файл,  который требуется
                для создания выходного файла. Выходной файл всегда вводит-
                ся  первым,  за ним следует двоеточие,  за которым следует
                один или более входных файлов,  требуемых для создания вы-
                ходного  файла.  Если  выходной файл отсутствует или имеет
                отметку о времени и дате,  более раннюю чем,  связанный  с
                ним входной файл(ы),  то следующая строка в файле описания
                выполняется как команда  операционной  системы  MS-DOS  (в
                данном примере "$(msm)$(f1);",  которая будет оттранслиро-
                вана в "masm /s/p/v/l/test1;".

                     Если данный входной файл не существует,  то  средство
                MAKE  останавливает обработку в этой точке и выводит сооб-
                щение об ошибке;
             - $(f1).EXE - имя конечного выходного файла, а  $(f1).OBJ
                -  имя  требуемого  входного файла. И снова, если файл
                $(f1).EXE (который транслируется в "test1.EXE") не су-
                ществует или если он имеет отметку о времени и дате, более
                раннюю по сравнению с файлом $(f1).OBJ, то следующая стро-
                ка выполняется как  команда  операционной  системы  MS-DOS
                $(lnk)$(f1);,  которая транслируется в "link/CP:1/I test1;
                в данном примере).
                     Если файл  $(f1).OBJ не существует,  то средство MAKE
                останавливает обработку и выводит сообщение об ошибке;
              - Файл описания,  может содержать любую команду операционной
                системы MS-DOS.  В конце примера показано,  как по команде
                DEL$(f1).obj   файл  $(f1).obj  (который  транслируется  в
                /test1.obj) должен быть удален, но только если процесс ре-
                дактирования связей был успешным.

              Средство MAKE способно отреагировать на коды ошибок, возвра-
         щаемые командами операционной системы MS-DOS  в  файле  описания.
         Например, если макроассемблер MASM выдал код возврата отличный от
         "0" (в данном примере $(msm) $(f1).asm;), средство MAKE остановит
         обработку  файла описания в этой точке и выведет на экран сообще-
         ние об ошибке.
              Если макроассемблер успешно проводит трансляцию данного фай-
         ла, однако редактор связей LINK возвратил ошибку, то команда уда-
         ления объектного файла (DEL$(f1).obj) не будет обработана.
              Средство MAKE является  отличным  средством  для  разработки

                                      - П-9 -
         проектов  программ,  особенно больших программных проектов.  Файл
         описания средства MAKE может содержать правила для многочисленных
         исходных /файлов,  а также объектных файлов; кроме того, он может
         описать использование нескольких различных ассемблеров,  компиля-
         торов,  редакторов связей и других средств,  а также и нескольких
         примеров с одинаковыми средствами.

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


            Использование шаблонов для создания .COM- и .EXE - программ
            ───────────────────────────────────────────────────────────

              Листинги A-5,  A-6 и A-7 могут оказаться полезными в началь-
         ной стадии разработки вами программ.
              Листинг A-5 показывает формат для .EXE-программ с  промежут-
         ками для записи вашего текста программы.
              Листинг A-6 показывает формат для .COM- файлов.
              Листинг A-7 содержит некоторые макрокоманды, которые могут
         оказаться полезными при написании или .EXE-,  или .COM  -  прог-
         рамм.  Некоторые макрокоманды могут быть или встроены в исходный
         файл вашей программы,  или могут постоянно размещаться в отдель-
         ном  файле,  который "включается" в ваш исходный файл в процессе
         трансляции с языка ассемблера (путем встраивания управляющей ко-
         манды INCLUDE макроассемблера MASM в исходный файл).


                   Листинг A-5. Шаблон .EXE-программы
         ─────────────────────────────────────────────────────────────
            PAGE    60,132             ; широкая печать
          ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
            FALSE   EQU     0          ; сравнить с логическим значением
                                       ; FALSE ("ложь")
            TRUE    EQU     0FFFFH     ; сравнить и проверить по маске
                                       ; логическоe значениe TRUE
                                       ; ("истина")
            ;
            ;    <Установление равенств и макрокоманд>
            ;
            ;- - - - Инициализация - - - - - - - - - - - -
            _TEXT   SEGMENT WORD PUBLIC 'CODE' ;сегмент текста программы
            _TEXT   ENDS
            _DATA   SEGMENT WORD PUBLIC 'DATA' ; сегмент данных
            _DATA   ENDS
            _STACK  SEGMENT PARA STACK 'STACK'  ; сегмент стека
            _STACK  ENDS
            ;
            DGROUP  GROUP   _DATA, STACK
            ;
                    ASSUME cs:_TEXT,ds:DGROUP,ss:DGROUP,es:DGROUP
            ;
            _TEXT   SEGMENT     ; начало сегмента текста программы
            ; Локальная память данных (хранит  эти  описания  в

                                      - П-10 -
            ; сегменте текста программы)
            DSdsave            dw   seg DGROUP  ; память для DS-регистра
            ;
            _TEXT   ENDS
            _DATA   SEGMENT
            PSPseg           dw   ?              ; сегмент PSP
            _DATA   ENDS

         _TEXT   SEGMENT
         ;
         main    PROC     NEAR          ; начинайте процесс "main"
                 mov      ds,DSsave  ; инициализируйте память данных DS
                 mov      ax,es               ; получите адрес сегмента
                 mov      word ptr PSPseg,ax  ; PSP и сохраните его
         ;
         ;
         ;       < Основная стандартная программа >
         ;
         ;
                 mov      ax,4C00h           ; завершите  программу
                 int      21h
         ;
         main    ENDP
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;
         ;   <Оставшаяся часть ваших стандартных программ>
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         _TEXT   ENDS
         _DATA   SEGMENT
         ;
         ;       < Bставьте данные >
         ;
         _DATA   ENDS
         _TEXT   SEGMENT
         ;------------------------------------------------------
         _TEXT   ENDS
                 END      main
         ─────────────────────────────────────────────────────────────



                   Листинг A-6. Шаблон .COM-программы
         ─────────────────────────────────────────────────────────────
         PAGE    60,132             ; широкая  печать
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         FALSE   EQU     0          ; сравнить с логическим значением
                                    ; FALSE ("ложь")
         TRUE    EQU     0FFFFH     ; сравнить и проверить по маске
                                    ; логическоe значениe TRUE
                                    ; ("истина")
         ;
         ;    <Установление равенств и макрокоманд>
         ;
         ;- - - - Инициализация - - - - - - - - - - - -
         code   SEGMENT

                                      - П-11 -

         ASSUME  cs:code, ds:code, ss:code, es:code
         ;
         main   PROC  NEAR
         ;
         entry: ORG   0100h
         ;
                mov   sp,offset top_of_stack   ; установите новый стек
         ;
         ;
         ;       < Основная стандартная программа >
         ;
         ;      mov      ax,4C00h               ; завершите программу
                int      21h
         ;
         main   ENDP
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;
         ;   <Оставшаяся часть ваших стандартных программ>
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;
         ;       < Bставьте данные >
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;Дополнительный  стек  -  BHИМAHИЕ - вы ДОЛЖНЫ(!)
         ;использовать функцию 4Сh для завершения данной
         ;программы, если вы используете локальный стек !
         ;
                db       32 DUP ('stack  ')     ; 256-байтный стек
         top_of_stack    EQU    $
         ;
         ;- - - - - - - - - - - - - - - - - - - - - -  - - - - -
         code   ENDS               ; конец сегмента текста программы
                END      entry



              Листинг A-7. Полезные  макрокоманды (STDMAC.INC):
         ─────────────────────────────────────────────────────────────
         ; - - - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;  Файл включения макроопределений
         ;- -  - - - - - - - - - - - - - - - - - - - - - - - - - - -
         ; Стандартные равенства:
         ;
         TRUE   EQU      0FFFFh  ;  "истина"

            FALSE   EQU     0    ;  "ложь"
            ;
            ; Cтандартные непечатаемые символы
            NUL     EQU    00000000b ; нуль
            BEL     EQU    00000111b ; "звонок"
            BS      EQU    00001000b ; возврат на символ с его стиранием
            NT      EQU    00001001b ; горизонтальная табуляция
            LF      EQU    00001010b ; перевод строки

                                      - П-12 -
            FF      EQU    00001100b ; перевод страницы
            CR      EQU    00001101b ; возврат каретки
            SUBST   EQU    00011010b ; подстановка
            ESCAPE  EQU    00011011b ; переход
            SPACE   EQU    00100000b ; пробел
            COLON   EQU    00111010b ; двоеточие
            SCOLON  EQU    00111010b ; точка с запятой
            ;
            ; Pасширенные символы (фирмы "ИБМ"):
            SLINE   EQU     11000100b  ; горизонтальная строка
            ;
            ;- - - - - - - - - - - - - - - - - - - - - - -
            ..XLIST            ; запретить распечатку макроопределений
            ;;.LALL  _          .  ; распечатка всего
            ;;
            ;;
            ;;** @MODEL ********* Макроопределения общего назначения **
            ;; Установка сегментов согласно модели памяти.
            ;; Это  макроопределение эмулирует управляющую команду
            ;; 5.Х.МОDEL макроассемблера MASM для использования с
            ;; более ранними версиями MASM.

            IF1    ;; Ассемблирование только в процессе прохода 1
            @Model MACRO memory_model,code_name,stack_size
                    ;; ПРИМЕЧAHИЕ: "имя-программы" используется только
                    ;; со средними, большими, а также с очень большими
                    ;; моделями памяти
                    IFNB<memory_model>   ;; модель памяти была указана?
                    ;;
                       IF memory_model  EQ 0
                       @TinyModel stack_size
                   ELSE
                       IF memory_model EQ 1
                       @SmallModel stack_size
                    ELSE
                         IF memory_model EQ 2
                         @MediumModel code_name,stack_size
                       ELSE
                         IF memory_model EQ 3
                         @CompactModel stack_size
                       ELSE
                         IF memory-model EQ 4
                         @ LargeModel code_name,stack_size
                       ELSE
                         IF memory_model EQ 5
                         @Large_model code_name,stack_size
                       ELSE
                         .ERR
                         %0UT @Model macro: неизвестная модель памяти
                       ENDIF;; конец проверки очень большой модели
                     ENDIF;; конец проверки большой модели
                   ENDIF;; конец проверки компактной модели
                 ENDIF;; конец проверки средней модели
               ENDIF;; конец проверки малой модели
             ENDIF;; конец проверки  очень малой модели
            ;;
            ELSE   ;; модель памяти не была указана

                                      - П-13 -
               .ERR       ;; завершить сообщением об ошибке
               %0UT @MODEL MACRO ERR0R: модель памяти не указана
            ENDIF  ;; конец проверки параметров модели - памяти
            ;;
            ENDM   ;; конец макроопределения
            ;;
            ENDIF  ;; конец обработки  прохода
            ;;
            ;;** @Tiny ************ Макрокоманды общего назначения **
            ;; (Эта управляющая макрокоманда вызывается через @Model 0.
            ;; Эта управляющая макрокоманда также может  вызываться
            ;; непосредственно).
            ;; Отметим, что эта макрокоманда, в отличие от других мак-
            ;; рокоманд  памяти-модели,  не  использует   макрокоманду
            ;; @Stack, поскольку другие стеки в .COM - программах дол-
            ;; жны  быть описаны в конце данной программы. Для опреде-
            ;; ления других стеков в .COM-программах выполните  макро-
            ;; команду @Stack в соответствующем месте исходного текста
            ;; программы.
            IF1   ;; Ассемблировать только в процессе прохода 1
            @TinyModel MACRO
                MEMODEL = 0
               _TEXT SEGMENT BYTE PUBLIC  'CODE' ; сегмент программы
               _TEXT ENDS
               ;; Назначить  физические  сегменты
               ASSUME cs:_TEXT,ds:_TEXT,ss:_TEXT, es:_TEXT
               ;;- - - - - - - - - - - - - - - - - - - - - - -
               ;; Вставьте вручную следующий текст программы после
               ;; @Model 0:
               ;;
               ;; _TEXT SEGMENT
               ;; main PROС near ;;  entry:  ORG 0100h ;;  jmp Start ;;  ;
               вставьте данные  здесь,  если  требуется  ;;  start:  ;;  ;
               вставьте текст программы здесь ;;  main ENDP ;;  ; вставьте
               стандартные программы здесь ;;  ;  вставьте  дополнительный
               стек здесь ;; ; вставьте данные в конце, если требуется ;;_
               TEXT ENDS ;;  ;;- - - - - - - - - - - - - - - - - - - - - -
               - - ;; ENDM ;; конец макроопределения
         ENDIF  ;; конец обработки прохода
         ;;
         ;;** @Small ************ Mакрокоманды общего назначения **
         ;; Управляющая  макрокоманда  для установки Малой (SMALL)
         ;; модели памяти.
         ;; (Эта макрокоманда вызывается  через "@Model Small".
         ;; Эта  макрокоманда может быть вызвана также
         ;; непосредственно.)
         IF1   ;; Ассемблирование только в процессе прохода 1
         @SmallModel MACRO stack_size
               Memodel = 1
               _TEXT SEGMENT BYTE PUBLICK 'CODE'  ; сегмент программы
               _TEXT ENDS
               _DATA SEGMENT WORD PUBLIC 'DATA'   ; сегмент данных
                                                  ; (DGROUP)
               _DATA ENDS
               _CONST SEGMENT WORD PUBLIC 'CONST' ; сегмент констант
               _CONST ENDS                        ; (DGROUP)
               _BSS SEGMENT WORD PUBLIC 'BSS'     ; сегмент непроинициа-

                                      - П-14 -
               _BSS ENDS                          ; лизированных данных
                                                  ; (DGROUP)
               STACK SEGMENT PARA STACK 'STACK'   ; сегмент стека
                                                  ; (DGROUP)
               STACK ENDS
               ;;
               IFNB <stack_size>
                       @Stack stack_size
                ENDM   ;; конец макроопределения
              ENDIF  ;; конец обработки прохода
               ;;
               DGROUP GROUP _DATA,CONST,_BSS,STACK ; группирование
                                                   ; сегментов данных
               ;;
               ;; Назначить физические сегменты:
               ASSUME   cs:_TEXT.ds:DGROUP,ss:dgroup,es :DGROUP
               ;;
               ENDM  ;;  конец макроопределения
         ENDIF   ;; конец обработки прохода
         ;;
         ;;** @  ************* Макрокоманды общего назначения **
         ;; Управляющая макрокоманда для установки средней модели
         ;; памяти. (Эта макрокоманда  вызывается  через  "@Model
         ;; medium".  Эта  макрокоманда  может быть вызвана также
         ;; непосредственно.)
         IF1  ;; Ассемблировать только в процессе прохода 1
         @MediumModel MACRO code_name,stack_size
                MEMODEL = 2
                code_name_TEXT SEGMENT BYTE PUBLIC 'CODE' ;поименованный
                                                     ; сегмент программы
                code_name_TEXT ENDS                       ;
                _DATA SEGMENT WORD PUBLIC 'DATA'     ; сегмент данных
                _DATA ENDS                           ; (DGROUP)
                CONST SEGMENT WORD PUBLIC 'CONST'    ; сегмент констант
                CONST ENDS                           ; (DGROUP)
                _BSS SEGMENT WORD PUBLIC 'BSS'       ; сегмент непроинициа-
                 _BSS ENDS                           ; лизированных данных
                                                     ; (DGROUP)
                STACK SEGMENT PARA STACK 'STACK'     ; сегмент стека
                STACK ENDS                           ; (DGROUP)
                ;;
                IFNB <stack_size>
                        @Stack stack_size
                ENDIF
                ;;
                DGROUP GROUP _DATA,CONST,_BSS,STACK  ; группирование
                                                     ; сегмента данных
                ;;
                ;; Hазначить физические сегменты
                ASSUME  cs:_TEXT,ds:DGROUP,ss:DGROUP,es:DGROUP
                ;;
                ENDM   ;; конец макроопределения
              ENDIF  ;; конец обработки прохода
                ;;
                ;;** @COMPACT ****** Mакрокоманды общего назначения **
                ;; Управляющая макрокоманда для установки компактной
                ;; (COMPACT) модели памяти. (Эта макрокоманда вызывается

                                      - П-15 -
                ;; через "@Model compact". Эта макрокоманда может быть
                ;; вызвана также непосредственно.)
                IF1   ;; Ассемблировать только в процессе прохода 1
                @CompactModel MACRO stack_size
                MEMODEL = 3
              _TEXT SEGMENT BYTE PUBLIC 'CODE' ;сегмент текста программы
              _TEXT ENDS
              FAR_DATA SEGMENT PARA 'FAR_BSS'  ; личный далекий сегмент
              FAR_DATA ENDS                    ; данных (DGROUP)
              FAR_BSS SEGMENT PARA 'FAR_BSS'   ; личный далекий непро-
              FAR_BSS ENDS                     ; инициализированный сег-
                                               ; мент данных (DGROUP)
             _DATA SEGMENT WORD PUBLICK 'DATA'  ; сегмент данных
             _DATA ENDS                         ; (DGROUP)
             CONST SEGMENT WORD PUBLIBC 'CONST' ; сегмент констант
             CONST ENDS                         ; (DGROUP)
            _BSS SEGMENT WORD PUBLIC 'BSS'      ; сегмент непроинициа-
            _BSS ENDS                           ; лизированных данных
                                                ; (DGROUP)
              STACK SEGMENT PARA STACK 'STACK'     ; сегмент стека
              STACK ENDS                           ; (DGROUP)
              ;;
              IFNB <stack_size>
                      @Stack stack_size
              ENDIF
              ;;
              DGROUP GROUP _DATA,CONST,_BSS,STACK  ; группирование
                                                   ; сегментов данных
              ;;
              ;; Назначить физические сегменты:
              ASSUME cs:_TEXT,ds:DGROUP, ss:DGROUP,es:DGROUP
              ;;
              ENDM  ;; конец макроопределения
         ENDIF  ;;  конец обработки прохода
         ;;
         ;;** @Large ***************** Mакрокоманды общего назначения **
         ;; Управляющая макрокоманда для установки большой (LARGE)
         ;; модели памяти. (Эта макрокоманда вызывается
         ;; через "@Model Large". Эта макрокоманда может быть
         ;; вызвана также непосредственно.)
         IF1  ;; Ассемблировать только в процессе прохода 1
         @LargeModel MACRO code_name,stack_size
             MEMODEL = 4
             code_name_TEXT SEGMENT BYTE PUBLIC 'CODE'  ; поименованный
             code_name_TEXT ENDS                    ; сегмент программы
             FAR_DATA SEGMENT PARA 'FAR_DATA'    ; личный далекий сегмент
             FAR_DATA ENDS                       ; данных (DGROUP)
             FAR-BSS SEGMENT PARA 'FAR_BSS'      ; личный далекий непро-
             FAR_BSS ENDS                        ; инициализированный сег-
                                                 ; мент данных (DGROUP)
             _DATA SEGMENT WORD PUBLIC 'DATA'    ; сегмент данных
             _DATA ENDS                          ; (DGROUP)
             CONST SEGMENT WORD PUBLIC 'CONST'   ; сегмент констант
             CONST ENDS                          ; (DGROUP)
             _BSS SEGMENT WORD PUBLIC 'BSS'      ; сегмент непроинициа-
             _BSS ENDS                           ; лизированных данных
                                                 ; (DGROUP)

                                      - П-16 -
             STACK SEGMENT PARA STACK 'STACK'    ; сегмент стека
             STACK ENDS                          ; (DGROUP)
             ;;
             IFNB <stak_size>


         @Stack stack_size
              ENDIF
              ;;
              DGROUP GROUP _DATA,CONST,_BSS,STACK  ; группирование
                                                   ; сегмента данных
              ;;
              ;; Назначить физические сегменты
              ASSUME cs:_TEXT,ds:DGROUP, ss:DGROUP,es:DGROUP
              ;;
                ENDM   ;; конец макроопределения
            ENDIF  ;; конец обработки прохода
         ;;
         ;;** @HUGE ************* Mакрокоманды общего назначения **
         ;;  Управляющая макрокоманда для установки очень большой
         ;;  (HUGE) модели памяти. (Эта макрокоманда вызывается
         ;;  через "@Model huge". Эта макрокоманда может быть
         ;;  вызвана также непосредственно.)
         ;;  Oчень  большая (HUGE) модель памяти в настоящее время
         ;;  устанавливается так же как и Большая (LARGE) модель
         ;;  памяти.
         IF1 ;; Ассемблировать только в процессе прохода 1
         @HugeModel MACRO code_name,stack_size
                 MEMODAL = 5
                 @LargeModel code_name,stack_size
                ENDM  ;; конец макроопределения
         ENDIF  ;;  конец обработки прохода
         ;;
         ;;** @Stack ************* Mакрокоманды общего назначения **
         ;; Управляющая  макрокоманда для установки размера стека
         IF1   ;; Ассемблировать только в процессе прохода 1
         @Stack MACRO stack_size,prog_type
           ;;
           IFB <PROG_TYPE>  ;;  если параметр типа программы пустой
             IF MEMODEL EQ 0
               PROGTYPE = 0
             ELSE
               IF MEMODEL EQ 1
                  PROGTYPE = 1
             ELSE
               IF MEMODEL EQ 2
                  PROGTYPE = 1
             ELSE
               IF MEMODEL EQ 4
                  PROGTYPE = 1
               ELSE
                   IF MEMODAL EQ 5
                      PROGTYPE = 1
                   ELSE
                       .ERR
                       %OUT @Stack macro: модель памяти
                       %OUT или тип программы не были установлены

                                      - П-17 -
                   ENDIF;; конец проверки очень большой модели
                 ENDIF ;; конец проверки большой модели
               ENDIF ;; конец проверки компактной модели
             ENDIF ;; конец проверки средней модели
           ENDIF ;; конец проверки малой модели
         ENDIF ;; конец проверки очень маленькой модели
         ELSE ;;  параметр типа программы был указан
           IF prog_type EQ 0  ;; установка программы типа .COM
              PROGTYPE = 0
           ELSE
             IF prog_type EQ 1
              PROGTYPE = 1
             ELSE
               .ERR     ;;  выход с сообщением об ошибке
               %OUT @Stack MACRO: указан некорректный тип программы
              ENDIF ;; конец проверки типа .EXE
            ENDIF ;; конец проверки типа  .COM
         ENDIF ;;  конец проверки параметра "тип-программы"
         ;;
         IFNB <stack_size>
         ;;
            IF PROGTYPE EQ 0
                  ;  Дополнительный стек. BHИМAHИЕ - вы должны ис-
                  ;  пользовать функцию 4h для  завершения  данной
                  ;  программы, если вы используете локальный стек.
                         db    stack_size DUP ('стек   ')
                  top_of_stack EQU     $
            ELSE ;;  тип программы - .EXE
                  STACK SEGMENT
                          db   stack_size DUP ('стек   ')
                  STACK ENDS
            ENDIF ;; конец проверки PROGTYPE
         ;;
         ELSE  ;; параметр "размер-стека" не был указан
         ;;
           IF PROGTYPE EQ 0
                  ; Дополнительный стек. ВНИМАНИЕ - вы должны исполь-
                  ; зовать функцию 4h для завершения данной программы
                  ; в  случае использования локального стека !
                          db       32 DUP ('стек   ')
              top_of_stack       EQU    $
           ELSE ;; тип программы - .EXE
              STACK SEGMENT      db     32 DUP ('стек   ')
                       STACK ENDS
                 ENDIF ;; конец проверки PROGTYPE
              ;;
              ENDIF  ;; конец проверки "размера стека"
              ;;
              ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @SwapNewStack ******** Mакрокоманды общего назначения **
         ;; Переключить стек на новый стек
         IF1   ;; Ассемблировать только в процессе прохода 1
         @SwapNewStack MACRO  tos
              LOCAL        bypass
              ;;

                                      - П-18 -
              jmp          bypass       ;; пропустить область данных
         old_stk_seg       dw      ?         ;; пространство для
                           ;; сегмента стека вызывающей макрокоманды
         old_stk_ptr       dw      ?         ;; пространство для
                          ; указателя стека вызывающей макрокоманды
         new_stk_seg       dw      ?         ;; пространство  для
                                        ;; нового сегмента   стека
         new_stk_ptr       dw  offset tos    ;; пространство  для
                                        ;; нового указателя  стека
                 ;;
         bypass:
                 mov       cs:new_stk_seg,cs ;; установить сегмент
                                             ;; нового стека
                 mov       cs:old_stk_seg,ss ;; сохранить старые
                                             ;; значения стека
                 mov       cs:old_stk_ptr,sp ;; сохранить старый
                                             ;; указатель стека
                 mov       ss,cs:new_stk_seg ;; получить новые
                                             ;; значения стека
                 mov       sp,cs:new_stk_ptr ;; получить новый
                                             ;; указатель стека
                 @PushAll                    ;; сохранить признаки и
                                        ;; содержимое всех регистров
              ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;**@SwapOldStack********** Mакрокоманды общего назначения **
         ;; Переключить с нового стека на исходный стек
                 @Popall               ;; восстановить признаки и
                                       ;; содержимое всех регистров
                 mov       ss,cs:old_stk_seg  ;; восстановить старые
                                              ;; значения стека
                 mov       sp,cs:old_stk_ptr
              ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @DosCall ************* Mакрокоманды общего назначения **
         ;; Bызвать функцию MS-DOS
            IF1     ;;  Ассемблировать только в процессе прохода 1
            @DosCall MACRO
            int      21h
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;**@DirConChar 10 ***** Mакрокоманды общего назначения **
            @DirConChar10 MACRO       ; проверить состояние клавиатуры
                                      ; и считать
                    push     dx              ; cохранить DX
                    mov      dl,0FFh         ; нет символа для вывода
                    mov      ah,06h          ;
              @DosCall
              pop      dx                ; восстановить DX
              ENDM
            ;;
            ;;** @ReadCon_NoEcho **** Mакрокоманды общего назначения **
            @ReadCon_NoEcho MACRO
                    mov     ah,08h     ; считать с клавиатуры без эхо

                                      - П-19 -
                    @DosCall
                    ENDM
            ;;
            ;;** @ReadBuffInput ***** Mакрокоманды общего назначения **
            @ReadBuffInput MACRO Buffname  ; считать буферизованный
                                           ; ввод с клавиатуры
                    mov    dx,offset bufname
                    mov    ah,0Ah
                    @DosCall
                    ENDM
            ;;
            ;;**DisChr ************** Mакрокоманды общего назначения **
            ;; Отобразить на экране символ
            IF1    ;; Ассемблировать только в процессе прохода 1
                    @DisChr MACRO   char
                    IFNB<char>      ;; аргумент символа был указан ?
                                    ;; да, поэтому вставить команду
                    push    ax      ;; сохранить используемые регистры
                    push    dx
                    mov     dl,char ;; загрузить символ
                    mov     ah,02h  ;; загрузить  номер функции
                    @DosCall        ;; вызвать MS-DOS
                    pop     dx      ;; восстановить содержимое регистров
                    pop     ax
                    ELSE            ;; в противном случае
                    .ERR            ;; сгенерировать  и вывести
                                    ;; сообщение об ошибке
                    %OUT @DisChr macro : аргумент "символ" ("char")
                                                     не указывается
                      ENDF
                    ;;
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода

            ;;
            ;;** @DisStr ************** Mакрокоманды общего назначения **
            ;; Oтобразить на экране строку памяти с  терминатором  кон-
            ;; ца-строки по умолчанию "$" или с указанным терминатором.
            ;; (Bызовы внутренних  макрокоманд @DisStr1 или @DisStr2.)
            IF1  ;; Ассемблировать только в процессе прохода 1
            @DisStr  MACRO  строка,терминатор
                  IFNB<string>    ;; параметр строки был указан?
                                  ;; да, поэтому
                   IFB<terminator>;; терминатор был указан?
                        ;; нет, поэтому вставить команду по
                        ;; умолчанию для  терминатора  "$"
                        @DisStr1 строка
                  ELSE  ;;  в противном случае терминатор был указан
                        @DisStr2 строка,терминатор
                  ENDIF ;; конeц проверки "терминатора"
                  ELSE  ;; в противном случае,"строка" не была указана
                  .ERR  ;; сгенерировать и вывести сообщение об ошибке
                  %OUT @DisStr macro: аргумент  "строки" ("string") не
                                                           указывается
               ENDIF
               ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода

                                      - П-20 -
            ;;
            ;;** @DisStr1 ********** Служебные макрокоманды *******
            ;; Вызваны макрокомандой @DisStr1 для отображения строки
            ;; памяти с терминатором конца-строки "$" по умолчанию.
            IF1    ;; Ассемблировать только в процессе прохода 1
            @DisStr1 MACRO  string
                     push   ax    ;; сохранить используемые регистры
                     push   dx
                     mov    dx,offset ds:string ;; указать на  строку
                                                ;; в памяти
                     mov    ax,09h          ;; загрузить номер функции
                     @DosCall               ;; обратиться к  MS-DOS
                     pop    dx              ;; сохранить регистры
                     pop    ax
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;** @DisStr2 ************ Служебные макрокоманды *******
            ;; Вызваны макрокомандой @DisStr1 для отображения строки
            ;; памяти с указанным терминатором конца-строки.
            IF1      ;; Ассемблировать только в процессе прохода 1
            @DisStr2 MACRO string,terminator
                     LOCAL strloop,strloopdone ;; создать локальные метки
                     push  si                  ;; сохранить регистры
                     push  ax
                     push  bx
                     push  dx
                     xor   bh,bh               ;; очистить BX
                     mov   bl,terminator       ;; получить терминатор
                     mov   si,offset string    ;; указать  на строку
                     xor   dx,dx
            strloop:
                     mov   dl,byte ptr [si] ;; получить следующий символ
                     cmp   dl,bl               ;; это терминатор?
                     je    strloopdone         ;; да, мы сделали
                     mov   ax,02h              ;; загрузить функцию
                                               ;; вывода символов
                     @DosCall                  ;; и вызвать DOS
                     jnc   si           ;; указать на следующий символ
                     jmp   short strloop       ;; и повторить
            strloopdone:
                     pop   dx      ;; восстановить содержимое регистров
                     pop   bx
                     pop   ax
                     pop   si
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;** @TypeStr ********** Mакрокоманды общего назначения **
            ;; Отобразить ближайшую строку.
            ;; Примечание: "строка" должна быть представлена в кавычках
            ;; с тем, чтобы она обрабатывалась как один аргумент макро-
            ;; команды  и  чтобы гарантировать, что данные закодированы
            ;; корректно.
            IF1      ;; Ассемблировать только в процессе прохода 1
            @TypeStr MACRO   string         ;; определить и отобразить
                                            ;; строку
                     LOCAL   TypeStrAddr    ;; установить локальную метку

                                      - П-21 -
                     ;;
                     IF MEMODEL NE 0        ;; если не тип .COM
            _TEXT    ENDS                   ;; конец сегмента программы
            _DATA    SEGMENT              ;; изменить на сегмент данных
                     ENDIF
            TypeStrAddr  DB string,'$' ;; определить строку в сегменте
                                       ;; данных
                     IF MEMODEL NE 0   ;; если не тип .COM
            _DATA    ENDS              ;; конец сегмента данных
            _TEXT    SEGMENT        ;; вернуться к сегменту программы
                     ENDIF
                     ;;
                     @DisStr TypeStrAddr   ;; отобразить строку
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;** @TypeStrCR ******** Mакрокоманды общего назначения **
            ;; Oтобразить ближайшую строку , завершаемую с
            ;; помощью GR/LF.
            IF1      ;; Ассемблировать только в процессе прохода 1
            ;; "строка" должна быть представлена в кавычках с тем, чтобы
            ;; она обрабатывалась как один аргумент макрокоманды.
            @TypeStrCR MACRO    string
                     @TypeStr   string ;; определить и отобразить строку
                     @NewLine          ;; завершить с помощью GR/LF
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;**@NewLine *********** Mакрокоманды общего назначения **
            ;; Oтобразить символ возврата каретки и перевода строки.
            IF1      ;; Ассемблировать только в процессе прохода 1
            @NewLine MACRO
                     INDIF      EXT_NEWLINE     ;; символ EXT_NEWLINE
                                                ;; был определен?
                     EXTRN      newLine:NEAR    ;; нет, вставьте EXTRN
                                                ;; только один раз
                     EXT_NEWLINE EQU 0          ;; и опишите равенство
                                                ;; только один раз
                     ENDIF        ;; верхние две строки не должны
                         ;; в последующие вызовы макрокоманд вставляться
                     call newLine ;; вызвать процедуру NEWLINE
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;**@DisNum ************ Mакрокоманды общего назначения **
            ;; Отобразить двоичное число в десятичном или шестнадцати-
            ;; ричном виде кода ASCII.
            IF1      ;; Ассемблировать только в процессе прохода 1
            @DisNum MACRO number,type,digits,sign
                     ;;
                     ;; Проверьте сначала требуемые параметры
                     IFB <number>  ;; числовой параметр указан?
                     .ERR          ;; нет, завершить обработку
                                   ;; сообщением об ошибке
                     %OUT @DisNum macro: параметр "number" не указан.
                     ENDIF
                     ;;

                                      - П-22 -
                     IFNB <type>   ;; тип вывода указан?
                     ;;
                   If type EQ 10         ;; десятичное  преобразование
                                         ;; указано?
                     INDIF EXT_BIN2DEC   ;; было определеноEXT_BIN2DEC?
                     EXTRN bin2dec:NEAR  ;; нет, вставьте определение
                                         ;; EXTRN
                  EXT_BIN2DEC EQU 0    ;; и только раз установите
                                       ;; равенство
                  ENDIF
                  ;;
                  ELSE
                  ;;
                IF type EQ 16                ;; шестнадцатиричное
                                        ;; преобразование  указано?
                  IFNDEF EXT_BIN2HEX    ;; было определено EXT_BIN2HEX?
                  EXTRN   bin2hex:NEAR  ;; нет, вставьте определение
                  EXT_BIN2HEX EQU 0     ;; EXTRN и только раз установите
                                        ;; равенство
                  ENDIF
                ;;
                ELSE
                ;;
                 .ERR
                 %OUT @DisNum Macro: указан запрещенный  "тип" ("type")
                 ENDIF        ;; окончить  проверку  для шестнадца-
                              ;; тиричного   преобразования
             ;;
             ENDIF ;; окончить  проверку  для десятичного преобразования
         ;;
         ELSE   ;; в противном  случае,  параметр пустой
         ;;
         .ЕRR   ;; завершить выполнение сообщением об ошибке
         %OUT @DisNum macro: параметр "type" не указан
         ENDIF  ;;  окончить  проверку  пустого параметра
         ;; Oкoнчить проверку требуемых параметров
         ;;
         ;; Hачать вставку программы
         push     ax            ;; сохранить содержимое регистров
         push     cx
         push     dx
         ;;
         mov                    ;; поместить число в AX
         ;;
         IFNB <digits>          ;; аргумент "разряды"  указан?
         mov      ch,digits     ;; да, записать значение в CH
         ELSE                   ;; в противном случае,  по  умолчанию
         mov      ch,1          ;; отобразить по крайней мере 1 разряд
         ENDIF
         ;;
         IFNB <sign>            ;; аргумент "знак"  указан?
         mov      dx,sign       ;; да, поэтому поместить его в DX
         ELSE                   ;; в противном случае, по умолчанию знак
         mov      dx,0          ;; будет  отсутствовать
         ENDIF
         ;;
         If type  EQ 10         ;; десятичное преобразование указано?

                                      - П-23 -
         call     bin2dec
         ELSE
                     IF type EQ 16  ;; шестнадцатиричное преобразование
                                    ;; указано?
                             call bin2hex
                             ENDIF  ;; конец проверки по основанию 16
                     ENDIF   ;; конец проверки по основанию 10
                     ;;
                     pop     dx   ;; восстановить содержимое регистров
                     pop     cx
                     pop     ax
                     ;;
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;
            ;;** @GetDate ********** Mакрокоманды общего назначения **
            ;; Получить  системную дату
            IF1      ;; Ассемблировать только в процессе прохода 1
            @GetDate MACRO
                     mov      ah,2Ah ;; загрузить номер функции
                     @DosCall        ;; вызвать  MS-DOS
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
           ;;** @GetTime ********** Mакрокоманды общего назначения **
            ;; Получить  системное время
            IF1      ;; Ассемблировать только в процессе прохода 1
            @GetTime MACRO
                     mov      ah,2ch ;; загрузить номер функции
                     @DosCall        ;; вызвать  MS-DOS
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;** @DiskRead ******** Mакрокоманды общего назначения **
            ;; Считать логический  сектор(а)
            IF1      ;; Ассемблировать только в процессе прохода 1
            @DiskRead MACRO
                     int     25h  ;; обработать абсолютное прерывание
                                  ;; по чтению диска
                  ENDM   ;; конец макроопределения
            ENDIF  ;; конец выполнения прохода
            ;;
            ;;** @DiskWrite ******* Mакрокоманды общего назначения **
            ;; Записать в логический сектор(а)
            IF1      ;;  Ассемблировать только в процессе прохода 1
         @DisckWrite MACRO
                  int      26h     ;; обработать машинное прерывание
                                   ;; по записи на диск
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @GetDOSVersion **** Mакрокоманды общего назначения **
         ;; Получить номер версии операционной  системы MS-DOS
         IF1      ;; Ассемблировать только в процессе прохода 1
         @GetDOSVersion MACRO
                  push     bx      ;; сохранить содержимое

                                      - П-24 -
                                   ;; уничтоженных  регистров
                  push     cx
                  mov      ah,30h  ;; загрузить номер функции
                  @DosCall         ;; вызвать MS-DOS
                  pop      cx      ;; восстановить содержимое регистров
                  pop      bx
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @GetDOSVer ******* Mакрокоманды общего назначения **
         ;; Получить номер версии операционной  системы MS-DOS
         IF1      ;; Ассемблировать только в процессе прохода 1
         @GetDOSVer MACRO
                  IFNDEF   EXT_GDOSV     ;; символ определен?
                  EXTRN    GETDOSV:NEAR  ;; нет, вставить команду EXTRN
                                         ;; только  один  раз
                  EXT_GDOSV EQU 0        ;; и только раз определить
                                         ;; равенство
                  ENDIF                  ;; (две верхние строки не
                                         ;; должны вставляться в
                                         ;; последующие вызовы
                                         ;; макроопределения)
                  call     dosver        ;; вызвать библиотечную
                                         ;; стандартную программу
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @DisDOSVer ********* Mакрокоманды общего назначения **
         ;; Получить и отобразить номер версии DOS
         IF1      ;; Ассемблировать только в процессе прохода 1
         @DisDOSVer MACRO
                  IFNDEF   EXT_DDOSV     ;; символ определен?
                  EXTRN    DOSV2CON:NEAR ;; нет, вставить команду EXTRN
                                         ;; только  один  раз
                  EXT_DOSV EQU 0         ;; и только раз определить
                                         ;; равенство
                  ENDIF                  ;; (две верхние строки не
                                         ;; должны вставляться в
                                         ;; последующие вызовы
                                         ;; макроопределения)
                  call     dosv2con      ;; вызвать библиотечную
                                         ;; стандартную программу
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @ChangeСase ******* Mакрокоманды общего назначения **
         ;; Изменить регистр  клавиатуры для  символа
         IF1      ;; Bыполнять только в  процессе прохода 1
         @ChangeCase MACRO  char,type
              IFB <char>   ;; символ, подлежащий преобразованию,
                           ;; указан ?
              .ERR                ;; нет, сгенерировать и
                                  ;; вывести сообщение  об  ошибке
              %OUT @ChangeCase macro: параметр "char"не определен !
              ELSE                   ;; в противном случае
              mov      al,char       ;; загрузите символ в AL
              ENDIF

                                      - П-25 -
              ;;
              IFB <type>          ;; тип преобразования указан?
              mov   ah,0          ;; нет, поэтому загрузить 0 в AH
              ELSE
              mov   ah,type   ;; загрузить тип преобразования в AH
              ENDIF
              ;;
              IFNDEF EXT_CHGCASE  ;; символ EXT_CHGCASE определен?
              EXTRN  CHGCASE:NEAR ;; нет, вставить EXTRN только раз
              EXT_CHGCASE EQU 0   ;; и только раз определить равенство
              ENDIF    ;; (две верхние строки не должны вставляться в
                       ;; последующие вызовы данной макрокоманды)
              ;;
              call     chgcase    ;; вызвать библиотечную процедуру
                                  ;; изменения регистра клавиатуры
           ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @case ************* Mакрокоманды общего назначения **
         ;; Mакрокоманда CASE языка ассемблера
         @Case    MACRO    key,case_list,jmp_lables
                  ??tmp_1 = 0
                  IRP      match,<&case_list>  ;; упорядочить регистры
                    ??tmp_1 = ??tmp_1 + 1  ;; установить номер индекса
                    cmp    key,&&match       ;; регистр соответствует?
                    ??tmp_2 = 0
                    IRP    retl,<&jmp_lables>  ;; упорядочить переходы
                      ??tmp_2 = ??tmp_2 + 1  ;; до тех пор, пока индекс
                                             ;; не будет соответствовать
                      IF (??tmp_1 EQ??tmp_2)
                        je &&&retl             ;; да !
                        EXITM
                      ENDIF   ;; конец проверки условия
                    ENDM      ;; конец второго блока IRP
                  ENDM        ;; конец первого блока IRP
                  ENDM        ;; конец макроопределения
         ;;
         ;;
         ;;*****************************************************
         ;; Используйте макрокоманды @PushAll и @PopAll вместо ко-
         ;; манд   PUSHA   и   POPA,   поддерживаемых  процессором
         ;; 80186/80188/80286/80386 для обеспечения  совместимости
         ;; с процессорами 8086/8088.
         ;;
         ;;** @PushAll ********** Mакрокоманды общего назначения **
         ;;  Поместить в стек содержимого всех регистров
         IF1     ;; Выполнять только в процессе прохода 1
         @PushAll MACRО  ;; сохранить содержимое всех регистров в стеке
                 push      ax
                 push      bx
                 push      cx
                 push      dx
                 push      dp
                 push      di
                 push      si
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода

                                      - П-26 -
         ;;
         ;;** @PopAll *********** Mакрокоманды общего назначения **
         ;; Снять со стека содержимое всех регистров
         IF1     ;; Выполнять только в процессе прохода 1
         @PopAll MACRO           ;; восстановить  содержимое всех
                                 ;; регистров из стеке
                 pop       si
                 pop       di
                 pop       dp
                 pop       dx
                 pop       cx
                 pop       bx
                 pop       ax
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;** @ExiToDos ********* Mакрокоманды общего назначения **
         ;;   Завершить процесс с необязательными установками
         ;;   значений переменной ERRORLEVEL
         IF1     ;; Выполнять только в процессе прохода 1
         @ExiToDOS MACRO errocode
                 IFB <errocode>     ;; код ошибки был указан?
                 mov       ax,4C00h ;; нет, загрузить функцию и значение
                                    ;; переменной ERRORLEVEL = "0" в AX
                 ELSE               ;; в противном случае
                 mov       ah,4Ch   ;; загрузить функцию и значение
                 mov       al,errocode   ;; переменной ERRORLEVEL отдельно
                 ENDIF
                 ;;
                 @DosCall           ;; вызвать MS-DOS
               ENDM   ;; конец макроопределения
         ENDIF  ;; конец выполнения прохода
         ;;
         ;;********************************************************
         ;; Конец макроопределений
         ;;********************************************************
         .LIST      ; восстановить выдачу листингов в нормальном виде
         ;; Kонец файла включения макроопределений

         ─────────────────────────────────────────────────────────────



              Использование стандартных библиотечных программ

              Если вы  используете  стандартный  набор немодифицированных
         программ во всех ваших программах,  для вас может оказаться  по-
         лезным  поместить эти стандартные программы в библиотечный файл,
         который всегда связан с вашими программами.  Использование этого
         метода упрощает процесс трансляции с ассемблера и редактирования
         связей,  а также уменьшает размер исходных файлов вашей програм-
         мы. Библиотечный файл создается путем трансляции файла, содержа-
         щего ваши стандартные программы и последующей обработки  .OBJ  -
         файла с помощью LIB - программы,  помещенной на диске с макроас-
         семблером MASM.  В результате обработки LIB-программы получается
         файл, содержащий корректно отформатированную объектную программу
         с расширением .LIB.  Внешние ссылки на эти стандартные программы

                                      - П-27 -
         должны  быть описаны в исходном тексте данной программы, которая
         должна вызывать эти стандартные программы. Эти стандартные прог-
         раммы пишутся в формате:
              EXTRN стандартная программа : расстояние
              где EXTRN - управляющая команда,  которая сообщает макроас-
         семблеру MASM,  что "стандартная подпрограмма", будет включаться
         во время редактирования связей либо из объектного файла, либо из
         библиотечного файла.
              Параметр "расстояние"  имеет  значение или "близко" (near),
         или "далеко" (far) в зависимости от того, как была описана стан-
         дартная программа,  на которую осуществляется ссылка.  Для прог-
         рамм с расширением типа .COM параметр и расстояние  всегда имеет
         значение "близко".
              После того как внешние стандартные  программы  описаны,  их
         можно вызывать также , как и любые другие стандартные программы.
              В листинге A-8 представлен полный исходных текст библиотеч-
         ного  файла  STDLIB.LIB,  о  котором рассказывалось в предыдущих
         главах.


              Листинг A-8. Исходный текст библиотечного файла
                                 STDLIB.LIB
         ─────────────────────────────────────────────────────────────
         PAGE 60,132
         TITLE   stdlib.asm/.ob Ўlib
         .8086       ; позволяет только команды процессоров 8086/8088
         .SALL       ; запретить распечатку макрорасширений
         ;- -  - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;
         ;- - - - - - Равенства и макроопределения - - - - - - - -
         ;
         INCODE stdmac.inc  ; включить стандартные макробиблиотеки
                            ; и равенства
         ;
         ;- - - - - - - - - - - Инициализация - - - - - - - - - -
         ;
         ; Инициализация, описанная ниже, представляет собой подм-
         ; ножество (и совместимое) с управляющей командой ".МОDEL
         ; SMALL" макроассемблера MASM версии 5.0 и выше.
         ;
         _TEXT   SEGMENT WORD PUBLIC 'CODE'   ; сегмент программы
         _TEXT   ENDS
         ;
         _DATA   SEGMENT WORD PUBLIC 'DATA'   ; сегмент данных
         _DATA   ENDS
         ;
         DGROUP  GROUP   _DATA       ; определить группу сегментов
         ;
         ASSUME  cs:_TEXT,ds:_DATA   ; назначить  физические сегменты
         ;
         ;
         ;********************************************************
         ; Начало библиотечных стандартных программ
         ;********************************************************
         ;
         _TEXT   SEGMENT            ; начало сегмента текста программы
         ;

                                      - П-28 -
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; Новая строка : отображает новую строку (возврат каретки +
         ;                + перевод строки)
         ;
         ; Вход : нет
         ;
         ; Выход :  AX и DX восстанавливаются;
         ;          другие регистры не используются.
         ;
         ; Bызываемых стандартных программ: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - -  - -
         PUBLIC NEWLINE          ; библиотечная  стандартная  программа
         ;
         newline PROC    NEAR
                 push    ax           ; сохранить содержимое регистров
                 push    dx
         ;
                 mov     dl,CR         ; отобразить возврат каретки
                 mov     ah,02h
                 @DosCall
                 mov     dl,LF         ; отобразить перевод строки
                 mov     ah,02h
                 @DosCall
         ;;
                 pop     dx   ; восстановить содержимое регистров
                 pop     ax
                 ret
         ;
         newline ENDP
         ;
         ;
         ;++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ;   CSAVE :  Выполняет автоматическое сохранение и
         ;   восстановление  содержимого  регистров : BX, CX, DI и
         ;   SI внутри вызываемой стандартной программы. Она вызы-
         ;   вается из  другой  вызываемой  стандартной  программы
         ;   следующим образом :
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         ; LOCALIZE       EQU   10h
         ; routine PROC   NEAR  ; FAR, если средняя, большая
         ;                      ; или очень большая модель
         ;
         ;      push      bp
         ;      mov       bp,sp
         ;      sub       sp,LOCALIZE
         ;      call      csave
         ;      :
         ;      (текст стандартной программы)
         ;      :
         ;      ret          ; всегда направляется в $cret
         ;
         ; routine ENDP
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
         ;
         ; Вход : смотри описание выше
         ;

                                      - П-29 -
         ; Выход : смотри описание выше
         ;
         ; Используемые регистры: содержимое регистров BX, CX, DI и
         ;                        SI сохраняется; регистры AX и DX
         ;                        не трогаются.
         ;
         ; Вызываемые стандартные программы: идут обращения к
         ; "вызывающей" стандартной программе до тех пор, пока
         ; по ее команде возврата RET не осуществится возврат в
         ; эту программу, после чего по команде возврата RET
         ; этой программе осуществится возврат в исходную
         ; вызвавшую программу.
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
         public   csave       ; библиотечная стандартная программа
         ;
         csave   PROC      NEAR
                 push     bp     ; установить адресацию стека
                 mov      bp,sp
                 xchg     bx,[bp+2] ; сохранить содержимое регистров
                                    ; BX и получить адрес возврата
                                    ; вызвавшей стандартной программы
                  pop       bp  ; восстановить текущий адрес возврата
                  push      cx  ; сохранить содержимое остальных
                                ; регистров
                  push      si
                  push      di
                  call      bx     ; продолжить обработку в
                                   ; вызвавшей стандартной программе
         ;
         ; Перейти  сюда по команде возврата RET вызвавшей
         ; стандартной программы
         $cret:   pop       di       ; восстановить сохраненное
                                     ; содержимое регистров
                  pop       si
                  pop       sx
                  pop       bx
                  mov       sp,bp    ; cбросить локальные переменные
                  pop       bp
                  ret                ; aвозвращает в то место, куда
                                   ; обычно идет возврат по команде
                               ; возврата RET в вызывающую программу
         ;
         csave    ENDP
         ;
         ;
         ;++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; BIN2DEC -   Преобразование из двоичной в десятичную сис-
         ; тему  счисления. Отображает на экране дисплея в десятич-
         ; ном виде шестнадцатиразрядное число со  знаком  или  без
         ; знака. Находит самый последний разряд справа путем деле-
         ; ния.  Повторяет  до  тех пор, пока все не будет найдено.
         ; Может быть указано минимальное количество разрядов, под-
         ; лежащих отображению. Если минимальное количество указан-
         ; ных разрядов больше  фактического  количества  разрядов,
         ; результирующее число дополняется начальными нулями.
         ;

                                      - П-30 -
         ; Вход :   AX = число, подлежащее отображению
         ;          CH = минимальное число разрядов, подлежащих
         ;                отображению
         ;          DX = 0, если число, подлежащее обработке, не
         ;                  имеет знака или = 1, если число, под-
         ;                  лежащее обработке, имеет знак
         ;
         ; Выход : (регистры AX, CХ и DX восстанавливаются)
         ;
         ; Вызываемые стандартные программы: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC   BIN2DEC      ; библиотечная стандартная программа
         ;
         bin2dec  PROC    NEAR
           push    ax              ; сохранить содержимое регистров
           push    bx
           push    cx
           push    dx
           mov     cl,0            ; очистить счетчик разрядов
           mov     bx,10           ; установить делитель = 10
           cmp     dx,0            ; всегда  отображать номер, как
                                   ; положительное число?
           je      more_dec        ; да, игнорировать проверку на
                                   ; отрицательное число
         ;
         ; Проверить на  отрицательное число. Если число
         ; отрицательное, сделать его положительным.
            or       ax,ax       ; число положительное ?
            jnl     more_dec     ; да, игнорировать "отрицательное"
            neg     ax           ; сделать число положительным
            @Dischr'-'           ; отобразить знак "минус"
         ;
         ; Основной цикл деления - получить десятичный разряд.
         ; Повторять, пока остаются разряды.
         more_dec:
                  xor     dx,dx                ; очистить
                  div     bx                   ; разделить на 10
                  push    dx                   ; сохранить остаток
                  inc     cl          ; добавить к значению счетчика
                                      ; разрядов единицу
                  or      ax,ax       ; проверить  частное
                  jnz     more_dec    ; продолжить, если больше
         ;
         ; Основной цикл печати разрядов - обратный порядок.
                  sub     ch,cl       ; минимальное число разрядов
                                      ; получено?
                  jle     morechr     ; да, начать отображение
                  xor     dx,dx       ; нет, начать вставлять "нули"
         morezero:
                  push    dx
                  inc     cl          ; добавить к значению счетчика
                                      ; разрядов единицу
                  dec     ch          ; проверить на совпадение
                  jnz     morezero    ; нет - продолжать вставку
         morechr:
                  pop     dx          ; восстановить последний разряд
                  add     dl,30h      ; преобразовать в код ASCII

                                      - П-31 -
                  @DisChr dl          ; разряд результата
                  dec     cl          ; вычесть из счетчика разрядов
                                      ; единицу
                  jnz     morechr     ; продолжить,  если больше
         ;
                  pop     dx    ; восстановить содержимое регистров
                  pop     cx
                  pop     bx
                  pop     ax
                  ret

         ;
         bin2dec  ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++
         ; BIN2DEC2 - Преобразование из двоичной в десятичную систе-
         ;   му  счисления;  отображает  32-разрядное число. Создает
         ;   два десятичных числа, которые отображаются через  обра-
         ;   щения к BIN2DEC.
         ;       Может быть указано минимальное число разрядов, под-
         ;   лежащих  отображению.  Если минимальное количество ука-
         ;   занных разрядов больше фактического числа разрядов, вы-
         ;   ходное число дополняется начальными нулями.
         ;       Примечание:  сдвоенных регистров, содержащих число,
         ;   разбивается в лучшем случае, наименьшая значащая  часть
         ;   числа составляет 9.999. Оно никогда не будет отображено
         ;   как отрицательное число.
         ;
         ; Вход :   DX: AX = число, подлежащее отображению
         ;          CH = минимальное число разрядов, подлежащих
         ;                отображению
         ;
         ; Выход : (регистры AX : DX восстанавливаются)
         ;
         ; Вызываемые стандартные программы: BIN2DEC (вывод
         ;            16-разрядного числа в десятичном виде)
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC  BIN2DEC2    ; библиотечная стандартная  программа
         ;
         bin2dec2 PROC    NEAR
         ;EXTRN  bin2dec2:NEAR   ; ссылка на стандартную программу
                                 ; BIN2DEC
                  push    ax     ; сохранить содержимое регистров
                  push    bx
                  push    cx
                  push    dx
         ;
         ;   Проверить на отрицательное число.  Если  отрицательное,
         ; сделать положительным.
                  or      dx,dx       ; число положительное ?
                  jnt     bd2_pos  ; да, игнорировать "отрицательное"
                  not     ax          ; сделать число положительным
                  not     dx
                  add     ax,1        ; (точное) дополнение в двоич-
                                      ; ной системе счисления (допол-
                                      ; нительный код), реализуемое

                                      - П-32 -
                                      ; аппаратным способом
                  adc     dx,0
                  push    dx
                  push    ax
                  @DisChr '-'
                  pop     ax
                  pop     dx
         ;
         ; Теперь разбить число, подлежащее распечатке, на две
         ; управляемые части.
         bd2_pos:
                  mov     bx,10000    ; установить делитель = 10000
                  div     bx          ; разбить число  на пары
                  cmp     dx,0        ; отбросить, если наибольшее
                  je      bd2_2big    ; значащее число слишком велико
                  or      ax,ax       ; выяснить, равно ли "0"
                                      ; наибольшее значащее число
                  jz      bd2_nosig   ; нет наибольшего значащего
                                      ; числа
         ;
         ;  Печать первого наибольшего значащего числа (старшая
         ;  часть числа).
               push    dx
               sub     ch,4        ; четыре разряда будут распе-
                                   ; чатаны из наименьшей значащей
                                   ; части  числа
               jnc     bd2_cntok   ; запросить больше 4 для того,
                                   ; чтобы значение счетчика стало
                                   ; действительным
               mov     ch,0        ; в противном  случае, опрос идет
                              ; до тех пор, пока не кончатся разряды
         bd2_cntok:

                  call    bin2dec     ; печатать наибольшую значащую
                                      ; часть числа
                  pop     dx          ; восстановить наименьшую
                                      ; значащую часть числа
                  mov     ch,4        ; четыре разряда в наименьшей
                                      ; значащей части числа
         ;
         ; Печатать наименьшую значащую часть числа (младшую часть
         ; числа).
         bd2_nosig:
                  mov     ax,dx       ; печатать сначала содержимое
                                      ; регистра DX (наименьшую зна-
                                      ; чащую  часть числа)
                  call    bin2dec     ; печатать наименьшую значащую
                                      ; часть числа
         bd2_done:
                  pop     dx          ; восстановить содержимое регист-
                                      ; ров и выйти из программы
                  pop     cx
                  pop     bx
                  pop     ax
                  ret
         bd2_2big:
                  @DisStr  Bin2BigErrMsg

                                      - П-33 -
                  jmp     short bd2_done   ; возвратиться из стан-
                                           ; дартной программы
         ;
         _TEXT    ENDS
         _DATA    SEGMENT
         Bin2BigErrMsg db "BIN2DEC2 error: Oшибка: число слишком
                                           велико.$"
         _DATA    ENDS
         _TEXT    SEGMENT
         ;
         bin2dec2 ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; BIN2HEX  -  Преобразование из двоичной в  шестнадцатирич-
         ; ную  систему  счисления;  отображает 16-разрядное число в
         ; шестнадцатиричном виде.
         ;       Может быть указано минимальное количество разрядов,
         ; подлежащих отображению : если минимальное число указанных
         ; разрядов  больше фактического количества разрядов, выход-
         ; ное число дополняется значащими нулями.
         ;
         ; Вход :   AX = число, подлежащее отображению
         ;          CH = минимальное число разрядов, подлежащих
         ;               отображению (от 1 до  4).
         ;               Если CH=0, то значение счетчика разря-
         ;               дов по умолчанию принимается равным 4)
         ;
         ; Выход : нет (регистры AX и CX восстанавливаются)
         ;
         ; Вызываемые стандартные программы: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC BIN2HEX    ; библиотечная стандартная программа
         ;
         bin2hex  PROC     NEAR
                  push     ax   ; сохранить содержимое регистров
                  push     bx
                  push     cx
                  push     dx
         ;
             mov      bx,ax        ; использовать регистр BX для
                                   ; временного хранения
             cmp      ch,0         ; счетчик уже установлен?
             jne      align_left   ; да, тогда продолжать
             mov      ch,4         ; иначе, установить значение
                                   ; счетчика символов, равным 4
         ;
         ; Выровнять число по левому краю регистра AX (циклически
         ; сдвигать влево на (4 - CH) х 4 битовые позиции
         allign_left:
               mov      cl,4   ; определить число сдвигаемых цифр
               sub      cl,ch
               shl      cl,1   ; умножить на 4
               shl      cl,1
               rol      bx,cl        ; выравнивание влево
               mov      cl,4         ; и установить наименьшее
                        ; значение счетчика циклического сдвига

                                      - П-34 -
         ;
         ; Основной  цикл повторить  N раз. Печатать старший разряд.
         more_hex:
                  rol      bx,cl        ; переместить на один разряд
                                        ; вправо
                  mov      al,bl        ; переслать в регистр AL
                  and      al,0Fh       ; только младший разряд
                  add      al,90h       ; скрытое преобразование в
                  daa                   ; шестнадцатиричные символы
                                        ; в коде ASCII
                  adc      al,40h
                  daa
         ;
         ; Отобразить разряд
                  @DisChr  al
                  dec      ch       ; вычесть из счетчика разрядов
                                    ; единицу
                  jnz      more_hex ; продолжить, если больше
         ;
                  pop      dx   ; восстановить содержимое регистров
                  pop      cx
                  pop      bx
                  pop      ax
                  ret
         ;
         bin2hex ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; CHGCASE   -    Изменить  регистр  клавиатуры для симво-
         ; лов. Меняет регистр символов в коде ASCII. Указывается
         ; тип преобразования регистра клавиатуры.
         ;
         ;  1. Принудительное изменение верхнего  регистра  клавиатуры
         ;     на нижний.
         ;  2. Принудительное изменение нижнего регистра клавиатуры на
         ;     верхний.
         ;  3. Изменить состояние регистра клавиатуры на противополож-
         ;     ное (если нижний, то верхний; если верхний, то нижний).
         ;
         ; Вход :   AL = буквенный символ в коде ASCII, подлежащий
         ;               преобразованию
         ;          AH = тип преобразования:
         ;               "L" или "l" = печать символа на нижнем
         ;                             регистре клавиатуры
         ;               "U" или "u" = печать символа на верхнем
         ;                             регистре клавиатуры
         ;               любое другое значение меняет состояние
         ;               регистра клавиатуры на противоположное
         ;
         ; Выход :  AL = преобразованный  символ в коде ASCII
         ;          AH = состояние символа:
         ;               "L" = нижний регистр
         ;               "U" = верхний регистр
         ;               0 = если символ в регистре AL не являлся
         ;                   буквенным символом в коде ASCII
         ;               Содержимое всех других регистров

                                      - П-35 -
         ;               восстанавливается
         ;
         ; Вызываемые стандартные программы: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC  CHGCASE   ; библиотечная стандартная программа
         ;
         chgcase PROC      NEAR
                 push      dx    ; сохранение содержимого регистров
         ;
         ; Определить, содержит ли регистр AL буквенный символ в коде
         ; ASCII, и если символ действителен, определить его регистр.
             cmp       al,"A"       ; находится символ под первой
                                    ; буквой верхнего регистра?
             jl        error        ; да, он не является буквенным
                                    ; символом в коде ASCII
             cmp       al,"Z"       ; находится символ под последней
                                    ; буквой верхнего  регистра?
             jle       is_upper     ; да, символ соответствует
                                    ; верхнему регистру
             cmp       al,"a"       ; находится символ под первой
                                    ; буквой нижнего регистра?
             jl        error        ; да, он не является буквенным
                                    ; символом  в  коде ASCII
             cmp       al,"z"       ; находится символ под последней
                                    ; буквой нижнего регистра?
             jle       is_lower     ; да, символ находится в нижнем
                                    ; регистре
             jmp       short error  ; в противном случае, он не являет-
                                    ; ся буквенным символом в коде ASCII
         ;
         is_upper:
             mov       dl,"U"        ; пометить символ как признак
                                     ; верхнего регистра
             jmp       short convert_type ; и продолжить
         is_lower:
              mov      dl,"L"        ; пометить символ как признак
                                     ; нижнего регистра
              jmp      short convert_type ; и продолжить
         error:
              mov      ah,0   ; пометить символ как не буквенный
                              ; символ  в  коде  ASCII
              jmp      short done  ; и завершить выполнение процедуры
         ;
         convert_type:
              cmp      ah,"l"     ; изменить  на  нижний регистр?
              je       to_lower   ; да, поэтому изменить символ
              cmp      ah,"L"     ; изменить  на  нижний регистр?
              je       to_lower   ; да, поэтому изменить символ
              cmp      ah,"u"     ; изменить  на  верхний регистр?
              je       to_upper   ; да, поэтому изменить символ
              cmp      ah,"U"     ; изменить  на  верхний регистр?
              je       to_upper   ; да, поэтому изменить символ
         ;
         ;    В противном случае, изменить регистр клавиатуры
         ;    на противоположный
            cmp      dl,"L"      ; это символ нижнего регистра?
            je       to_upper    ; да, изменить его на верхний регистр

                                      - П-36 -
                            ; в противном случае, это верхний  регистр,
                            ; поэтому сделать его нижним
         ;
         to_lower:
             mov      ah,"L"     ; установить признак регистра для
                                 ; возврата
             cmp      dl,ah      ; символ уже соответствует нижнему
                                 ; регистру?
             je       done       ; да, действие выполнено
             add      al,20h     ; в противном случае, изменить на
                                 ; нижний регистр
             jmp      short done ; и выйти из процедуры
         ;
         to_upper:
             mov      ah,"U"   ; установить признак регистра для возврата
             cmp      dl,ah    ; символ уже соответствует верхнему
                               ; регистру ?
             je       done     ; да, действие выполнено
             sub      al,20h   ; в противном случае, изменить на
                               ; верхний  регистр
         ;
         done:
                  pop      dx  ; восстановить содержимое регистров
                  ret
         ;
         chgcase  ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; DOSVER -  Получает версию операционной системы MS-DOS
         ; и  возвращает старшую и младшую версии. Возвращает значе-
         ; ние "1.00", если текущая версия DOS 1.00 или 1.10.
         ;
         ; Вход :   нет
         ;
         ; Выход :  AL = старшая версия
         ;          AH = младшая версия ( =  00,  если  перед этим
         ;               была  версия 2.00 DOS)
         ;       (Содержимое всех других регистров восстанавливается)
         ;
         ; Вызываемые стандартные программы: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC  DOSVER       ; библиотечная стандартная программа
         ;
         dosver    PROC    NEAR
                   push    bx      ; сохранить содержимое регистров
                   push    cx
                   push    dx
         ;
                   xor     ax,ax             ; очистить регистр AX
                   mov     ah,30h    ; загрузить функцию "получить
                                     ; версию DOS"
                   @DosCall
                   cmp     al,0      ; это версия предыдущая 2.00?
                   jg      dos2plus  ; нет, действие сделано
                   mov     al,1    ; в противном случае это версия 1.ХХ
                   mov     ah,0    ; установить младшую версию в "00"

                                      - П-37 -
         ;
         dos2plus:
                   pop     dx      ; восстановить содержимое регистров
                   pop     cx
                   pop     bx
                   ret
         ;
         dosver    ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; DOSV2CON: Получает и отображает текущую версию операцион-
         ; ной системы MS-DOS, и возвращает версию  вызывающей  прог-
         ; рамме.
         ;
         ; Вход :   нет
         ;
         ; Выход :  AL = старшая версия
         ;          AH = младшая версия
         ;       (Содержимое всех других регистров восстанавливается)
         ;
         ; Вызываемые стандартные программы:
         ;        DOSVER  (получает версию MS-DOS)
         ;        BIN2CON (отображает номера в десятичном виде)
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC DOSV2CON    ; библиотечная стандартная  программа
         ;
         dosv2con   proc   NEAR
         ;                                    ;
         ;EXTRN  dosver: NEAR    ; получить  версию MS-DOS
         ;EXTRN  bin2dec: NEAR   ; отображает номера в десятичном виде
         ;
                push   bx      ; сохранить  содержимое  регистров
                push   cx      ;
                push   dx      ;
         ;
                call   dosver  ; получить  версию MS-DOS
                push   ax      ; сохранить возвращенную версию
                push   ax      ; и сохранить ее снова
                xor    ah,ah   ; записать номер старшей версии в
                               ; регистр AL
                mov    ch,1    ; отобразить по крайней мере 1 разряд
                call   bin2dec ; вывести  на  печать число
                @DisChr '-'    ; символ-разделитель
                pop    ax      ; восстановить номер младшей версии
                cmp    al,1    ; это версия 1.ХХ?
                je     ver1xx  ; да, отобразить "ХХ" как младшую версию
                xchg   ah,al   ; в противном случае поместить номер
                               ; младшей версии в регистр AL
                xor    ah,ah   ; очистить верхние
                mov    ch,2    ; отобразить, по крайней мере, 2 разряда
                call   bin2dec ; вывести число
                jmp    short end_ver      ; конец
         ;
         ver1xx:
                    @DisChr 'X'   ; вывести "Х"
                    @DisChr 'X'   ; и опять

                                      - П-38 -
         ;
         end_ver:
                    pop      ax   ; восстановить  номер версии для воз-
                                  ; врата основной стандартной программе
                    pop      dx   ; восстановить остальные регистры
                    pop      cx
                    pop      bx
                    ret
         ;
         dosv2con   ENDP           ; конец  стандартной  программы
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; MEMALLOC - Распределяет  блок памяти указанного размера
         ; в параграфах (16 байт).
         ;
         ; Вход :  BX = размер запрашиваемого блока в 16-байтных
         ;              параграфах
         ;
         ; Выход : Признак  переноса  = 0, если УСПЕХ, причем
         ;                 AX = адрес сегмента распределенного
         ;                      блока памяти
         ;                 (Содержимое  регистра BX восстанавливается)
         ;         Признак переноса = 1, если ОТКАЗ,  причем
         ;                 AX = код ошибки,
         ;                      7 = разрушенные блоки управления памятью
         ;                      8 = недостаточная память
         ;                 BX  = наибольший доступный блок памяти в
         ;                       параграфах
         ;
         ; Вызываемые стандартные программы: нет
         ;- -  - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC MEMALLOC   ; библиотечная стандартная  программа
         ;
         memalloc  PROC      NEAR
                   push      bp        ; сохранить указатель базы
                   push      bx        ; сохранить содержимое регистра BX
                   mov       bp,sp     ; инициализировать указатель базы
         ;
                   xor       al,al     ; очистить регистр AL
                   mov       ah,48h    ; загрузить функцию распределения
                                       ; памяти
                   @DosCall            ; выполнить распределение памяти
                   jnc       end_memalloc     ; завершить выполнение,
                                       ; если нет ошибки с адресом
                                       ; сегмента в регистре AX
                                    ; в  противном случае, завершить
                                    ; выполнение с установкой признака
                                    ;  переноса
                   mov       word ptr [bp],bx ; максимальным размером
                                       ; блока  (в  регистре BX)
                                       ; и кодом ошибки в регистре AX
         ;
         end_memalloc:
                   pop       bx       ; восстановить регистр BX
                   pop       bp       ; восстановить указатель базы
                   ret

                                      - П-39 -
         ;
         memalloc ENDP
         ;
         ;
         ;+++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; MEMSIZE:  Изменяет размер блока памяти,  ранее  распреде-
         ; ленной  с помощью стандартной программы MEMALLOC. Указыва-
         ; ются адрес блока и запрашиваемый размер (в 16-байтных  па-
         ; раграфах).
         ;
         ; Вход :  ES = адрес сегмента распределенного блока памяти
         ;         BX = новый размер в 16-байтных параграфах
         ;
         ; Выход : Признак  переноса  = 0, если УСПЕХ, причем
         ;            (Содержимое  всех регистров восстанавливается)
         ;         Признак переноса = 1, если ОТКАЗ,  причем
         ;                 AX = код ошибки,
         ;                      7 = разрушенные блоки управления памятью
         ;                      8 = недостаточная память
         ;                      9 = недействительный адрес блока
         ;                 BX  = наибольший доступный блок памяти в
         ;                       параграфах, если AX = 8,
         ;                       в противном случае, содержимое его
         ;                       восстанавливается.
         ;                (Содержимое регистра ES восстанавливается)
         ;
         ; Вызываемые стандартные программы: нет
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC   MEMSIZE   ; библиотечная стандартная  программа
         ;
         memsize  PROC       NEAR
                  push       bp   ; сохранить указатель базы
                  push       es   ; сохранить адрес блока памяти
                  push       ax   ; сохранить регистр AX
                  push       bx   ; сохранить регистр BX
                  mov        bp,sp  ; инициализировать указатель базы
         ;
                  xor        al,al   ; очистить регистр AL
                  mov        ah,4Ah  ; загрузить функцию и изменить
                                     ; размер блока
                  @DosCall
                  jnc        end_memsize       ; завершить выполнение,
                                               ; если нет ошибки
                            ; в противном случае, завершить выполнение
                            ; с установкой признака  переноса
                  pushf                        ; сохранить признаки
                  cmp        ax,8              ; памяти недостаточно?
                  jne        memsize_err       ; нет, продолжить
                  mov        word ptr [bp],bx  ; в противном случае,
                              ; сохранить максимально доступный размер
         memsize_err:
                  mov        word ptr [bp+2],ax ; сохранить код ошибки
                  popf                          ; восстановить  признаки
         ;
         end_memsize:
                  pop        bx   ; восстановить содержимое регистров
                  pop        ax

                                      - П-40 -
                  pop        es
                  pop        bp   ; восстановить указатель базы
                  ret
         ;
         memsize  ENDP
         ;
         ;
         ;++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; MEMFREE - Освобождает  блок памяти, ранее распределенный
         ; стандартной программой MALLOC.
         ;
         ; Вход :  ES = адрес сегмента распределенного блока памяти
         ;
         ; Выход : Признак  переноса  = 0, если УСПЕХ
         ;                (Содержимое регистра ES восстанавливается)
         ;         Признак переноса = 1, если ОТКАЗ,  причем
         ;                 AX = код ошибки,
         ;                      7 = разрушенные блоки управления памятью
         ;                      9 = недействительный адрес блока
         ;                (Содержимое регистра ES восстанавливается)
         ;
         ; Вызываемые стандартные программы: нет
         ;
         ;- - - - - - - - - - - - - - - - - - - - - - - - - - - -
         PUBLIC MEMFREE     ; библиотечная стандартная  программа
         ;
         memfree  PROC       NEAR
                  push       bp              ; сохранить указатель базы
                  push       es              ; сохранить адрес блока памяти
                  push       ax              ; сохранить регистр AX
                  mov        bp,sp           ; инициализировать указатель
                                             ; базы
                  xor        al,al           ; очистить регистр AL
                  mov        ah,49h          ; загрузить функцию осво-
                                             ; бождения памяти
                  @DosCall             ; выполнить освобождение памяти
                  jnc        end_memfree     ; завершить выполнение,
                                             ; если нет ошибки
                                 ; в противном случае, завершить выпол-
                                 ; нение с установкой признака переноса
                  mov   word ptr [bp],ax ;  и кодом ошибки (регистр AX)
         ;
         end_memfree:
                  pop        ax   ; восстановить содержимое регистра AX
                  pop        es   ; восстановить адрес блока
                  pop        bp   ; восстановить  указатель базы
                  ret
         ;
         memfree  ENDP
         ;
         ;
         ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++
         ; MERRHNDL - Обработка ошибки распределения памяти/ос-
         ; вобождения памяти (повторного задания размера).
         ;
         ; Вход :  AX = код ошибки
         ;         BX  = наибольший доступный блок памяти

                                      - П-41 -
         ;                       (если код ошибки = 8)
         ;         ES = адрес сегмента распределенного блока памяти
         ;                       (если код ошибки = 9)
         ;
         ;         ES = адрес сегмента распределенного блока памяти
         ;
         ; Выход : нет (содержимое всех регистров восстанавливается)
         ;
         ; Вызываемые стандартные программы:
         ;        BIN2CON (отображает номера в десятичном виде)
         ;- - - - - - - - - - - - - - - - - - - - - - - - - -  - -
         PUBLIC  MERRHNDL       ; библиотечная стандартная  программа
         ;
         merrhndl PROC      NEAR
         ;
                 cmp        ax,7   ; очищены блоки управления памятью?
                 jne        mem_error8       ; нет, продолжить проверку
                 @DisStr    TrashedMemErr_Msg; да, завершить выполнение
                                             ; сообщением
                 ret                         ; вернуться
         ;
         mem_error8:
                 cmp        ax,8             ; памяти  недостаточно?
                 jne        mem_error9       ; нет, продолжить проверку
                 @DisStr    InsuffMemErr_Msg ; да, завершить выполнение
                                             ; сообщением
                 @DisNum    bx,10,1,0   ; и наибольшим доступным блоком
                                        ; памяти
                 @Newline               ; отобразить пустую строку
                 ret                    ; вернуться
         ;
         mem_error9:
                 cmp        ax,9             ; адрес блока памяти
                                             ; недействителен?
                 jne        mem_err_unknown  ; нет, неизвестна причина
                 @DisStr    IncorrSegAddr_Msg; отобразить сообщение об
                                             ; ошибке
                 @DisNum    es,16,4      ; отобразить адрес  сегмента
                 @NewLine                ; отобразить пустую строку
                 ret                     ; вернуться
         ;
         mem_err_unknown:
                 @DisStr   UnknownMemErr_Msg ; вывести сообщение
                 ret
         ;
         _TEXT   ENDS            ; конец сегмента текста программы
         _DATA   SEGMENT         ; начало сегмента данных
         trashedMemErr_Msg db  ""Сбой при распределении памяти: управ-"
                           db "ляющие блоки памяти разрушены.",CR,LF,"$"
         InsuffMemerr_Msg  db ""Сбой при  памяти: "
                           db "Недостаточно памяти",CR,LF
                           db "наибольший доступный блока памяти = $"
         IncorrSegAddr_Msg db "Неправильный адрес сегмента для "
                       db "повторного задания размера/освобождения.",CR,LF
                           db "Адрес сегмента = $"
         UnknownMemErr_Msg db "Неизвестная ошибка при распределении/"
                           db "повторном задании размера/освобождении "

                                      - П-42 -
                           db "памяти.",CR,LF,"$"
         _DATA    ENDS            ; конец сегмента данных
         _TEXT    SEGMENT         ; начало сегмента программы
         ;
         merrhndl ENDP
         ;
         ;
         ;********************************************************
         ;  Конец стандартных библиотечных программ
         ;********************************************************
         _ТEXT    ENDS
                  END
         _________________________________________________________


              Как видно из листинга, все стандартные программы должны быть
         описаны  в  исходном файле как PUBLIC (общего пользования) с тем,
         чтобы сделать их доступными для других программ. Любая метка (ко-
         торая представляет собой то же, что и имя стандартной программы),
         подлежащая использованию в других программах, должна быть описана
         таким образом.
              Если стандартные программы должны включаться  в  .EXE-файлы,
         то единственное что необходимо - это использовать управляющую ко-
         манду EXTRN,  помещенную "за пределами описания сегмента". Редак-
         тор  связей  LINK  находит  данную ссылку в библиотеке и помещает
         стандартную программу,  на которую идет ссылка в  ее  собственный
         сегмент в окончательной программе.  Однако,  если эти стандартные
         программы должны  включаться  в файлы типа .COM,  то оба имени и
         сегмента и "класса",  используемые для .COM - программы,  должны
         соответствовать именам,  используемым в стандартной библиотечной
         программы.
              Чтобы использовать стандартные программы BIN2DEC или BIN2НEХ
         программа  типа  .COM должна использовать следующее описание сег-
         мента:

            code     segment para public "code"

              Отметим, что описание данного сегмента должно быть определе-
         но  как PUBLIC.  В этом случае и имя сегмента (code) и имя класса
         ('code') одинаковы, чтобы облегчить их запоминание. Кроме того уп-
         равляющие команды EXTRN должны быть помещены в описание  сегмента,
         что позволит макроассемблеру MASM знать, какие внешние стандартные
         программы являются составной частью этого сегмента.  (Метки PUBLIC
         и EXTRN даются атрибутам того же сегмента,  что и сегмента который
         включает их описания).
              Дополнительная информация  относительно  библиотечных  стан-
         дартных  программ,  меток PUBLIC и EXTRN можно найти в справочных
         руководствах по макроассемблеру MASM и редактору связей LINK фир-
         мы "Майкрософт".

                                      - П-43 -


                   Приложение Б. НЕ ОПИСАННЫЕ В ДОКУМЕНТАЦИИ ПО
                 ОПЕРАЦИОННОЙ СИСТЕМЕ MS-DOS ПРЕРЫВАНИЯ И ФУНКЦИИ



              Не описанные в  документации прерывания операционной
              системы MS-DOS
              Не описанные в документации вызовы функций прерывания 21h(33)


              В этом приложении приводится описание некоторых не описанных
         в документации средств операционной системы MS-DOS.  В частности,
         описываются прерывания MS-DOS и функции, связанные с этими преры-
         ваниями.  "Не  описанные в документации" относятся к таким средс-
         твам,  которые не описываются подробно,  а о которых просто  идет
         упоминание  как о "зарезервированных" или "неиспользуемых" средс-
         твах в Техническом справочном руководстве по MS-DOS (фирмы "Майк-
         рософт")  или  Техническом  справочном  руководстве по DOS (фирмы
         "ИБМ").
              Несмотря на то, что некоторые из "зарезервированных" средств
         действительно зарезервированы и,  по-видимому,  функционально  не
         связаны  между  собой,  другие же средства функционально связаны,
         что обнаружено на практике опытными и искусными программистами.
              Описанные ниже средства представляют собой конспективное из-
         ложение не описанных в документации прерываний и функций по обра-
         ботке прерываний, которые были проанализированы авторами и други-
         ми лицами,  представившими свои находки в  различных  электронных
         возможностях объявлений в качестве общедоступной информации.
              Необходимо отметить,  что  авторы  и издатель не дают вообще
         никаких заверений относительно верности  и  точности  информации,
         представленной в данном приложении.
              Поскольку все прерывания и функции,  описанные в этом прило-
         жении,  помечены как "зарезервированные" в технической справочной
         документации фирм "Майкрософт" и "ИБМ", разумно предположить, что
         разработчики операционной системы MS-DOS должны , возможно, изме-
         нить определение этих прерываний и функций в будущих версиях опе-
         рационной  системы MS-DOS.  Поэтому,  любой желающий использовать
         любые из описанных прерываний или функций в своих программах  де-
         лает это на свой страх и риск.  Только некоторые из данных преры-
         ваний и функций прерываний получили общераспространенное  призна-
         ние их использования в некоторых типах программ (например,  TSR -
         программ, остающихся резидентными после завершения).
             Большинство описанных  средств  представлено  с  единственной
         целью удовлетворить свойственное нам любопытство и с целью  даль-
         нейшего понимания работы операционной системы MS-DOS.


               Не описанные в  документации прерывания операционной
                                  системы MS-DOS

              В версии 3.3 операционной системы 2Eh описаны в документации
         по операционной системе как  зарезервированные. Прерывания  28h,
         29h и 2Eh описаны в следующих параграфах.


                                      - П-44 -

                Прерывание 28h(40): прерывание по безопасности DOS

              Прерывание 28h  обычно  называется "прерыванием для безопас-
         ности операционной системы MS-DOS" или "прерыванием по циклу  за-
         нятости  клавиатуры".  Оно  используется  внутренней  стандартной
         программой операционной системы MS-DOS "Get  Input"  (Осуществить
         ввод с клавиатуры),  если и только если она безопасна для исполь-
         зования функций "0Сh" и выше при прерывании "int 21h". Прерывание
         "int 28h" используется главным образом программами "завершиться и
         остаться резидентными",  включая программу PRINT.COM операционной
         системы MS-DOS.  Если какая-либо  программа  вызвала  стандартную
         программу  "Осуществить ввод с клавиатуры" и ожидает нажатия кла-
         виши, операционная система MS-DOS приостанавливает вызов прерыва-
         ния  "int  28h"  в качестве сигнала другим прикладным программам,
         которые могут могут быть загружены,  что никакие функции прерыва-
         ния  "int  21h" (кроме 0Сh и выше) не должны вызываться.  Нажатие
         клавиши и завершение выполнения данной стандартной программы  вы-
         зывает  прерываний "int 28h",  служащее сигналом для других прик-
         ладных программ,  которые могут быть загружены, что система прос-
         таивает  и безопасна для выполнения функций прерывания "int 21h".
              В большинстве случаев прерывания "int 28h" используются сов-
         местно  с  функцией  34h (Получить признак занятости операционной
         системы DOS) прерывания "int 21h" :  операционная система  MS-DOS
         вызывает или снимает прерывание "int 28h" соответственно, а прик-
         ладная программа вызывает функцию установления признака занятости
         DOS с целью определения незанятого состояния системы.


                  Прерывание 29h(41): Вывод на устройство консоли

              Прерывание "int  29h" ,  часто называемое по "выводу на уст-
         ройство консоли" или FAST PUTCHAR,  вызывают внутренние стандарт-
         ные программы вывода операционной системы MS-DOS, если вывод осу-
         ществляется на устройство,  а не в файл,  а также  если  в  слове
         атрибута   драйвера,  обслуживающего  данное  устройство,  разряд
         3(04h) установлен в 1.  Прерывание "int 29h" можно назвать черным
         ходом для драйвера устройства вывода на консоль: символ в регист-
         ре AL выводится на консоль в процессе обработки этого прерывания.

             Прерывания с 2Ah(42) по 2Dh(45) : внутренние стандартные
                       программы операционной системы MS-DOS

              Прерывания, начиная с "int 2Ah" и кончая "int 2Dh" , являют-
         ся  внутреними прерываниями операционной системы MS-DOS.  Векторы
         всех этих прерываний указывают на код операции  IRET.  Прерывание
         "int  2Ah"  используется для управления сетью в системах установ-
         ленных с MSNET и другим сетевым  программным  обеспечением  фирмы
         "Майкрософт".


            Прерывание 2Eh(46). "Черный ход" для командного процессора

              Обычно для обработки команды с помощью командного процессора
         COMMAND.COM используется  функция  EXEC (функция  4Вh  прерывания

                                      - П-45 -
         "int 21h").  Однако, альтернативный, быстрый и "грубый" метод вы-
         полнения  той же функции обеспечивает прерывание "int 2Eh". Чтобы
         выполнить какую-либо команду операционной системы MS-DOS, вначале
         уплотняется  память  с  целью выделения места для новой программы
         (как и в случае функции 4Вh прерывания "int 21h" ), затем заносят
         в регистр DS:SI указатель на строку параметров данной команды и в
         конце обрабатывается прерывание "int 2Eh". Первый байт  в  строке
         параметров данной команды - это длина строки, за ней следует сама
         строка (например,  CHKDSK  C:),  которая  заканчивается  символом
         "возврат каретки" (0Dh).
              Этот завершающий символ считается частью длины строки. После
         того как прерывание "int 2h" обработано, важным моментом является
         обнуление стека,  поскольку в результате прерывания "int 2h"  со-
         держимое регистров SS и SP может не сохраниться.

                         Прерывания с 30h(48) по FFh(255)

              Для операционной системы MS-DOS, начиная с версии 3.30, пре-
         рывания с "int 30h" по "int FFh" помещаются  как  зарезервирован-
         ные.  Однако  некоторые  из этих прерываний используются дополни-
         тельным аппаратным и программным обеспечением.  К примеру, преры-
         вание  "int  67h"  является зарезервированным для использования в
         спецификации  систем  расширенной  памяти  (EMS)   с   драйверами
         Lotus/Intel/Microsoft (LIM). С помощью этого прерывания (реализо-
         ванного в драйвере устройства EMS)выполняются все функции LIM EMS
         (см.  главу 7 для более полной информации по системам расширенной
         памяти EMS).  Прерывания с 30h(48) по FFh(255) используют  другие
         типы дополнительного аппаратного и программного обеспечения , та-
         кого как сетевые адаптеры фирмы "Майкрософт" и "ИБМ", стандартные
         программы базовой системы ввода-вывода (BIOS), адаптеры EGA и VGA
         и другие.

           Не описанные в документации вызовы функций прерывания 21h(33)

              Следующие вызовы функций  прерывания  "int 21h" помечены как
         "зарезервированные" или "неиспользуемые" в Техническом справочном
         руководстве  по  операционной  системе  DOS  фирм  "Майкрософт" и
         "ИБМ"  (для версии 3.3 операционной системы MS-DOS):  18h,  с 1Dh
         до 20h,  32h,  34h,  37h,  с 50h по 53h, 55h, 58h, 5Dh, 60h, 61h,
         63h, 64h.
              Наибольшим номером  описанной  функции  прерывания "int 21h"
         (по данным на версию 3.3 операционной системы MS-DOS) является 68
         h.Зарезервированные функции свыше 68h,  если вообще имеются,  еще
         предстоит узнать.Ниже описаны более  детально недокументированные
         функции прерывания 21h и выполняемые этими функциями операции.

             Функции  18h(24), 1Dh(29), 1Eh(30), 20h(32h): формальные
        функции, обеспечивающие совместимость с операционной системой CP/M

              Многие функции операционной системы MS-DOS c  более  низкими
         номерами эквивалентны   подобным  функциям  операционной  системе
         CP/M.  Не все из функций CP/M реализованы в операционной  системе
         MS-DOS,  однако  многие из них располагают "пустым окном" для об-
         легчения переноса программ операционной системы  CP/M  в  MS-DOS.
         Эти функции в после своего выполнения ничего не возвращают.


                                     - П-46 -

           Функция 1Fh(31): найти информацию о блоке на диске для текущего
                                       диска

              Функция 1Fh  используется для возврата указателя на "таблицу
         с информацией о блоке на диске" для текущего диска. В таблице Б-1
         приведен формат этой таблицы и ее содержимое.
              Вход :   AH = 1Fh
              Возврат: DS:BX содержит адрес точки первого входа блока на
                       диска для текущего диска
              Примечание: Функция 1Fh аналогична функции 32h,  за исключе-
                       нием того, что функция 32h возвращает информацию  о
                       блоке диска для указанного диска. При работе с вер-
                       сиями 2.0 и выше операционной  системы  MS-DOS  эта
                       функция  просто  выполняет  функцию  32h прерывания
                       "int 21h" при AL = 0.

                                                       Таблица Б-1
                Формат блока диска операционной системы MS-DOS
         ─────────────────────────────────────────────────────────────
         Смещение Тип          Данные
         ─────────────────────────────────────────────────────────────
         00     Байт      Диск (дисковод) 0 = A, 1 = В и т.д.
         01     Байт      Устройство внутри драйвера (0,1,2, и т.д.)
         02     Слово     Количество байтов  в  секторе
         04     Байт      Количество секторов в кластере - 1;
         05     Байт      Кластер сдвига сектора
         06     Слово     Количество зарезервированных (начальная
                          загрузка) секторов
         08     Байт      Количество  таблиц FAT
         09     Слово     Количество элементов корневого каталога
         0B     Слово     Номер сектора  кластера  2  (1-ый  сектор
                          данных)
         0D     Слово     Количество кластеров +1 (или последнего
                          кластера)
         0F     Байт      Секторы для таблиц FAT
         10     Слово     Номер сектора в каталоге
         12 Двойное слово Адрес  заголовка устройства
         16     Байт      Байт дескриптора среды
         17     Байт      Ноль, если к диску  идет обращение
         18 Двойное слово Адрес следующего блока диска операционной
                          системы DOS (FFFF, если последний блок диска
                          в цепочке)
         ─────────────────────────────────────────────────────────────



             Функция 32h(50) : найти информацию о блоке на диске  для
                                 указанного диска

              Функция 32h аналогична функции 1Fh, за исключением того, что
         может  быть  определен  указатель  на таблицу информации о блоках
         диска для указанного диска.
               Вход : AH = 32h
                      DL = номер дисковода (0 = по умолчанию, 1= A и т.д.)

                                      - П-47 -
               Возврат: AL = 00 если диск существует; =FFh если нет.
                       DS:BX содержит адрес первого входа в блок диска.
               Примечания: Функция 32h аналогична функции 1Fh, за исключе-
                       нием только того, что функция 1Fh возвращает инфор-
                       мацию о блоке диска для текущего диска

            Функция  34h (52): получить флаг занятости операционной
                                  системы MS-DOS

              Функция 34h возвращает указатель на флаг занятости  операци-
         онной  системы MS-DOS (также называемый флагом критической секции
         операционной системы MS-DOS). Флаг занятости операционной системы
         MS-DOS - это байт,  установленный в "0" в случае его безопасности
         для прерывания операционной системы MS-DOS и установленный в зна-
         чение, не  равное "0" в случае отсутствия безопасности для преры-
         вания операционной системы MS-DOS.  Эта функция используется сов-
         местно  с прерыванием "int 28h":  данное прерывание устанавливает
         флаг занятости операционной системы MS-DOS,  а функция 34h по об-
         работке  прерывания "int 21h" указывает на положение флага (отсы-
         лаем к более раннему обсуждению не описанных в документации  пре-
         рываний).
              Вход:    AH = 34h
              Возврат: ES:BX указывает на флаг занятости MS-DOS
              Примечания: Есть некоторые специфические особенности, касаю-
                       щиеся флага занятости операционной системы MS-DOS в
                       различных версиях операционной системы  MS-DOS. При
                       работе под управлением  операционной системы MS-DOS
                       версии 2.10 байт,  расположенный непосредственно за
                       флагом занятости операционной системы MS-DOS должен
                       быть установлен в "00", чтобы вызвать прерывание по
                       обработке   PRINT.COM.   Для  операционной  системы
                       MS-DOS версии 3.0 и 3.1 (за исключением  COMPAQ DOS
                       3.0) байт  перед флагом занятости операционной сис-
                       темы MS-DOS должен быть установлен в "0",  для опе-
                       рационной  системы COMPAQ DOS версии 3.0 байт 01AAh
                       до этого должен быть установлен в "0".


             Функция 37h(55): получить/установить символ переключения

              Функция 37h используется для изменения символа,  который ис-
         пользуется для переключений командных строк операционной системы
         MS-DOS. "Символ-переключатель"  по  умолчанию  представляет собой
         символ / (наклонная черта),  однако он может быть изменен  с  по-
         мощью функции 37h на какой-нибудь другой символ, подобный символу
         переноса (-),  который является по умолчанию подобным символом  в
         операционной системе UNIX. Эта функция была полно описана в доку-
         ментации по операционной системе MS-DOS до того, как была выпуще-
         на версия 3.0 операционной системы MS-DOS, когда в составе ее ко-
         манд  была  команда,  которая  должна  была  помещаться  в   файл
         конфигурации системы CONFIG.SYS (SWITCHAR=/).
              Для версии 3.0 операционной системы  MS-DOS  ссылки  на  эту

                                      - П-48 -
         функцию и на команду SWITCHAR из CONFIG.SYS были удалены из доку-
         ментации по  операционной  системе MS-DOS. Однако,  в версии 3.30
         операционной системы MS-DOS, функция 37h прерывания 21h  выполня-
         ются также как и прежде.
              Вход: AH = 37h
                    AL = 0 (считать "символ-переключатель" (возвращаемый в
                            регистре DL)
                    AL = 1 (установить символ переключения (новый символ в
                            регистре DL)
                    AL = 2 (только версия 2.Х операционной системы MS-DOS:
                            Считать готовность устройства)
                    AL = 3 (только версия 2.Х операционной системы MS-DOS:
                            Установить готовность устройства,  где DL = 0,
                            если /DEV/ должно предшествовать  именам  уст-
                            ройств, и  DL<>0,  если  /DEV/ не должно пред-
                            шествовать именам устройств
              Возврат: DL = Cимвол-переключатель (если AL = 0 или 1
                             на входе)
                       DL = флаг готовности устройства (если AL = 2 или 3
                             на входе)
                       AL = 0FFh в случае ошибки (значение регистра AL на
                             входе не равно числу от 0 до 3)


                      Функция 50h(8): установить сегмент PSP

              Функция 50h  используется для установки сегмента для  нового
         сегмента программного префикса (PSP).
              Вход: AH = 50h
                    BX = адрес сегмента нового PSP
              Возврат: ничего
              Примечания: Для версии 2.Х операционной системы  MS-DOS  эта
                          функция не может быть вызвана внутри обработчика
                          прерывания "int 28h" без предшествующего обраще-
                          ния  к  функции 5Dh прерывания "int 21h"

                       Функция 51h(81): Считать сегмент PSP

              Функция 51h  используется для возврата адреса сегмента теку-
         щего сегмента программного префикса (PSP).
              Вход: AH = 51h
              Возврат: BX = адрес сегмента текущего PSP

           Функция 52h(82): Считать адрес "списка списков" операционной
                                  системы MS-DOS

              Функция 52h возвращает указатель на "список списков"  опера-
         ционной  системы  MS-DOS,  содержащий  различные типы информации,
         включающие указатели на другие списки информации.  В таблицах Б-2
         и Б-3 представлен формат  "списка списков"  операционной  системы
         MS-DOS.
              Вход: AH = 52h

              Возврат: ES:BX содержит адрес "списка  списков" операционной
                             системы MS-DOS.
              Примечание: Список списков, о котором идет речь, различается

                                      - П-49 -
                          для версий  2.ХХ  и  3.ХХ  операционной  системы
                          MS-DOS  (см.  таблицы Б-2 и Б-3).Несмотря на то,
                          что указанный "Список списков", вызываемый вслед
                          за функцией  52h,  содержит  информацию в первом
                          блоке диска,  это не вызывает доступа  к  диску,
                          поскольку  данная информация на диске может ока-
                          заться не точной.  Функции 1Fh или 32h,  однако,
                          дают возможность  обращаться к диску,  автомати-
                          чески обновляя данный блок диска в случае  изме-
                          нений на диске.
                                                    Таблица Б-2
             "Список списков" операционной системы MS-DOS версии 2.ХХ
         ─────────────────────────────────────────────────────────────
         Смещение Тип          Данные
         ─────────────────────────────────────────────────────────────
          02    Слово   Сегмент первого управляющего блока памяти
          00    Байт    Пустой
          01    Слово   Указатель на первый блок диска (см.функцию 36h)
          04    Байт    Не известно; указатель на первый резидентный
                        драйвер?
          08    Слово   Указатель  на  драйвер устройства CLOCK$
          0С    Слово   Указатель на фактический CON: драйвер устройства
          10    Байт    Количество  логических дисководов в системе
          11    Слово   Максимальное количество байтов в блоке любого
                        блокового устройства
          13    Байт    Неизвестно
          17    Байт    Начало (не указатель) драйвера устройства NUL
         ─────────────────────────────────────────────────────────────

                                                    Таблица Б-3
             "Список списков" операционной системы MS-DOS версии 3.ХХ
         ─────────────────────────────────────────────────────────────
         Смещение Тип          Данные
         ─────────────────────────────────────────────────────────────
          02    Слово   Сегмент первого управляющего блока памяти
          00    Байт    Пустой
          01    Слово   Указатель на первый блок диска (см.функцию 36h)
          04    Байт    Не известно: указатель на первый резидентный
                        драйвер?
          08    Слово   Указатель  на  драйвер устройства CLOCK$
          0С    Слово   Указатель на фактический CON: драйвер устройства
          10    Байт    Максимальное количество байтов в блоке любого
                        блокового устройства
          12    Байт    Неизвестно (возможно указатель на текущий блок
                        каталога)
          16    Байт    Неизвестно (возможно массив информации на диске)
          1A    Байт    Неизвестно
          20    Байт    Количество блоковых устройств
          21    Байт    Значение команды LASTDRIVE в файле CONFIG.SYS
                        (по умолчанию = 5)
          22    Байт    Начало (не указатель) драйвера устройства NUL
         ─────────────────────────────────────────────────────────────

                                      - П-50 -
             Функция 53h(83): Преобразовать блок параметров BIOS (BPB)
                                  в блок на диске

              Функция 53h  преобразует  блок параметров BIOS (BPB) данного
         диска в формат "блока на диске" операционной системы DOS и разме-
         щает информацию в указанное место (см. таблицу Б-4).
              Вход: AH = 53h
                    DS:SI = указатель на блок параметров BIOS (BPB) для
                             диска
                    ES:BP = указатель  на  область, в которой должен хра-
                             ниться блок диска операционной системы DOS
              Возврат: информация в формате блока  диска,  хранимая  в
                       области первоначально указанной с помощью ES:BP

                                                         Таблица Б-4
          Информация о структуре блока диска операционной системы MS-DOS,
                             возвращенная функцией 53h
         ─────────────────────────────────────────────────────────────
         Смещение Тип          Данные
         ─────────────────────────────────────────────────────────────
         00     Слово     Количество байтов  в  секторе
         02     Байт      Количество секторов в кластере
         03     Слово     Зарезервированные сектора
         05     Байт      Количество  таблиц FAT
         05     Байт      Смещение от кластера до сектора
         06     Слово     Количество элементов корневого каталога
         08     Слово     Общее  количество  секторов
         0A     Байт      Байт описания среды
         0B     Слово     Количество секторов в таблице FAT
         ─────────────────────────────────────────────────────────────

                         Функция 55h(85): Создать блок PSP

              Функция 55h  используется для создания порожденного сегмента
         программного префикса (PSP).  Эта функция аналогична функции  26h
         прерывания 21h за исключением того, что новый PSP создается вмес-
         то копирования текущего PSP.
              Вход: AH = 55h
                    DX = адрес сегмента, в который должен  быть  уста-
                         новлен PSP
              Возврат: ничего


           Функция 58h(88): Получить/установить стратегию распределения
                                      памяти

              Вход : AH = 58h
                     AL = код функции
                     AL = 0 - получить стратегию распределения
                     AL = 1 - установить стратегию распределения
                     BL = код стратегии
                     BL = 0, если используется метод первого  подходя-
                             щего  (использует  первый  блок  в списке
                             свободной памяти, размер которого  больше
                             запрошенного или равен запрошенному

                                      - П-51 -
                     BL  = 1, если используется метод наилучшего приб-
                             лижения: (использует наименьший блок  па-
                             мяти,  достаточно  большой по отношению к
                             запрошенному)
                     BL = 2, если используется метод последнего подхо-
                             дящего (использует старшие адреса послед-
                             него пригодного для  использования  блока
                             памяти)
              Возврат:  Признак  переноса  = 1 в случае ошибки, причем
                        код  ошибки  в регистре AX. Признак переноса =
                        = 0, если нет ошибки, причем код  стратегии  в
                        регистре AX.

              Примечание: Подфункция установки воспринимает любое значение
                          в  регистре BL (2 или больше) как "метод послед-
                          него подходящего".  Подфункция возвращает  уста-
                          новку последнего значения с тем,  чтобы програм-
                          мы,  осуществляющие проверку,  смогли распознать
                          равно  ли  это  значение  2,  а также больше или
                          меньше 2.


             Функция 60h(96): Разложить строку пути доступа на строку
                       с полностью уточненным путем доступа

              Функция 60h принимает строку с указанием пути доступа, кото-
         рая указывает на и возвращает полностью уточненную версию того же
         пути доступа.
              Вход:  AH = 60h
                     DI:SI = указатель на строку пути доступа
                     ES:DI = указатель  на область, в которой должна
                             храниться возвращенная строка с полностью
                             уточненным  путем доступа
              Возврат:  Строка  с  полностью  уточненным путем доступа
                        возвращается в область,  первоначально  ука-
                        занную с помощью ES:DI. Не известны возвращен-
                        ные коды ошибок.


                Функция 63h(99): Получить таблицы начального байта

              Вход : AH = 63h
                     AL = подфункция
                     AL = 0 - получить системную таблицу начального байта
                          DL = 0 - очистить флаг
                          DL = 1 - установить флаг
                     AL = 2 установить временный флаг консоли
              Возврат:  DS:SI  = указатель на таблицу начального байта
                                 (если вызывается с AL = 0)
                        DL = временный флаг консоли (если вызывается
                             при AL = 2)

                                      - П-52 -

                            Приложение В.   ЛИТЕРАТУРА


                       Книги
                       Статьи



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


                                    Книги
                                    ─────
                Abel, P. Programming Assembler Language.2d ed. Reston,
         VA: Reston, 1984.
                Allworth,  S.  T.  Introduction  to Real-Time Software
         Design. New-York: Springer-Verlag, 1981.
                Angermeyer, J., R. Fahringer,K. Jaeger, and D. Shafer.
         Tricks of the MS-DOS Masters. Indianapolis: Howard  W.  Sams,
         1987.
                Demarco, T. Structured Analysis and Specification. New
         York: Yourdon, 1978.
                Disk  Operating  System. Boca Raton, FL: International
         Business Mashines, 1982 (for DOS 1.10),1983 (for  DOS  2.00),
         1983  (for  DOS  2.10), 1984 ( for DOS 3.00), 1984 and 1985 (
         for DOS 3.10).
                Disk Operating System Technical Reference. Boca Raton,
         FL: International Business Mashines, 1983 (  for  DOS  2.10),
         1984 (for DOS 3.00), 1984 and 1985 ( for DOS 3.10).
                Duncan,  Ray.  Advanced MS-DOS. Redmond, WA; Microsoft
         Press, 1986.
                Hyman, Michael. Memory Resident Utilities, Interrupts,
         and Disk Management with MS  &  PC  DOS.  Portland,  OR:  MIS
         Press, 1986.
                IAPX   86/88,   186/188  User's  Manual:  Programmer's
         Reference. Santa Clara, CA: Intel, 1983.
                Kane, G., D. Hawkins, and L. Leventhal. 68000 Assembly
         Language Programming. Berkeley, Osborne/McGraw-Hill,1981.
                Kernighan,  Brian,   and   Dennis   Ritchie.   The   C
         Programming  Language.  Englewood  Cliffs, NJ: Prentice-Hall,
         1978.
                Lafore, R. Assembly Language Primer for the IBM PC and
         XT. New York and Scarborough, Ontario: New American  Library,
         1984.
               Lai,  S.  Robert.  Writing  MS-DOS  Device Drivers. New
         york: Addison-Wesley, 1987.
               Lattice 8086/8088 C Compiler Manual. New york: Lifeboat
         Associates, 1982.
               Microsoft  C  Compiler:  User's  Guide.  Bellevue,  WA:
         Microsoft, 1984 and 1985 ( for C 3.00).
               Microsoft  C: Run-Time Library Reference. Bellevue, WA:
         Microsoft, 1984 and 1985 ( for C 3.00).
               Microsoft Macro Assembler User's Manual. Bellevue,  WA:
         Microsoft,  1981  and  1983 ( for MASM 2.00), 1984 and 1985 (
         for MASM 4.00).

                                      - П-53 -
               Microsoft MS-DOS Programmer's Reference. Bellevue,  WA:
         Microsoft, 1981 and 1983 ( for MS-DOS 2.10 ).
               Morgan,  C.  L.  Bluebook of Assembly Language Routines
         for the IBM PC & XT. New York and Scarborough,  Ontario:  New
         American Library, 1984.
               Morgan,   C.   L.   and   M.  Waite.  8086/8088  16-Bit
         Microprocessor Primer. Peterborough, NH: BYTE/McGraw-Hill,1982.
               Norton, P. Inside the IBM PC. Bowie, MD: Robert J. Brady
         Co., 1983.
               Savitzky, Stephen. Real-Time Microprocessor Systems.  New
         York: Van Nostrand Reinhold, 1985.
               Simrin,  Steven.  The  Waite Group's MS-DOS Bible. rev.
         ed. Indianapolis: Howard W. Sams, 1988.
               Tausworthe, R.C. Standardized Development  of  Computer
         Software. Pt. I. Englewood Cliffs, NJ: Prentice-Hall, 1977.
               Turbo  Pascal  Reference  Manual  Version  2.0.  Scotts
         Valley, CA: Borland International, 1984.
               Turbo  Pascal  Reference  Manual  Version  3.0.  Scotts
         Valley, CA: Borland International, 1983, 1984, and 1985.
               Waite    Group,   The.   The   Waite   Group's   MS-DOS
         Papers.Indianapolis: Howard W. Sams, 1988.
               Yourdon,  E.  U.  and  L.  L.  Constantine.  Structured
         Design. Englewood Cliffs, NJ: Prentice-Hall, 1977.
               Yourdon,  E.  U.  Techniques  of  Program Structure and
         Design. Englewood Cliffs, NJ: Prentice- Hall, 1975.

                                    Статьи
                                    ───────
              Duncan, Ray. "Lotus/Intel/Microsoft  Expanded  Memory", Byte
         11, no. 11, 1986 ( Special IBM Edition).
               Kaк писать программы,используя LIM EMS 3.2. Пример кус-
         ков программы  RAMDISK, использующей расширенную память.
               Hansen,  Marion,  and  John  Driscoll.  "LIM EMS 4.0: A
         Definition for Next Generation of Expanded  Memory",  MSJ  3,
         no. 1, Jan 88.
               Описание  особенностей, вводимых  LIM  EMS  4.0. Пример
         программ на "C" и на языке Ассемблера демонстрируют  улучшен-
         ные  методы  сохранения экрана, разделения данных между прог-
         раммами, а также выполнения программы в расширенной памяти.
               Lefor, John A., and Karen Lund. "Reaching into Expanded
         Memory." PCTJ 5, no.5, May 86.
               Пояснение  LIM  EMS  3.2 и AQA EEMS, ориентированных на
         приложения.Законченные образцы программ для  получения  пара-
         метров расширенной памяти и дампа данных расширенной памяти.
               Lotus, Intel,Microsoft. "Lotus/Intel/Microsoft Expanded
         Memory   Specification,   Version   4.0,  "  Document  number
         300275-005, Oct 87.
               Полная спецификация последней версии спецификации  рас-
         ширенной  памяти.  Включает  образцы  программ на языке Turbo
         Pascal и на языке ассемблера.
               Mirecki, Ted. " Expandable Memory," PCTJ, no. 2, Feb 86.
               Описание LIM EMS 3.2 и AQA EEMS. Тесты продуктов расши-
         ренной памяти фирм "Интел" и " Эй-ЭС-ТИ".
               Yao, Paul. "EMS Support Improves Microsoft Windows  2.0
         Application Performance," MSJ 3, no. 1, Jan 88.
               Обсуждение  техники использования LIM EMS 4.0 в Windows
            2.0 для управления несколькими одновременными приложениями.

                                      - П-54 -


                     Приложение Г.  СПРАВОЧНИК ПО КОДАМ ASCII
                              И ПРЕОБРАЗОВАНИЯ ЧИСЕЛ



              Описания непечатаемых  символов  ASCII
              Преобразование шестнадцатиричного кода в десятичный
              Преобразование десятичного кода в шестнадцатиричный


              Таблица Г-1 является таблицей соответствия  значений  клавиш
         терминала в десятичном (основание 10), шестнадцатиричном (основа-
         ние 16), восьмиричном (основание 8), а также в коде ASCII (Амери-
         канский  стандартный код для обмена информацией).  Последователь-
         ности клавиш, включающие клавишу "Control" вводятся одновременным
         нажатием  клавиши  "Control" и указанной клавиши.  Эти последова-
         тельности основаны на тех  последовательностях,  которые  описаны
         для  большинства  стандартных  терминалов,  таких  как клавиатура
         "Diablo 1640" и серия терминалов "Televideo" и может быть описана
         иначе на других терминалах.


                                                    Таблица Г-1
                        Перекрестные ссылки в коде ASCII
         ─────────────────────────────────────────────────────────────
         Деся-  Шестнад-  Восьми- Символы   Графи-     Клавиша
         тичный цатирич-  ричный  в коде    ческие    терминала
         код    ный код   код     ASCII     символы   фирмы "ИБМ"
         ─────────────────────────────────────────────────────────────
           0     00      00        NUL                <Ctrl-@>
           1     01      01        SOH               <Ctrl-A>
           2     02      02        STX               <Ctrl-B>
           3     03      03        ETX               <Ctrl-C>
           4     04      04        EOT               <Ctrl-D>
           5     05      05        ENQ               <Ctrl-E>
           6     06      06        ACK               <Ctrl-F>
           7     07      07        BEL               <Ctrl-G>
           8     08      10        BS                <Ctrl-H>
           9     09      11        HT                        <Ctrl-I>
          10     0A      12        LF                <Ctrl-J>
          11     0B      13        VT                <Ctrl-K>
          12     0C      14        FF                <Ctrl-L>
          13     0D      15        CR
       <Ctrl-M>
          14     OE      16        SO                <Ctrl-N>
          15     0F      17        SI                <Ctrl-O>                                      <Ctrl-F>
          16     10      20        DLE               <Ctrl-P>
          17     11      21        DC1               <Ctrl-Q>
          18     12      22        DC2               <Ctrl-R>
          19     13      23        DC3               <Ctrl-S>
          20     14      24        DC4               <Ctrl-T>
          21     15      25        NAK               <Ctrl-U>
          22     16      26        SYN               <Ctrl-V>
          23     17      27        ETB               <Ctrl-W>
          24     18      30        CAN               <Ctrl-X>
          25     19      31        EM                <Ctrl-Y>

                                      - П-55 -
         ─────────────────────────────────────────────────────────────
         Деся-  Шестнад-  Восьми- Символы   Графи-     Клавиша
         тичный цатирич-  ричный  в коде    ческие    терминала
         код    ный код   код     ASCII     символы   фирмы "ИБМ"
         ─────────────────────────────────────────────────────────────
          26     1A      32        SUB               <Ctrl-Z>
          27     1B      33        ESC               <Esc>
          28     1C      34        FS                <Ctrl-\>
          29     1D      35        GS                <Ctrl-`>
          30     1E      36        RS                <Ctrl-=>
          31     1F      37        US                <Ctrl-->
          32     20      40        SP                 Пробел <Клавиша
                                                      интервалов>
          33     21      41        !         !        !(Восклицательный
                                                      знак)
          34     22      42        "         "        " (Кавычки)
          35     23      43        #         #        # (Знак числа)
          36     24      44        $         $        $ (Знак "доллар")
          37     25      45        %         %        % (Процент)
          38     26      46        &         &        & (Амперсанд)
          39     27      47        '         '        ' (Апостроф или
                                                      диакритический знак)
          40     28      50        (         (        ( (Открывающие
                                                      (круглые) скобки)
          41     29      51        )         )        ) (Закрывающие
                                                      (круглые) скобки)
          42     2A      52        *         *        * (Звездочка)
          43     2B      53        +         +        + (Плюс)
          44     2C      54        ,         ,        , (Запятая)
          45     2D      55        -         -        - (Дефис, тире
                                                      или минус)
          46     2E      56        .         .        . (Точка)
          47     2F      57        /         /        / (Косая черта)
          48     30      60        0         0        0
          49     31      61        1         1        1
          50     32      62        2         2        2
          51     33      63        3         3        3
          52     34      64        4         4        4
          53     35      65        5         5        5
          54     36      66        6         6        6
          55     37      67        7         7        7
          56     38      70        8         8        8
          57     39      71        9         9        9
          58     3A      72        :         :        : (Двоеточие)
          59     3B      73        ;         ;        ; (Точка с запятой)
          60     3C      74        <         <        < (Меньше, чем)
          61     3D      75        =         =        = (Равняется)
          62     3E      76        >         >        > (Больше, чем)
          63     3F      77        ?         ?        ? (Вопросительный
                                                      знак)
          64     40     100        @         @        @ (Коммерческий
                                                      знак at)
          65     41     101        A         A        A
          66     42     102        B         B        B
          67     43     103        C         C        C
          68     44     104        D         D        D
          69     45     105        E         E        E

                                      - П-56 -
         ─────────────────────────────────────────────────────────────
         Деся-  Шестнад-  Восьми- Символы   Графи-     Клавиша
         тичный цатирич-  ричный  в коде    ческие    терминала
         код    ный код   код     ASCII     символы   фирмы "ИБМ"
         ─────────────────────────────────────────────────────────────
          70     46     106        F         F        F
          71     47     107        G         G        G
          72     48     110        H         H        H
          73     49     111        I         I        I
          74     4A     112        J         J        J
          75     4B     113        K         K        K
          76     4C     114        L         L        L
          77     4D     115        M         M        M
          78     4E     116        N         N        N
          79     4F     117        O         O        O
          80     50     120        P         P        P
          81     51     121        Q         Q        Q
          82     52     122        R         R        R
          83     53     123        S         S        S
          84     54     124        T         T        T
          85     55     125        U         U        U
          86     56     126        V         V        V
          87     57     127        W         W        W
          88     58     130        X         X        X
          89     59     131        Y         Y        Y
          90     5A     132        Z         Z        Z
          91     5B     133        [         [        [ (Открывающая
                                                      квадратная скобка)
          92     5C     134        \         \        \ (Обратная косая
                                                      черта)
          93     5D     135        ]         ]        ] (Закрывающая
                                                      квадратная скобка)
          94     5E     136        ^         ^        ^ (Диакритический
                                                      знак)
          95     5F     137        _         _        _ (Символ подчер-
                                                      кивания)
          96     60     140        `         `        ` (Диакритический
                                                      знак)
          97     61     141        a         a        a
          98     62     142        b         b        b
          99     63     143        c         c        c
         100     64     144        d         d        d
         101     65     145        e         e        e
         102     66     146        f         f        f
         103     67     147        g         g        g
         104     68     150        h         h        h
         105     69     151        i         i        i
         106     6A     152        j         j        j
         107     6B     153        k         k        k
         108     6C     154        l         l        l
         109     6D     155        m         m        m
         110     6E     156        n         n        n
         111     6F     157        o         o        o
         112     70     160        p         p        p
         113     71     161        q         q        q
         114     72     162        r         r        r
         115     73     163        s         s        s

                                      - П-57 -
         ─────────────────────────────────────────────────────────────
         Деся-  Шестнад-  Восьми- Символы   Графи-     Клавиша
         тичный цатирич-  ричный  в коде    ческие    терминала
         код    ный код   код     ASCII     символы   фирмы "ИБМ"
         ─────────────────────────────────────────────────────────────
         116     74     164        t         t        t
         117     75     165        u         u        u
         118     76     166        v         v        v
         119     77     167        w         w        w
         120     78     170        x         x        x
         121     79     171        y         y        y
         122     7A     172        z         z        z
         123     7B     173        {         {        { (Открывающая
                                                      фигурная скобка)
         124     7C     174        |         |        | (Вертикальный
                                                      штрих (логическое
                                                      ИЛИ))
         125     7D     175        }         }        } (Закрывающая
                                                      фигурная скобка)
         126     7E     176        ~         ~        ~ (Знак "тильда")
         127     7F     177        DEL       DEL      <Del> (Удаление)
         ─────────────────────────────────────────────────────────────

                    Описания непечатаемых  символов  ASCII

              ACK (подтверждение) - управляющий символ при  передаче  дан-
         ных,  который служит в качестве обычного ответа "да" на различные
         вопросы, но также иногда указывает: "Я получил вашу последнюю пе-
         редачу и готов к вашей следующей передаче"
              BELL (звонок) - управляющий символ общего назначения активи-
         зирует  звонок,  гудок  или другой звуковой сигнал тревоги на том
         устройстве, на которое он был послан.
              BS (возврат) - управляющий символ спецификации формата пере-
         мещает каретку,  печатающую головку или курсор назад на один про-
         бел или позицию.
              CAN (отмена) - управляющий символ общего назначения,  указы-
         вающий  что информация предыдущей передачи не должна учитываться,
         причем объем этой информации определяется пользователем.
              CR (возврат каретки или возврат) - управляющий символ специ-
         фикации формата перемещает каретку, печатающую головку или курсор
         на экране терминала к началу данной строки.  В большинстве терми-
         налов клавиша Возврата вызывает и возврат каретки (CR), и перевод
         строки (LF).
              DC1-DC4 (управление устройством) - управляющий символ общего
         назначения,  которые управляют терминалом пользователя или анало-
         гичными устройствами.  Стандартные функции не  присваиваются,  за
         исключением того, что функция DC4 часто означает "останов".
              Международный консультативный комитет по телеграфии и  теле-
         фонии (CCITT) предлагает ряд возможных назначений.  Вообще, CCITT
         предпочитает использование первых двух функций по управлению уст-
         ройством для "включения",  а двух последних - для "выключения", а
         функции DC2 и DC4 имеют отношение к более важному  устройству.  В
         некоторых  системах  эти коды помечены соответственно XON,  TAPE,
         XOFF и NO TAPE.  "Х" - означает "передатчик",  а "TAPE" и "NO TA-
         PE" означают  "Включить  ленту" или "Выключить ленту".  Эти метки
         находятся в верхней части некоторых терминалов.
              DEL (удаление) - управляющий символ общего назначения удаля-
         ет символ.  Символ DEL, в некоторых терминалах называемый RUBOUT,

                                      - П-58 -
         не является строго говоря,  управляющим символом, поскольку он не
         группируется с другими управляющими символами кода ASCII.
              Функция удаления DEL имеет единицы во всех разрядах при дво-
         ичном представлении числа (1111 1111, основание 2). Причина тако-
         го представления имеет историческую основу: единственным способом
         удалить двоичный образ,  отперфорированный на бумажной ленте, был
         способ пробивки всех кодовых отверстий так,  чтобы результирующий
         образ был эквивалентен нулю.
              Код ASCII  до сих пор рассматривает функцию удаления DEL эк-
         вивалентом нуля, хотя многие операционные системы используют сим-
         вол DEL для удаления предшествующего символа.
              DLE ("авторегистр 1") - управляющий символ при передаче дан-
         ных,  который  использует  специальный тип управляющей последова-
         тельности специально для управления каналом  связи  и  средствами
         передачи.
              EM (конец носителя данных) - управляющий символ общего  наз-
         начения указывает на конец (бумажной) перфоленты (или другого но-
         сителя данных).
              ENQ (запрос) - управляющий символ при передаче данных обычно
         используется для идентификации запроса или информации  о статусе.
         В некоторых системах этот код выглядит как WRU ("Кто вы/").
              EOT (конец передачи) - управляющий символ при передаче  дан-
         ных отмечает конец передачи после одного или более сообщений.
              ESC ("авторегистр 2") - символ  общего  назначения  отмечает
         начало управляющей последовательности. Управляющая последователь-
         ность состоит из серии кодов которые в качестве группы имеют осо-
         бое назначение, обычно функции управления. В некоторых терминалах
         символ ESC называется ALT MODE.
              ETB (конец блока передачи) - управляющий символ при передаче
         данных используется при необходимости разбить  длинные  сообщения
         на блоки. Символ ETB отмечает границы блока. Блоки обычно не име-
         ют ничего общего с форматом сообщения, подлежащего передаче.
              EXT (конец  текста) - управляющий символ при передаче данных
         отмечает конец текста. См. символ SOH. Этот код первоначально на-
         зывался  ЕОМ  (конец сообщения) и может использоваться в качестве
         отметки как таковой на некоторых терминалах.
              FF (перевод страницы) - управляющий символ спецификации фор-
         мата вызывает перемещение каретки,  печатающего колесика или кур-
         сора к началу следующей страницы.
              FS,GS,RG,US (символы- разделители файлов,  групп,  записей и
         устройств)  - набор управляющих символов - разделителей,  которые
         определяют границы порций информации.  Стандарты на  употребление
         таких  символов  отсутствуют за исключением того,  что символ FS,
         как предполагается, имеет отношение к наибольшему делению, а сим-
         вол US - к наименьшему.
              HT (горизонтальная табуляция) - управляющий символ  специфи-
         кации формата который устанавливает каретку,  печатающее колесико
         или курсор на следующем заранее определенном месте той же строки.
         Пользователь  обычно  решает,  как осуществлять разметку горизон-
         тальной таблицы.
              LF (перевод строки) - управляющий символ спецификации форма-
         та перемещает каретку, печатающую головку или курсор вниз на одну
         строку.  Большинство систем объединяет возврат каретки (CR) с пе-
         реводом строки (LF).  В результате этого  объединения  получается
         новая строка, называемая NL.
              NAK (отрицательное подтверждение) - управляющий  символ  при
         передаче  данных  указывает  "нет" в ответе на различные вопросы.

                                      - П-59 -
         Иногда он описан как:  "Я получил вашу последнюю передачу,  но  в
         ней есть ошибки, и я жду повторной передачи".
              NUL (нуль) - управляющий символ общего  назначения,  который
         главным образом используется в качестве заполнителя пространства.
         См. также символ SYN.
              SI (переключение  на стандартный регистр) - управляющий сим-
         вол общего назначения,  используемый после кода SO  для  указания
         того, что коды возвращаются к обычному значению в коде ASCII.
              SO (переключение на дополнительный  регистр)  -  управляющий
         символ  общего назначения указывает на следующие двоичные образы,
         значения которых выходят за рамки  стандартного  набора  символов
         кода ASCII и будет продолжать указывать до тех пор, пока не будет
         введен символ переключения на стандартный регистр.
              SOH (начало  заголовка)  -  управляющий  символ при передаче
         данных отмечает начало заголовков,  если они используются в сооб-
         щениях  наряду  с  текстом.  В Заголовках обычно сообщается имя и
         ячейка с адресом.  Этот код первоначально назывался  SOM  (начало
         сообщения).
              STX (начало текста) - управляющий символ при  передаче  дан-
         ных,  используемый в качестве отметки начала текста и конца заго-
         ловка (если используется).  Этот код первоначально назывался  ЕОА
         (конец адреса).
              SUB (замена) - управляющий символ общего назначения,  указы-
         вающий на символ,  который должен занять место неправильного сим-
         вола.
              SYN (синхронизация)  -  управляющий символ при передаче дан-
         ных, используемый некоторыми быстродействующими системами переда-
         чи  данных,  которые используют синхронизированные часы на концах
         приемника и передатчика. В периоды простоя, когда отсутствие дво-
         ичных  образов  не  позволяет часам на приемном конце отслеживать
         часы передатчика,  приемник может нарушать синхронизацию.  Каждая
         передача,  следующая за период простоя,  поэтому заменяются тремя
         или четырьмя символами синхронизации SYN.  Код SYN имеет двоичный
         образ,  который  позволяет приемнику не только запирать (блокиро-
         вать) часы передатчика,  но также определять точки начала и конца
         каждого символа.  Символы синхронизации SYN могут кроме того, ис-
         пользоваться для заполнения коротких периодов простоя с тем чтобы
         поддерживать синхронизацию, отсюда и данное название.
              VT (вертикальная таблица) - управляющий символ  спецификации
         формата,  который подводит каретку, печатающую головку или курсор
         к следующему заранее определенному ограничителю  (обычно строке).

              Преобразование шестнадцатиричного кода в десятичный
              На рисунке Г-1 показано, как  шестнадцатиричное  число
         5F9D преобразуется в его десятичный эквивалент.
         5 F 9 D  Шестнадцатиричный
         │ │ │ │
         │ │ │ └─> Dh=13d ─────> 13d x    1d =    13d
         │ │ │
         │ │ └───> 9h=9d  ─────>  9d x   16d =   144d
         │ │
         │ └─────> Fh=15d ─────> 15d x  256d =  3840d
         │
         └───────> 5h=5d  ─────>  5d x 4096d = 20480d
                                              ________
                                               24477  Десятичный
              Рис. Г-1 . Преобразование шестнадцатиричного числа 5F9D
         в его десятичный эквивалент

                                      - П-60 -


              Каждая  шестнадцатиричная  цифра  всегда в 16 раз больше
         ближайшей цифры справа.

         24477 Десятичный                    5 F 9 D Шестнадцатиричный
                                             │ │ │ │
         24477  4096=5  ─────>   5d = 5h ────┘ │ │ │
         Остаток = 3997                        │ │ │
                                               │ │ │
         3997  256=15   ─────>  15d = Fh ──────┘ │ │
         Остаток = 157                           │ │
                                                 │ │
         157  1=9       ─────>   9d = 9h ────────┘ │
         Остаток = 13                              │
                                                   │
         13  1=13       ─────> 13d  = Dh ──────────┘

              Рис. Г-2. Десятичное число 24477, преобразованное  об-
         ратно в его шестнадцатиричный эквивалент


                Преобразование десятичного кода в шестнадцатиричный
                ───────────────────────────────────────────────────

              Процесс преобразования  меняется при преобразовании десятич-
         ных чисел в шестнадцатиричные числа.  Процесс начинается с выбора
         самого  старшего разряда и определения его порядка в данном числе
         (тысячи,  сотни и т.д.).  Далее десятичное число делится на шест-
         надцатиричное значение - первой относительной позиции цифры.  Ес-
         ли, к примеру, первая цифра располагается в позиции тысяч, то де-
         лим  на  4096  (шестнадцатиричный  эквивалент  десятичного  числа
         1000). Результатом будет первая шестнадцатиричная цифра.
              Остаток делится  на шестнадцатиричное значение следующей от-
         носительной позиции цифры (т.е.  делим цифру в разряде  сотен  на
         256,  поскольку 256 является шестнадцатиричным эквивалентом деся-
         тичного числа 100).
              На рисунке Г-2 показано,  как десятичное число, полученное в
         предыдущем примере, превращается обратно в шестнадцатиричное чис-
         ло.



                                      - П-61 -
                                                     Таблица Г-2
                Расширенные перекрестные ссылки фирмы "ИБМ"
         ─────────────────────────────────────────────────────────────
         Двоичный Восьмиричный Десятичный  Шестнад-  Расширенный набор
         код      код          код         цатирич-  символов в коде
                                             код           ASCII*
         ─────────────────────────────────────────────────────────────
         1000 0000     200      128        80
         1000 0001     201      129        81
         1000 0010     202      130        82
         1000 0011     203      131        83
         1000 0100     204      132        84
         1000 0101     205      133        85
         1000 0110     206      134        86
         1000 0111     207      135        87
         1000 1000     210      136        88
         1000 1001     211      137        89
         1000 1010     212      138        8A
         1000 1011     213      139        8B
         1000 1100     214      140        8C
         1000 1101     215      141        8D
         1000 1110     216      142        8E
         1000 1111     217      143        8F
         1001 0000     220      144        90
         1001 0001     221      145        91
         1001 0010     222      146        92
         1001 0011     223      147        93
         1001 0100     224      148        94
         1001 0101     225      149        95
         1001 0110     226      150        96
         1001 0111     227      151        97
         1001 1000     230      152        98
         1001 1001     231      153        99
         1001 1010     232      154        9A
         1001 1011     233      155        9B
         1001 1100     234      156        9C
         1001 1101     235      157        9D
         1001 1110     236      158        9E
         1001 1111     237      159        9F
         1010 0000     240      160        A0
         1010 0001     241      161        A1
  >      1010 0010     242      162        A2
         1010 0011     243      163        A3
         1010 0100     244      164        A4
         1010 0101     245      165        A5
         1010 0110     246      166        A6
         1010 0111     247      167        A7
         1010 1000     250      168        A8
         1010 1001     251      169        A9              ┌
         1010 1010     252      170        AA              ┐
         1010 1011     253      171        AB
         1010 1100     254      172        AC
         1010 1101     255      173        AD
         1010 1110     256      174        AE
         1010 1111     257      175        AF
         1011 0000     260      176        B0              ░
         1011 0001     261      177        B1              ▒
         1011 0010     262      178        B2              ▓
         1011 0011     263      179        B3              │

                                      - П-62 -
         ─────────────────────────────────────────────────────────────
         Двоичный Восьмиричный Десятичный  Шестнад-  Расширенный набор
         код      код          код         цатирич-  символов в коде
                                             код           ASCII*
         ─────────────────────────────────────────────────────────────
         1011 0100     264      180        B4              ┤
         1011 0101     265      181        B5              ╡
         1011 0110     266      182        B6              ╢
         1011 0111     267      183        B7              ╖
         1011 1000     270      184        B8              ╕
         1011 1001     271      185        B9              ╣
         1011 1010     272      186        BA              ║
         1011 1011     273      187        BB              ╗
         1011 1100     274      188        BC              ╝
         1011 1101     275      189        BD              ╜
         1011 1110     276      190        BE              ╛
         1011 1111     277      191        BF              ┐
         1100 0000     300      192        C0              └
         1100 0001     301      193        C1              ┴
         1100 0010     302      194        C2              ┬
         1100 0011     303      195        C3              ├
         1100 0100     304      196        C4              ─
         1100 0101     305      197        C5              ┼
         1100 0110     306      198        C6              ╞
         1100 0111     307      199        C7              ╟
         1100 1000     310      200        C8              ╚
         1100 1001     311      201        C9              ╔
         1100 1010     312      202        CA              ╩
         1100 1011     313      203        CB              ╦
         1100 1100     314      204        CC              ╠
         1100 1101     315      205        CD              ═
         1100 1110     316      206        CE              ╬
         1100 1111     317      207        CF              ╧
         1101 0000     320      208        D0              ╨
         1101 0001     321      209        D1              ╤
         1101 0010     322      210        D2              ╥
         1101 0011     323      211        D3              ╙
         1101 0100     324      212        D4              ╘
         1101 0101     325      213        D5              ╒
         1101 0110     326      214        D6              ╓
         1101 0111     327      215        D7              ╫
         1101 1000     330      216        D8              ╪
         1101 1001     331      217        D9              ┘
         1101 1010     332      218        DA              ┌
         1101 1011     333      219        DB              █
         1101 1100     334      220        DC              ▄
         1101 1101     335      221        DD              ▌
         1101 1110     336      222        DE              ▐
         1101 1111     337      223        DF              ▀
         1110 0000     340      224        E0
         1110 0001     341      225        E1
         1110 0010     342      226        E2
         1110 0011     343      227        E3
         1110 0100     344      228        E4
         1110 0101     345      229        E5
         1110 0110     346      230        E6
         1110 0111     347      231        E7

                                      - П-63 -
         ─────────────────────────────────────────────────────────────
         Двоичный Восьмиричный Десятичный  Шестнад-  Расширенный набор
         код      код          код         цатирич-  символов в коде
                                             код           ASCII*
         ─────────────────────────────────────────────────────────────
         1110 1000     350      232        E8
         1110 1001     351      233        E9
         1110 1010     352      234        EA
         1110 1011     353      235        EB
         1110 1100     354      236        EC
         1110 1101     355      237        ED
         1110 1110     356      238        EE
         1110 1111     357      239        EF
         1111 0000     360      240        F0               Ё
         1111 0001     361      241        F1               ё
         1111 0010     362      242        F2               Є
         1111 0011     363      243        F3               є
         1111 0100     364      244        F4               Ї
         1111 0101     365      245        F5               ї
         1111 0110     366      246        F6               Ў
         1111 0111     367      247        F7               ў
         1111 1000     370      248        F8               °
         1111 1001     371      249        F9               ∙
         1111 1010     372      250        FA               ·
         1111 1011     373      251        FB               √
         1111 1100     374      252        FC               №
         1111 1101     375      253        FD               ¤
         1111 1110     376      254        FE               ■
         1111 1111     377      255        FF           (пробел)
         ______________________________________________________________
          * Символы,  отсутствующие в данной графе, не могут быть выве-
            дены на экран при работе с клавиатурой данного типа.

         ** Эти последовательности клавиш, состоящие из "<Ctrl->"  на-
            бираются путем нажатия клавиши Ctrl, и не отпуская ее, на-
            жать указанную клавишу. Эти последовательности основаны на
            последовательностях,  описанных для кода клавиатуры персо-
            нальных компьютеров IBM PC. Для других клавиатур эти  пос-
            ледовательности могут быть описаны иначе.
                 Символы расширенного набора кода  ASCII  фирмы  "ИБМ"
            можно отображать путем нажатия клавиши <Alt> и далее ввода
            десятичного кода символа на вспомогательной клавиатуре.

                    Сокращения (аббревиатура):
              DEC = десятичный (основание 10)
              HEX = шестнадцатиричный (основание 16)
              OCT = восьмиричный (основание 8)
              ASCII = Американский стандартный код для обмена информа-
                      цией


                                      - П-64 -


              Приложение Д. СТРУКТУРЫ ОПЕРАЦИОННОЙ СИСТЕМЫ MS-DOS

         Структура каталога
         ──────────────────
         Запись "время"     Часы:5, Минуты:6, Секунды:5
                     ; F E D C B A 9 8 7 6 5 4 3 2 1 0
                     ; │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
                     ; │ │ │ │ │ │ │ │ │ │ │ └─┴─┴─┴─┴── Секунды/2
                     ; │ │ │ │ │ └─┴─┴─┴─┴─┴──────────── Минуты
                     ; └─┴─┴─┴─┴──────────────────────── Часы


         Запись "дата"     Год:7,Mесяц:4, День:5
                     ; F E D C B A 9 8 7 6 5 4 3 2 1 0
                     ; │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
                     ; │ │ │ │ │ │ │ │ │ │ │ └─┴─┴─┴─┴── Дни 1 -31
                     ; │ │ │ │ │ │ │ └─┴─┴─┴──────────── Mесяцы 1-12
                     ; └─┴─┴─┴─┴─┴─┴──────────────────── Год + 1980

         dir      STRUC
         dir_stat   db    1 dup (?)       ; фактически первый символ
                                          ; имени файла или:
                            ; 00h = имя файла, никогда не используемое
                            ; 05h = первый символ-это действительно Е5h
                            ; E5h = файл был уничтожен
                            ; 2Eh = файл является подкаталогом
         dir_name   db    7 dup (?)   ; остальные символы имени файла
         dir_ext    db    3 dup (?)   ; расширение
         dir_attr   db    1 dup (?)   ; атрибуты:
                             ; 7 6 5 4 3 2 1 0
                             ; │ │ │ │ │ │ │ │
                             ; │ │ │ │ │ │ │ └── Только считывание
                             ; │ │ │ │ │ │ └──── Невидимый (скрытый)
                             ; │ │ │ │ │ └────── Система
                             ; │ │ │ │ └──────── Метка тома
                             ; │ │ │ └────────── Подкаталог
                             ; │ │ └──────────── Архив
                             ; └─┴────────────── Не используемый


         dir_resv   db   10 dup (?)       ; зарезервирован
         dir_time   Time < >              ; отметка времени (2 байта)
         dir_date   Date < >              ; отметка даты (2 байта)
         dir_first  db    2 dup (?)       ; количество файлов в
                                          ; начальном кластере
         dir_size   db    4 dup (?)       ; размер файла в байтах (1-ое
                                          ; слово имеет  размер меньшего
                                          ; порядка)
         dir      ENDS



            Блок параметров базовой системы ввода-вывода BIOS (BPB)

         bpb       STRUC      ; Смещение -  Описание
         bpb_sec_size    dw ? ;  0 -- количество байтов в секторе

                                      - П-65 -
         bpb_clust_sec   db ? ;  2 -- количество  секторов в кластере
         bpb_resv_sec    dw ? ;  3 -- количество зарезервированных
                              ;       секторов
         bpb_fats        db ? ;  5 -- количество  FAT-таблиц (копий)
         bpb_dir_ents    dw ? ;  6 -- количество элементов корневого
                              ;       каталога
         bpb_secs        dw ? ;  8 -- общее количество секторов
         bpb_media       db ? ; 10 -- байт описателя носителя;
         bpb_fat_secs    dw ? ; 11 -- количество секторов в
                              ;       FAT-таблице
         bpb       ENDS


         Формат управляющего блока файла (FСВ)
         Запись "дата"     Год:7,Mесяц:4, День:5

         fcb      STRUC                   ; Основная часть FСВ
                                          ; Смещение  - Описание
         fcb_drive       db   1  dup (0)  ;  0 -- номер дисковода (0 =
                                          ;       до открытия дисковод
                                          ;       по умолчанию)
         fcb_name        db   8  dup (" ");  1 -- имя файла или имя
                                          ;       устройства;
         left-                            ;       выровнено по левому
                                          ;       полю без двоеточия
         fcb_ext         db   3  dup (" ");  9 -- расширение файла; вы-
                                          ;       равнено по левому краю
         fcb_cur_blk     dw   ?           ; 12 -- текущий блок относи-
                                          ;       тельно начала файла
         fcb_rec_size    dw   80h         ; 14 -- размер логической
                                          ;       записи в  байтах
         fcb_filsiz_lo   dw   0           ; 16 -- размер файла в байтах:
                                          ;       слово имеет размер
                                          ;       меньшего порядка
         fcb_filsiz_hi   dw   0           ; 18 -- слово имеет размер
                                          ;       большего порядка
         fcb_date        Date <>          ; 20 -- файл "дата" был создан
                                          ;       или  последним
                                          ;       обновлен (см. струк-
                                          ;       туру каталога)
         fcb_resv1       db   10  dup (?) ; 22 -- зарезервирован
         fcb_curr_rec    db   ?           ; 32 -- текущая относительная
                                          ;       запись внутри текущего
                                          ;       блока
         fcb_rndm_rec_l  dw   ?           ; 33 -- относительная запись
                                          ;       от начала файла; слово
                                          ;       имеет размер меньшего
                                          ;       порядка
         fcb_rndm_rec_h  dw   ?           ; 35 -- относительная запись
                                          ;       от начала файла; слово
                                          ;       имеет размер большего
                                          ;       порядка
         fcb       ENDS                   ;
         fcb_exten STRUC                  ; Расширенная часть FCB
                                          ; Смещение  - Описание
         fcb_ext_flag    db   0FFh        ; -7 --  признак (флажок),
                                          ;        содержащий FFh,

                                      - П-66 -
                                          ;        указывает на расши-
                                          ;        ренный FCB
         fcb_resv2       db   5  dup  (0) ; -6 -- зарезервирован
         fcb_attr        db   ?           ; -1 -- атрибуты (см. структу-
                                          ;       ру каталога)
         fcb_struc       FCB  <>          ;  0 -- ссылки на основную
                                          ;       структуру FCB
         fcb_exten ENDS


         Формат сегмента префикса программы (PSP)

         psp      STRUC                   ; Смещение  - Описание
         psp_int20       db   0CDh,020h   ;  0 -- команда по обработке
                                          ;       прерывания "int 20h"
         psp_top         dw   ?           ;  2 -- вершина памяти в виде
                                          ;       параграфа
         psp_reserv1     db   6  dup  (?) ;  4 -- зарезервирован
         psp_termIP      dw   ?           ; 10 -- адрес IP завершения
         psp_termCS      dw   ?           ; 12 -- адрес CS - завершения
         psp_ctlbrkIP    dw   ?           ; 14 -- адрес IP выхода
                                          ;       Ctrl-Break
         psp_ctlbrkCS    dw   ?           ; 16 -- адрес CS выхода
                                          ;       Ctrl-Break
         psp_critIP      dw   ?           ; 18 -- критическая ошибка в
                                          ;       адресе IP выхода
         psp_critCS      dw   ?           ; 20 -- критическая ошибка в
                                          ;       адресе CS выхода
         psp_reserv2     db  22  dup  (?) ; 22 -- зарезервирован
         psp_environ     dw   ?           ; 44 -- адрес сегмента
                                          ;       окружения
         psp_reserv3     db  34  dup  (?) ; 46 -- зарезервирован
         psp_dos         db   0CDh,021h   ; 80 -- вызов функции по об-
                                          ;       работке функции 21h
                                          ;       о.с. MS-DOS
         psp_reserv4     db  10  dup  (?) ; 82 -- зарезервирован
         psp_fcb1        db  16  dup  (?) ; 92 -- неоткрытый стандартный
                                          ;       управляющий блок
                                          ;       файла FCB1
         psp_fcb2        db  20  dup  (?) ;108 -- неоткрытый стандартный
                                          ;       управляющий блок
                                          ;       файла FCB2
         psp_parmlen     db   ?           ;128 -- количество символов в
                                          ;       списке параметров
         psp_parms       db 127  dup  (?) ;129 -- параметры команды
         psp       ENDS



              Ниже в сжатой форме представлена информация по кодам ошибок,
         важным прерываниям, всем функциям по обработке прерываний "int 21
         h" и всем функциям по обработке прерываний "int 67h" (EMS).


                       Заранее определенные описатели  файла
                       -------------------------------------
         0 = Стандартное устройство ввода (может быть переназначено)

                                      - П-67 -
         1 = Стандартное устройство вывода (может быть переназначено)
         2 = Стандартное устройство вывода ошибок (может быть
             переназначено)
         3 = Стандартное внешнее дополнительное устройство
         4 = Стандартное устройство печати

                                   Коды возврата
                                   -------------
              Из приведенного  ниже  списка кодов ошибок только коды с 01h
         по 12h возвращаются в регистр AX по завершении обработки прерыва-
         ний "int 21h" или "int 24h" .  Остальные коды ошибок получаются в
         результате вызова функции "Получить расширенную  ошибку" (функция
         59h по обработке прерывания "int 21h").


           Коды ошибок операционной системы MS-DOS версий с 2.00 по 4.0
           ------------------------------------------------------------
              01h = Ошибочный номер функции
              02h = Файл не найден
              03h = Путь не найден
              04h = Слишком много открытых файлов (нет описателей слева)
              05h = Отказ в доступе
              06h = Недопустимый (ошибочный описатель)
              07h = Разрушенные управляющие блоки памяти
              08h = Недостаточно памяти
              09h = Ошибочный адрес блока памяти
              0Ah = Недопустимое окружение
              0Bh = Недопустимый формат
              0Ch = Ошибочный код доступа
              0Dh = Ошибочные данные
              0Eh = Зарезервирован
              0Fh = Был указан недопустимый дисковод
              10h = Попытка удалить текущий каталог
              11h = Не то устройство
              12h = Больше нет файлов
              13h = Попытка записи на дискету, имеющую защиту от записи
              14h = Неизвестное устройство
              15h = Дисковод не готов
              16h = Неизвестная команда
              17h = Ошибка контроля с циклическим избыточным кодом
                    (CRC)
              18h = Неправильная длина структуры запроса
              19h = Ошибка поиска
              1Ah = Неизвестный тип носителя
              1Bh = Сектор не найден
              1Ch = Вывод на бумажный носитель
              1Dh = Сбой при записи
              1Eh = Сбой при считывании
              1Fh = Общий сбой


            Коды ошибок операционной системы MS-DOS версий с 3.0 по 4.0
            -----------------------------------------------------------
              20h =  Нарушение совместного пользования
              21h =  Нарушение блокировки
              22h =  Ошибочная смена диска
              23h =  Недоступный блок управления файлом (FCB)

                                      - П-68 -
              24h  = Переполнение  буфера  совместного  использования
                     (операционная система MS-DOS версии 3.3, 4.0)
              25h - 41h = (Зарезервированы)
              42h - 58h = (см. коды ошибок операционной системы MS-DOS
                          версий с 3.1 по 4.0)
              59h - 5Fh = (Зарезервированы)
              60h = Файл существует
              61h = (Зарезервирован)
              62h = Не может выполнить функцию
              63h = Сбой при обработке прерывания "int21h"
              64h - 68h = (см.коды ошибок операционной системы MS-DOS
                          версий с 3.3 по 4.0)


            Коды ошибок операционной системы MS-DOS версий с 3.1 по 4.0
            -----------------------------------------------------------
              42h = Запрос к сети не поддерживается
              43h = Удаленная ЭВМ не приведена в списке
              44h = Повторное имя в сети
              45h = Имя в сети не найдено
              46h = Сеть занята
              47h = Устройство сети больше не существует
              48h = Превышение границы командой NETBIOS
              48h = Аппаратная ошибка адаптера сети
              4Ah = Некорректный ответ, поступивший от сети
              4Bh = Не ожидаемая ошибки сети
              4Ch = Несовместимый удаленный адаптер
              4Dh = Очередь файлов, ожидающих печати, переполнена
              4Eh = Очередь файлов, ожидающих печати, не переполнена
              4Fh = Недостаточно пространства для распечатки файлов
              50h = Имя файла было уничтожено
              51h = Отказ в доступе
              52h = Некорректный тип устройства сети
              53h = Имя в сети не найдено
              54h = Имя в сети превысило границу
              55h = Сеанс команды NETBIOS превысил границу
              56h = Временная пауза
              57h = Запрос к сети не принят
              58h = Пауза в переназначении устройства печати/диска
              59h - 5Fh = (Зарезервированы)
              60h = Файл существует
              61h = Зарезервированы
              62h = Не может выполнить
              63h = Сбой при обработке прерывания "int 24"

             Коды ошибок операционной системы MS-DOS версий с 3.3, 4.0
            ----------------------------------------------------------
              64h = Отсутствие структур
              65h = Уже назначено
              66h = Ошибочный пароль
              67h = Недопустимый параметр
              68h = Сбой при записи в сети


                                      - П-69 -
              ┌────────────────────────────────────────────┐
              │               Классы ошибок                │
              ├────────────────────────────────────────────┤
              │   01h = Отсутствие ресурса                 │
              │   02h = Временная ситуация                 │
              │   03h = Авторизация (санкционирование)     │
              │   04h = Внутренний                         │
              │   05h = Отказ аппаратуры                   │
              │   06h = Системный сбой                     │
              │   07h = Ошибка в прикладной программе      │
              │   08h = Не найден                          │
              │   09h = Неправильный формат                │
              │   0Ah = Заблокировано                      │
              │   0Bh = Сбой носителя                      │
              │   0Ch = Уже существует                     │
              │   0Dh = Неизвестный                        │
              └────────────────────────────────────────────┘

              ┌────────────────────────────────────────────┐
              │     Коды, определяющие действия            │
              ├────────────────────────────────────────────┤
              │   01h = Повторить                          │
              │   02h = Задержать повторение               │
              │   03h = Повторный ввод                     │
              │   04h = Аварийное завершение               │
              │   05h = Непосредственный выход             │
              │   06h = Игнорировать                       │
              │   07h = Вмешательство пользователя         │
              └────────────────────────────────────────────┘

              ┌────────────────────────────────────────────┐
              │        Местоположение                      │
              ├────────────────────────────────────────────┤
              │   01h = Неизвестное                        │
              │   02h = Устройство блока (на диске)        │
              │   03h = Зарезервировано                    │
              │   04h = Последовательное устройство        │
              │   05h = Память                             │
              └────────────────────────────────────────────┘

                      Прерывания операционной системы MS-DOS
                      ──────────────────────────────────────
              Примечание:  При  описании  ниже прерываний операционной
                           системы MS-DOS числа в  квадратных  скобках
                           указывают  номер версии операционной системы
                           MS-DOS

               Прерывание 20h - Завершить программу [1] [2] [3] [4]
               ────────────────────────────────────────────────────
              Вход: CS = адрес сегмента PSP программы
              Возврат : Нет

                     Прерывание 21h - Запрос на вызов функции
                     ────────────────────────────────────────
              Примечание: Если не указано особо проверить все функции с
                          помощью  комбинации  клавиш  "Ctrl-Break"  и
                          "Ctrl-C";  если  используется,   выполняется

                                      - П-70 -
                          прерывание "int 23h"
                  AH = 00h - Завершить программу [1] [2] [3] [4]
                  ──────────────────────────────────────────────
              Вход: CS = адрес сегмента PSP программы
              Возврат : Нет
              Примечание:  Все буферы файла заполнены: файлы открывае-
                           мые с помощью  блоков  управления  файлами,
                           могут потерять данные, если не будут забла-
                           говременно  закрыты.  Отдается предпочтение
                           функции 4Ch


             AH = 01h - Ввести символ с консоли с эхом [1] [2] [3] [4]
             ─────────────────────────────────────────────────────────
              Вход: нет
              Возврат : Если AL>0 при первом вызове, AL =  стандартный
                        символ в коде ASCII
                        Если AL=0 при первом вызове, второй раз вызвать
                        функцию 01h с целью получения расширенного сим-
                        вола кода ASCII в регистре AL


                AH = 02h - Ввести символ на консоль [1] [2] [3] [4]
                ───────────────────────────────────────────────────
              Вход  : DL = символ для записи в первый последовательный
                           порт [1] или в STDAUX [2] [3] [4]
              Возврат : Нет

                AH = 03h - Ввести символ со вспомогательного порта
                ──────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход: нет
              Возврат: AL =  символ с первого последовательного порта
                             [1] или в STDAUX [2] [3] [4]
              Примечание: Ввод не буферизован или  управляется  с  по-
                          мощью прерывания. Состояние последовательно-
                          го порта не проверяется (см. прерывание "int
                          14h" при выполнении команды ROM-BIOS


                 AH = 04h - Вывести символ на вспомогательный порт
                ──────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход  : DL = символ для вывода на  STDAUX
              Возврат : Нет
              Примечание: Состояние последовательного  порта не
                          проверяется


                AH = 05h - Вывести символ на печатающее устройство
                ──────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход  : DL = символ для вывода на  STDPRN

                                      - П-71 -
              Возврат : Нет


            AH = 06h - Назначить консольный ввод/вывод [1] [2] [3] [4]
            ──────────────────────────────────────────────────────────
              Вход : Если DL > 0FFh, вывести символ в регистре  DL  на
                     STDOUT;  в  противном случае выполнить прямой
                     консольный ввод
              Возврат : Отсутствует из-за назначения вывода на консоль
                        Для назначения ввода с консоли: ZF =  1,  если
                        символ отсутствует , кроме того AL = символ
              Примечание: Расширенным кодам ASCII требуется два вызова.


               AH = 07h - Назначить консольный ввод символа без эха
               ─────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : нет
              Возврат : AL = символ от STDIN
              Примечание: Функции 07h и 08h  требуют двух вызовов для
                        расширенных кодов ASCII.


               AH = 08h - Назначить консольный ввод символа без эха
               ─────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : нет
              Возврат : AL = символ от STDIN


               AH = 09h - Вывести строку на консоль [1] [2] [3] [4]
               ────────────────────────────────────────────────────
              Вход:  DS : DS = Указатель на строку, заканчивающуюся
                               символом "$"
              Возврат : нет


             AH = 0Ah - Ввести буферизованную строку с консоли с эхом
             ────────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход: DS : DХ = указатель на буфер строки. Структура бу-
                              фера:
            buf_count  db ?          ; количество байтов в буфере
            ret_count  db ?          ; количество  возвращенных байтов
            ret_char_str db x DUP (?) ; возвращенные символы

              Возврат : нет


              AH = 0Bh - Проверить состояние стандартного устройства
              ──────────────────────────────────────────────────────
                               ввода [1] [2] [3] [4]
                               ─────────────────────
              Вход : нет

                                      - П-72 -
              Возврат : AL = 0FFh, если имеется символ от STDIN;
                        AL <> FFh, если символ отсутствует


              AH = 0Ch - Очистить буфер клавиатуры и вызвать функцию
              ──────────────────────────────────────────────────────
                       работы с клавиатурой [1] [2] [3] [4]
                       ────────────────────────────────────
              Вход :  AL  =  номер  функции  по  обработке  прерывания
                             "int 21h"  (01h;  06h; 07h; 08h или 0Ah ).
                      Другие регистры определены функцией в регистре AL
              Возврат : AL = символ (если только не была вызвана функ-
                             ция 0Ah). Другие регистры описаны функци-
                             ей в регистре AL на входе


               AH = 0Dh - Сброс/переустановка диска [1] [2] [3] [4]
               ────────────────────────────────────────────────────
              Вход :    нет
              Возврат : нет
              Примечание: Заполнение всех  буферов  файлов  не  должно
                          привести к закрытию файлов

                      AH = 0Eh - Выбрать диск [1] [2] [3] [4]
                      ───────────────────────────────────────
              Вход :   DL = номер дисковода (0 = А:, ..., 26 = Z:)
              Возврат: AL = номер логических дисков (0 = A:, ...,
                       26 = Z:)
              Примечание:  В  операционной системе MS-DOS версий 3 и 4
                           сообщается минимум о пяти логических дисках,
                           если  только  не   подавляются   установкой
                           LASTDRIVE  в файле CONFIG.SYS


            AH  =  0Fh - Открыть файл с помощью блока управления файлом
            ───────────────────────────────────────────────────────────
                               (FCB) [1] [2] [3] [4]
                               ─────────────────────
              Вход:  DS : DХ = Указатель на неоткрытый FCB
              Возврат:  AL  =  00h, если файл был открыт успешно; AL =
                        = 0FFh, если не успешно


           AH  =  10h - Закрыть файл с помощью блока FCB [1] [2] [3] [4]
           ─────────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый блок FCB
              Возврат:  AL  =  00h, если файл был закрыт успешно; AL =
                        = 0FFh, если не успешно


              AH  =  11h - Поиск первой записи в FCB [1] [2] [3] [4]
              ───────────────────────────────────────────────────────

              Вход: DS : DХ = указатель на неоткрытый FCB
              Возврат:  AL  =  00h, если совпадение обнаружено; AL =
                        = 0FFh, если не обнаружено


                                      - П-73 -
             AH  =  12h - Поиск следующей записи в FCB [1] [2] [3] [4]
             ─────────────────────────────────────────────────────────
              Вход:  DS  : DХ = указатель FCB, возвращенный предыдущим
                     вызовом функций первого или следующего поиска.
              Возврат:  AL  =  00h, если совпадение обнаружено; AL =
                        = 0FFh, если не обнаружено


                AH  =  13h - Удалить через FCB файл [1] [2] [3] [4]
                ───────────────────────────────────────────────────
              Вход: DS : DХ = указатель на неоткрытый FCB
              Возврат:  AL  =  00h, если файл был удален; AL = 0FFh,
                        если не был удален


             AH  =  14h - Последовательно считать  FCB [1] [2] [3] [4]
             ─────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
              Возврат: AL = нормально/сбой
                            00h = считывание завершилось успешно;
                            01h = считывание не проводилось: уже в
                                  конце файла
                            02h = считывание отменено; DTA слишком мала
                            03h = выполнено частичное  считывание; те-
                                  перь - в конце файла


             AH  =  15h - Последовательная запись  FCB [1] [2] [3] [4]
            ──────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
              Возврат: AL = нормально/сбой
                            00h = запись была успешно выполнена;
                            01h = попытка записи не проводилось:
                                  носитель переполнен
                            02h = запись отменена; DTA слишком мала

                AH  =  16h - Создать файл через FCB [1] [2] [3] [4]
               ────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на неоткрытый FCB
              Возврат:  AL  =  00h, если файл был создан; AL = 0FFh,
                        если не был создан


             AH  =  17h - Переименовать файл через FCB [1] [2] [3] [4]
             ─────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на модифицированный FCB (новое
                    имя начинается в поле чисел текущего блока)
              Возврат:  AL  =  00h, если файл был переименован; AL =
                        = 0FFh, если не был переименован


                AH  =  19h - Получить текущий диск [1] [2] [3] [4]
                ───────────────────────────────────────────────────
              Вход : нет
              Возврат : AL = номер текущего дисковода (0 = A:, ...,
                        25 = Z:)


                                      - П-74 -

          AH  =  1Ah - Установить адрес передачи на  диск [1] [2] [3] [4]
          ───────────────────────────────────────────────────────────────
              Вход : DS = DХ указатель на новый адрес передачи на диск
                     (DTA)
              Возврат : нет


              AH  =  1Bh - Получить информацию таблицы распределения
              ──────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : нет
              Возврат  :  DS  : BX = указатель на байт содержащий байт
                          идентификатора таблицы размещения файлов
                          (FAT) для  дисковода  по умолчанию
                          DX = количество кластеров
                          AL = количество секторов в кластере
                          CX = количество байтов в секторе


              AH  =  1Ch - Получить информацию таблицы распределения
              ──────────────────────────────────────────────────────
                     для указанного устройства [1] [2] [3] [4]
                    ──────────────────────────────────────────
              Вход : DL = номер дисковода (0 = A:, ... 26 = Z:)
              Возврат  :  DS  : BX = указатель на байт содержащий байт
                          идентификатора таблицы размещения файлов
                          (FAT) для  дисковода  по умолчанию
                          DX = количество кластеров
                          AL = количество секторов в кластере
                          CX = количество байтов в секторе


            AH  =  21h - Произвольное считывание файла [1] [2] [3] [4]
            ──────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
              Возврат: AL = состояние возврата
                            00h = считывание было успешным;
                            01h = конец файла; нет данных для считыва-
                                  ния
                            02h = DTA слишком мала
                            03h = конец  файла; частичное считывание
                                    записи


              AH  =  22h - Произвольная запись в файл [1] [2] [3] [4]
              ───────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
              Возврат: AL = состояние возврата
                            00h = запись была успешной;
                            01h = попытка записи не удалась;
                                  носитель переполнен
                            02h = запись отменена; DTA слишком мал



                                      - П-75 -
                AH  =  23h - Получить размер файла [1] [2] [3] [4]
                ───────────────────────────────────────────────────
              Вход : DS : DХ = указатель на неоткрытый FCB
              Возврат : Если AL = 00h , произвольное поле записи FCB =
                        записи в файле.
                        Если AL = 0FFh, файл не найден


         AH  =  24h - Установить поле относительной записи [1] [2] [3] [4]
         ─────────────────────────────────────────────────────────────────
              Вход : DS : DХ = указатель на открытый FCB
              Возврат : нет


             AH  =  25h - Установить вектор прерывания [1] [2] [3] [4]
             ─────────────────────────────────────────────────────────
              Вход : AL = номер прерывания для установки
                     DS : DХ = указатель на стандартную программу  об-
                     работки нового прерывания
              Возврат : нет


             AH  =  26h - Создать новый сегмент  префикса программы PSP
             ─────────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : DХ : 0 = указатель на новую область PSP
              Возврат : нет


           AH  =  27h - Считать произвольный блок файла [1] [2] [3] [4]
           ────────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
                    CX = количество записей для считывания
              Возврат : AL = состояние возврата:
                             00 = считывание было успешным
                             01 = конец файла; нет данных для
                                  считывания
                             02 = DTA слишком мала
                             03 = конец файла; частичное считывание
                                  записи
                        CX = фактическое количество считанных записей


           AH  =  28h - Запись в произвольный блок файла [1] [2] [3] [4]
           ─────────────────────────────────────────────────────────────
              Вход: DS : DХ = указатель на открытый FCB
                    CX = количество записей, подлежащих записи
              Возврат : AL = состояние возврата:
                             00h = запись была успешной
                             01h = попытка записи не удалась;
                                   носитель переполнен
                             02h = запись отменена; DTA слишком мала
                        CX = фактическое количество записанных записей



                                      - П-76 -
            AH  =  29h - Проанализировать имя файла FCB [1] [2] [3] [4]
            ───────────────────────────────────────────────────────────
              Вход : DS : SI = указатель на строку команд для разбора
                     ES : DI = указатель на FCB для анализируемого
                               имени файла
                     AL = управление синтаксическим разбором
        7 6 5 4 3 2 1 0
        │ │ │ │ │ │ │ │
        │ │ │ │ │ │ │ └─ 1 = прекратить сканирование начальных разделителей
        │ │ │ │ │ │ └─── 1 = установить  байт  идентификатора дисковода*
        │ │ │ │ │ └───── 1 = установить имя файла*
        │ │ │ │ └─────── 1 = установить расширение*
        └─┴─┴─┴───────── Зарезервирован

         ──────────────────
              * Только если указано в строке команд

              Возврат : DS : SI = указатель на первый байт после  раз-
                                  бираемого имени файла
                        ES  : DI = указатель на первый байт форматиру-
                                   емого FCB
                        AL = состояние возврата:
                             00h = нет встретившихся глобальных символов
                             01h = глобальные символы встретились
                             0FFh = указанный дисковод был ошибочным

                    AH  =  2Ah - Получить дату [1] [2] [3] [4]
                    ──────────────────────────────────────────
              Вход : нет
              Возврат : CX = год (с 1980 до 2099)
                        DH = месяц ( с 1 по 12)
                        DL = день (с 1 по 31)
                        AL = день недели (0 = Воскресенье)


                   AH  =  2Bh - Установить дату [1] [2] [3] [4]
                   ────────────────────────────────────────────
              Вход: CX = год (с 1980 до 2099)
                    DH = месяц ( с 1 по 12)
                    DL = день (с 1 по 31)
              Возврат: AL  =  00h, если дата была не ошибочная;
                       AL = 0FFh, если ошибочная дата


                    AH  =  2Ch - Получить время [1] [2] [3] [4]
                    ───────────────────────────────────────────
              Вход : нет
              Возврат : CH =  часы (от 0 до 23)
                        CL =  минуты (от 0 до 59)
                        DH = секунды (от 0 до 59)
                        DL = сотые доли (с 0 до 99)

                   AH  =  2Dh - Установить время [1] [2] [3] [4]
                   ─────────────────────────────────────────────
              Вход : CH =  часы (от 0 до 23)
                     CL =  минуты (от 0 до 59)
                     DH = секунды (от 0 до 59)

                                      - П-77 -
                     DL = сотые доли (с 0 до 99)
              Возврат:  AL  =  00h, если время было правильное;
                        AL =  0FFh, если время ошибочное


              AH  =  2Eh - Установить/сбросить переключатель проверки
              ───────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход :  AL = 00h, для установки проверки в режиме  "off"
                                ("отключить");
                      AL =  01h, для установки проверки в режиме  "on"
                                ("включить");
              Возврат : нет


           AH  =  2Fh - Получить адрес передачи диска (DTA) [2] [3] [4]
           ────────────────────────────────────────────────────────────
              Вход : нет
              Возврат : ES : BX  = указатель на текущую DTA


             AH  =  30h  - Получить номер версии операционной системы
             ────────────────────────────────────────────────────────
                                MS-DOS  [2] [3] [4]
                                ───────────────────
              Вход : нет
              Возврат:  AL  = старший номер версии (слева от точки)
                        AH  = младший номер версии (справа от точки)
                        BX, CX = 0000
              Примечание: AX = 0, если версия 1.Х операционной систе-
                          мы MS-DOS

              AH  =  31h  - Завершить процесс и остаться резидентным
              ──────────────────────────────────────────────────────
                                    [2] [3] [4]
                                    ───────────
              Вход : AL = код возврата (переменная ERRORLEVEL  команд-
                          ного файла )
                     DX = количество параграфов памяти, которые должны
                          остаться резидентными
              Возврат : нет


          AH  =  33h  - Получить/установить статус проверки "Ctrl-Break"
          ──────────────────────────────────────────────────────────────
                                    [2] [3] [4]
                                    ───────────
              Вход : AL = получить текущее состояние
                     AL = установить статус проверки Ctrl-Break
                          остаться резидентными
                     DL  = 00h установить комбинацию клавиш Ctrl-Break
                           в режим "off" ; AL = 01h установить в режим
                           "on"


              Возврат: DL = 00h,  если  комбинация  клавиш  Ctrl-Break

                                      - П-78 -
                            имеет статус "off"; AL = 01h если статус
                            "on"


               AH  =  35h  - Получить вектор прерывания  [2] [3] [4]
               ─────────────────────────────────────────────────────
              Вход : AL = номер вектора
              Возврат : ES : BX = указатель на текущий обработчик пре-
                                  рывания

           AH  =  36h  - Получить свободное пространство памяти на диске
           ─────────────────────────────────────────────────────────────
                                    [2] [3] [4]
                                    ───────────
              Вход : DL = номер дисковода (0 = текущий дисковод,
                     1 = A:, ... 26 = Z:)
              Возврат : BX = количество доступных кластеров
                        DX = количество кластеров на диске
                        CX = количество байтов в секторе
                        Если AX > 0FFFFh. диск недействителен
                        Если  AX <> 0FFFFh, AX = количество секторов в
                        кластере

          AH  =  38h  - Получить текущую информацию о стране [2] [3] [4]
          ──────────────────────────────────────────────────────────────
              Вход : AL = получить текущую информацию о стране
                     AL = с 01h по  0FEh для кодов страны < 255
                     AL = 0FFh для кодов страны > 255
                     BX = код страны, если AL = 0FFh
                     DS : DX = указатель на 32-байтный буфер  информа-
                               ции о стране
              Возврат : Если CF = 0, BX = код страны
                        Если CF = 1, AX = код ошибки
              Примечание:  См.  Руководство  по  операционной  системе
                           MS-DOS по структуре и содержимому буфера
                           информации о стране


           AH = 38h - Установить информацию, относящуюся к стране [3][4]
          ──────────────────────────────────────────────────────────────
              Вход : DX = 0FFFFh (указать "установить страну")
                     AL = 01h по  0FEh для кодов страны < 255
                     AL = 0FFh для кодов страны > 255
                     BX = код страны, если AL = 0FFh
              Возврат: Если CF = 1, AX = код ошибки


           AH  =  39h  - Создать подкаталог (MKDIR) стране [2] [3] [4]
           ────────────────────────────────────────────────────────────
              Вход:  DS : DX = указатель на имя пути ASCIIZ
              Возврат: Если CF = 1, AX = код ошибки


                AH = 3Ah - Удаление подкаталога (RMDIR) [2] [3] [4]
                ---------------------------------------------------
              Вход : DS : DX = указатель на имя пути доступа
              Возврат : Если CF = 1 , AX = код ошибки

                                      - П-79 -


            AH = 3Bh - Изменение текущего каталога (CHDIR) [2] [3] [4]
            ----------------------------------------------------------
              Вход : DS : DX = указатель на имя пути ASCIIZ
              Возврат: Если CF = 1,  AX = код ошибки


                   AH = 3Ch - Создать файл (СREATE) [2] [3] [4]
                   --------------------------------------------
              Вход : DS : DX = указатель на имя пути ASCIIZ
                     CХ = атрибуты файла
              Возврат: Если CF = 0 , AX = описатель файла
                       Если CF = 1 , AX = код ошибки


                       AH = 3Dh - Открыть файл  [2] [3] [4]
                       ------------------------------------
              Вход : DS : DX = указатель на имя пути ASCIIZ
                     AL = режим открытия

         7 6 5 4 3 2 1 0
         │ │ │ │ │ │ │ │
         │ │ │ │ │ └─┴─┴─ Режим доступа: 000 = только считывание
         │ │ │ │ │           001 = только запись
         │ │ │ │ │           010 => считывание/запись
         │ │ │ │ └─────── Всегда 0
         │ └─┴─┴───────── Режим разделения:
         │                    000 = режим совместимости
         │                    001 = отказ в считывании/записи
         │                    010 = отказ в записи
         │                    011 = отказ в считывании
         │                    100 = никакого отказа
         └──────────────── Признак наследования

              Возврат: Если CF = 0 , AX = описатель файла
                       Если CF = 1 , AX = код ошибки
              Примечание: Открытие сетевых файлов недоступно под уп-
                          равлением операционной системы DOS версии 2.Х

                  AН = 3Eh - Закрыть описатель файла  [2] [3] [4]
                 ------------------------------------------------
              Вход : BX = описатель файла
              Возврат : Если CF = 1 , AX = код ошибки

              AH = 3Fh - Считать с файла или с устройства [2] [3] [4]
              -------------------------------------------------------
              Вход : BX = описатель файла
                     CX = количество байтов для считывания
                     DS : DX = указатель на буфер считывания
              Возврат: Если  CF = 0, AX = количество действительно
                                          считанных  байтов
                       Если CF = 1 , AX = код ошибки

             AH = 40h - Записать в файл или на устройство [2] [3] [4]
             --------------------------------------------------------
              Вход : BX = описатель файла

                                      - П-80 -
                     CX = количество байтов для записи
                     DS : DX = указатель на буфер записи


              Возврат: Если CF = 0 , AX = количество байтов, фактичес-
                       ки записанных
                       Если CF = 1 , AX = код ошибки


              AH = 41h - Удалить файл из указанного каталога (UNLINK)
              -------------------------------------------------------
                                    [2] [3] [4]
                                    -----------
              Вход: DS : DX = указатель на имя файла ASCII
              Возврат: Если CF = 1 , AX = код ошибки


                AH = 42h - Передвинуть указатель считывания/записи
                ---------------------------------------------------
                             файла (LSEEK) [2] [3] [4]
                             -------------------------
              Вход : CX : DХ = расстояние для сдвига в байтах (сме-
                               щение)
                     AL = источник передвижения:
                          00 = начало файла плюс смещение
                          01 = текущая позиция плюс смещение
                          02 = конец файла плюс смещение
                     BX = описатель файла
              Возврат: Если CF = 0, DХ : AX = новое положение указателя
                       Если CF = 1, AX = код ошибки


                AH = 43h - Изменить режим файла (CHMOD) [2] [3] [4]
                ---------------------------------------------------
              Вход : DS : DX = указатель на имя пути ASCIIZ
                     AL = 00h - получить атрибут; AL = 01h - устано-
                                вить атрибут
                     CH = 00h, если AL = 01h
                     CL = новый атрибут, если AL = 01h


                  AH = 44h - Управление устройствами ввода/вывода
                --------------------------------------------------
                                (IOCTL) [2] [3] [4]
                                -------------------
              Примечание: См. Tехническое  справочное  руководство  по
                          операционной системе MS-DOS для более полной
                          информации о следующих подфункциях IOCTL

              00h = Получить информацию об устройства [2] [3] [4]
              01h = Установить информацию об устройстве [2] [3] [4]
              02h = Считать с символьного устройства  [2] [3] [4]
              03h = Записать на символьное устройство [2] [3] [4]
              04h = Считать с устройства блока [2] [3] [4]
              05h = Записать на устройство блока [2] [3] [4]
              06h = Получить состояние устройства ввода [2] [3] [4]
              07h = Получить состояние устройства вывода [2] [3] [4]

                                      - П-81 -
              08h = Измялся данный блок устройства [2] [3] [4]
              09h = Локальное или удаленное логическое устройство?
                    [3.1] [3.2] [3.3] [4]
              0Ah = Описатель локальный или удаленный?
                    [3.1] [3.2] [3.3] [4]
              0Bh = Изменить счетчик повторной попытки совместного
                    пользования [3] [4]*
              0Ch = Обобщенный запрос описателя IOCTL (переключение
                    страниц кода) [3.3] [4]
              0Dh = Обобщенный запрос описателя IOCTL на устройстве
                    [3.2] [3.3] [4]
              0Eh = Получить логическое устройство [3.2] [3.3] [4]
              0Fh = Установить логическое устройство [3.2] [3.3] [4]
         ───────────────────────
              * Здесь приводится один из вариантов перевода строки
                "Chande Sharing retry count" (Примеч. переводчика.)

             AH = 45h - Дублировать описатель файла (DUP) [2] [3] [4]
             --------------------------------------------------------
               Вход : BX = существующий описатель файла
               Возврат: Если CF = 0, AX = новый дублирующий описатель
                                          файла
                        Если CF = 1, AX = код ошибки


                AH = 46h - Вынужденное дублирование описателя файла
               ----------------------------------------------------
                               (FORCDUP) [2] [3] [4]
                               ---------------------
               Вход : BX = существующий описатель файла
                      CX = требуемый дублирующий описатель файла
               Возврат: Если CF = 1, AX = код ошибки


                  AH = 47h - Получить текущий каталог [2] [3] [4]
                  -----------------------------------------------
                Вход : DS : SI = указатель на 64-байтный буфер пользо-
                                 вателя
                       DL  =  номер  диска (0 = текущий диск, 1 = А: ,
                              ..., 26 = Z:)
                Возврат  :  DS : SI = указатель на полное имя пути от
                            корневого каталога
                            Если CF = 1, AX = код ошибки
                Примечание : Возвращенное имя пути не включает иденти-
                             фикатор диска ID и начальный символ "/"


                    AH = 48h - Распределить память [2] [3] [4]
                    ------------------------------------------
              Вход : BX = количество параграфов запрашиваемой памяти
              Возврат : Если CF = 0, AX:0 = указатель на  распределен-
                        ный блок памяти
                        Если CF = 1, AX = код ошибки и BX = размер на-
                        ибольшего блока доступной памяти (в параграфах)



                                      - П-82 -
              AH = 49h - Освободить распределенную память [2] [3] [4]
              -------------------------------------------------------
              Вход : ES = Сегмент распределенного блока памяти, подле-
                          жащий освобождению
              Возврат: Если CF = 1, AX = код ошибки

               AH = 4Ah - Модифицировать распределенные блоки памяти
               -----------------------------------------------------
                              (SETBLOCK) [2] [3] [4]
                              ----------------------
              Вход : ES:0 = адрес сегмента распределенного блока памя-
                            ти, подлежащей модификации
                     BХ = новое количество параграфов для блока
              Возврат:  Если CF = 1, AX = код ошибки и BX = максималь-
                        ный возможный размер блока

           AH = 4Bh - Загрузить или выполнить программу (EXЕС) [2][3][4]
           -------------------------------------------------------------
              Вход: DS : DX = указатель на спецификацию файла ASCIIZ
                    AL =  значение функции:
                          00h = загрузить и выполнить данную программу
                          03h = загрузить оверлейный сегмент
                    ЕS : ВX = указатель на блок параметров :
                    Если AL = 00h

              seg_env  dw ?    ; сегмент строки окружения
              cmd_ptr  dd ?    ; указатель  на  командную строку
              fcb1_ptr dd ?    ; указатель на первый блок FCB
              fcb2_ptr dd ?    ; указатель  на второй блок FCB

                    Если AL = 03h

         seg_load dw ?  ; сегмент, в который необходимо загрузить файл
         rel_fact dw ?  ; константа настройки, подлежащая использованию

              Возврат : Если CF = 1, AX = код ошибки

                  AH = 4Ch - Завершить процесс (EXIT) [2] [3] [4]
                  -----------------------------------------------
              Вход : AL = код возврата (командный ERRORLEVEL)
              Возврат : нет


           AH = 4Dh - Получить код возврата подпроцесса (WAIT) [2][3][4]
           -------------------------------------------------------------
              Вход : Нет
              Возврат : AL = код возврата, посылаемый подпроцессом
                        AH = состояние возврата:
                             00h - нормальное завершение
                             01h - завершение по Ctrl-Break
                             02h - завершение из-за критической
                                   ошибки
                             03h - остаться резидентным через  функцию
                                   31h по обработке прерывания 21h



                                      - П-83 -
           AH = 4Eh - Найти первый совпавший файл (FINDFIRST) [2][3][4]
           ------------------------------------------------------------
              Вход: DS : DX = указатель на спецификацию файла ASCIIZ
                    CX =  атрибут , используемый в процессе поиска
              Возврат:  Если CF = 1, AX = код ошибки
                        Если CF = 0, DTA заполняется следующим образом:

         reserved db 21 dup (?)  ; зарезервировано
         attrib   db  ?          ; атрибут файла
         time     dw  ?          ; отметка о времени (создания)  файла
         date     dw  ?          ; отметка о дате (создания) файла
         size     dd  ?          ; размер файла
         name     db 13 dup (?)  ; имя файла ASCIIZ

              AH = 4Fh - Найти следующий совпадающий файл (FINDNEXT)
              ------------------------------------------------------
                                    [2] [3] [4]
                                    -----------
              Вход : DTA, возвращенный  предыдущим  вызовом  FINDFIRST
                     или вызовом FINDNEXT
              Возврат: тот же самый, что и при вызове функции FINDFIRST


               AH = 54h - Получить установку верификации [2] [3] [4]
               -----------------------------------------------------
              Вход : нет
              Возврат : AL = 00h, если проверка в состояние "оff"
                        AL = 01h, если проверка в состояние "оn"


                     AH = 56h - Переименовать файл [2] [3] [4]
                     -----------------------------------------
              Вход:  DS : DX = указатель на старое имя ASCIIZ
                               [дисковод:путь \ имя файла]
                     ЕS : DI = указатель на новое имя ASCIIZ
                               [дисковод:путь \ имя файла]
              Возврат: Если CF = 1, AX = код ошибки


               AH = 5700h - Получить дату и время файла [2] [3] [4]
               ----------------------------------------------------
               Вход : BX = описатель файла
               Возврат: Если CF = 0, CX = время файла и DX = дата файла
                        Если CF = 1, AX = код ошибки


              AH = 5701h - Установить дату и время файла [2] [3] [4]
              -------------------------------------------------------
               Вход : BX = описатель файла
                      CX = новое время
                      DX = новая дата
               Возврат: Если CF = 1, AX = код ошибки


           AH = 59h - Получить расширенную информацию об ошибке [3] [4]
           ------------------------------------------------------------
              Вход : BX = 000h

                                      - П-84 -
              Возврат : AX = расширенный код ошибки
                        BH = класс ошибки
                        BL = предполагаемое действие
                        CH = местоположение
                        CL, DX, SI, DI, ES и DS уничтожены


                     AH = 5Ah - Создать временный файл [3] [4]
                     -----------------------------------------
              Вход: DS : DX = указатель на строку ASCIIZ с  дисководом
                              и путем, оканчивающуюся символом "\"
                    CX =  атрибут файла
              Возврат:  Если  CF = 0, AX = описатель файла и DS : DX =
                        указатель на строку ASCIIZ, законченную именем
                        файла
                        Если CF = 1, AX = код ошибки


                       AH = 5Bh - Создать новый файл [3] [4]
                       -------------------------------------
              Вход: DS : DX = указатель на путь/имя файла ASCIIZ
                    CX =  атрибут файла
              Возврат:  Если CF = 0, AX = описатель
                        Если CF = 1, AX = код ошибки


           AH = 5Ch - Блокировать/Разблокировать доступ к файлу [3] [4]
           ------------------------------------------------------------
              Вход : AL = 00h блокировать доступ к файлу;
                     AL = 01h разблокировать доступ к файлу
                     BX = описатель файла
                     CX = старшее слово смещения
                     DX = младшее слово смещения
                     SI = старшее слово длины
                     DI = младшее слово длины
              Возврат: Если CF = 1, AX = код ошибки


              AX = 5E00h Сеть: Получить имя ЭВМ [3.1] [3.2] [3.3] [4]
              ───────────────────────────────────────────────────────
              Вход : DS : DX = указатель на 16-байтный буфер для
                     ASCIIZ имени ЭВМ
              Возврат : Если CF = 0, DS : DX = указатель на ASCIIZ имя
                        ЭВМ
                        Если CF = 1, AX = код ошибки
                        Если CН = 0, имя/номер не определены
                        Если CH <> 0, имя/номер определены
                        и CL = номер имени NETBIOS


               AX = 5E02h Сеть: Установить строку установки принтера
               ─────────────────────────────────────────────────────
                               [3.1] [3.2] [3.3] [4]
                               ────────────────────
              Вход : BX = переназначение индекса списка
                     CX = длина строки установки (максимальная длина
                          строки установки = 64 байтам)

                                      - П-85 -
                     DS:SI = указатель на строку установки принтера
              Возврат : Если CF = 1, AX = код ошибки


                AX = 5E03h Сеть: Получить строку установки принтера
               ─────────────────────────────────────────────────────
                               [3.1] [3.2] [3.3] [4]
                               ────────────────────
              Вход : BX = индекс списка переназначения
                     ES : DI = указатель на 64-байтный буфер установки
                               принтера
              Возврат : Если CF = 0, CX = длина возвращенный данных и
                        ES : DI = указатель на строку установки принтера
                        Если CF = 1, AX = код ошибки

              AX = 5F02h Сеть: Получить элемент списка переназначения
              ───────────────────────────────────────────────────────
                               [3.1] [3.2] [3.3] [4]
                               ────────────────────
              Вход : BX = индекс списка переназначения (на базе нуля)
                     DS : SI = указатель на 128-байтный буфер для
                               максимального имени
                     ES : DI = указатель на 128-байтный буфер для
                               имени в сети
              Возврат : Если CF = 0, BH = признак состояния устройства
                        Если бит 0 = 0, устройство действительно
                        Если бит 0 = 1, устройство недопустимо
                        BL = тип устройства
                        CX = хранимое значение параметра
                        DS : SI = локальное имя ASCIIZ
                        ES : DI = имя в сети ASCIIZ
                        Если CF = 1, AX = код ошибки


           AX = 5F03h Сеть: Переназначить устройство [3.1] [3.2][3.3][4]
           ─────────────────────────────────────────────────────────────
              Вход : ВL = тип устройства
                     03 = принтер
                     04 = файл
                     CX = 000h
                     DS : SI = указатель на локальное имя  ASCIIZ  для
                               переназначения
                     ES : DI = указатель на имя переназначения в сети
                               ASCIIZ
              Возврат : Если CF = 1, AX = код ошибки


            AH = 62h Получить адрес сегмента  префикса программы [3] [4]
            ───────────────────────────────────────────────────────────
              Вход : нет
              Возврат : BX : 0 = указатель на текущий PSP

             AH  = 65h Получить расширенную информацию, относящуюся к
             ────────────────────────────────────────────────────────
                                 стране [3.3] [4]
                                 ────────────────
              Вход : AL = идентификатор информации ID

                                      - П-86 -
                     BX = страница кода (-1 = глобальная страница кода)
                     DX = идентификатор страны (-1 = текущая информация
                          о стране)
                     CX = размер
                     ЕS : DI = указатель на буфер информации о стране
              Возврат : Если CF = 0, CX = размер возвращенного формата
                        информации на информацию о стране
                        Если CF = 1, AX = код ошибки


             AH  = 66h Получить/установить глобальную кодовую страницу
             ─────────────────────────────────────────────────────────
                                     [3.3] [4]
                                     ─────────
              Вход : AL = 01h получить глобальную кодовую страницу;
                     AL = 02h установить глобальную кодовую страницу
                     BX = кодовая страница (если AL = 02h)
              Возврат : Если CF = 0, BX = активная кодовая страница и
                        DX = системная кодовая страница
                        Если CF = 1, AX = код ошибки


                 AH  = 67h Установить счетчик описателя [3.3] [4]
                 ────────────────────────────────────────────────
              Вход : BX = количество открытых предусмотренных описателей
              Возврат : Если CF = 1, AX = код ошибки


                         AH  = 68h Передать файл [3.3] [4]
                         ─────────────────────────────────
              Вход : BX = описатель файла
              Возврат : Если CF = 1, AX = код ошибки

                 AH  = 69h Расширенная функция открыть/создать [4]
                 ─────────────────────────────────────────────────
              Вход : BX = режим открытия:

         BL = 7 6 5 4 3 2 1 0
              │ │ │ │ │ │ │ │
              │ │ │ │ │ └─┴─┴─ Код доступа:
              │ │ │ │ │            000 = только считывание
              │ │ │ │ │            001 = только запись
              │ │ │ │ │            002 = считывание/запись
              │ │ └─┴─┴─────── Режим разделения:
              │ │                  000 = режим совместимости
              │ │                  001 = отказ в считывании/записи
              │ │                  010 = отказ в записи
              │ │                  011 = отказ в считывании
              │ │                  100 = никакого отказа
              │ └────────────  Признак наследования
              │                    0 = передать описатель дочернему узлу
              │                    1 = нет наследования
              └─────────────── Зарезервировано



                                      - П-87 -
         BH = 7 6 5 4 3 2 1 0
              │ │ │ │ │ │ │ │
              │ │ │ │ │ └─┴─┴─ Зарезервировано
              │ │ └─┴─┴─────── 0 = обработка прерывания "int 24h"
              │ │              1 = возвратить ошибку
              │ └────────────  0 = не выполнять
              │                1 = автоматическое выполнение
              └─────────────── Зарезервировано

              CX  =  атрибуты  нового файла (игнорируются при открытии
                     файла)
              DX =  управление функцией:

              7 6 5 4 3 2 1 0
              │ │ │ │ │ │ │ │
              │ │ │ │ └─┴─┴─┴─ Действие имеется:
              │ │ │ │              000 = сбой
              │ │ │ │              001 = открыть
              │ │ │ │              010 = переместить/открыть
              └─┴─┴─┴───────── Отсутствие действия:
                                   000 = сбой
                                   001 = создать
              DS : SI = указатель на 64-байтную спецификацию файла
                        ASCIIZ
              Возврат : Если CF = 0, AX = описатель файла и
                        CX = код предпринимаемого действия:
                        1 = файл открывался
                        2 = файл создавался/открывался
                        3 = файл перемещался/открывался
                        Если CF = 1, AX = код ошибки
                 Прерывание 22h - Завершить адрес [1] [2] [3] [4]
                 ────────────────────────────────────────────────
              Примечание: Не выдавайте напрямую  это  прерывание;  ис-
                          пользуйте, вместо этого, вызов функции EXEC,
                          которая выдает для вас прерывание "int 22h"
            Прерывание 23h - Адрес выхода по Ctrl-Break [1] [2] [3] [4]
            ───────────────────────────────────────────────────────────
              Примечание: Не выдавайте напрямую  это  прерывание;
                          если  режим  Break  установлен  в  состояние
                          "on",  прерывание "int 23h" проверяется на
                          большинство вызовов функций (за исключением
                          функций 06h и 07h).
           Прерывание 24h - Адрес обработчика критических ошибок [3] [4]
           ─────────────────────────────────────────────────────────────
         Вход : AH =
         Биты 7 6 5 4 3 2 1 0
              │ │ │ │ │ │ │ └─ Область диска, затронутая
              │ │ │ │ │ └─┴─── операцией 0 - считать/1 - записать:
              │ │ │ │ │          00 = область операционной системы DOS,
              │ │ │ │ │          01 = область таблицы FAT; 10=каталог;
              │ │ │ │ │          11 = область данных
              │ │ │ │ └─────── Сбой допускался: 0 = нет; 1 = да
              │ │ │ └───────── Повторная попытка допускалась:0=нет;1=да
              │ │ └─────────── Допускалось игнорирование: 0=нет; 1=да
              │ └───────────── (неиспользуемый)
              └───────────────  0 = ошибка из-за диска; 1 = другая

                                      - П-88 -

              BP  :  SI = указатель на блок управления заголовком уст-
                          ройства, по которому можно отыскать допол-
                          нительную информацию
              DL =  код ошибки устройства, как следует ниже
              Возврат : AL = 0 (игнорировать ошибку)
                        AL = 1 (повторить ошибку)
                        AL = 2 (завершить  программу  по  прерыванию
                               "int 23h")
                        AL = 3 (системный сбой; вызов, производимый в
                               данное время).

              Коды ошибок при обработке прерывания  "int 24h" - адрес
         обработчика критических ошибок:
              00h = Попытка записать на диск, имеющий защиту от записи
              01h = Неизвестное устройство
              02h = Дисковод не готов
              03h = Неизвестная команда
              04h = Ошибка в данных (CRC)
              05h = Ошибочная длина структуры запроса
              06h = Ошибка при поиске дорожки
              07h = Неизвестный тип носителя
              08h = Сектор не найден
              09h = Вывод на бумажный носитель
              0Ah = Сбой при записи
              0Bh = Сбой при чтении
              0Ch = Необычная ошибка


             Прерывание  25h  -  Считывание абсолютное =< 32-Мбайтный
             ────────────────────────────────────────────────────────
                диск) и 26h (Запись абсолютная =< 32-Мбайтный диск)
                ───────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : AL = номер дисковода (0=А, 1=В, и т.д.)
                     CX = количество секторов для считывания
                          (прерывание "int 25h") или для записи
                          (прерывание "int 26h")
                     DX = номер начала логического сектора
                     DS : BX = адрес передачи
              Возврат: Если CF = 0, успешная передача
                            AL = код ошибки
                            AH = 80h, если подсоединение  не  выполни-
                                      лось для ответа
                                 40h,  если операция поиска дорожки не
                                       выполнилась
                                  08h, если ошибка в данных (CRC)  при
                                       считывании диска
                                  04h, если запрашиваемый сектор не
                                       найден
                                  03h, если попытка записи на защищен-
                                       ную от записи дискету
                                  02h, если ошибка отличается от типов
                                       ошибок, перечисленных выше

                                      - П-89 -
                            AX = 0207h, если не выполнился расширенный
                                   формат  для  считывания/записи, ис-
                                   пользующий стандартные вызовы  пре-
                                   рываний "int 25h" и "int 26h"


              Прерывание  25h  - Считывание абсолютное > 32-Мбайтный
              ──────────────────────────────────────────────────────
              диск) и 26h (Запись абсолютная > 32-Мбайтный диск) [4]
              ───────────────────────────────────────────────────────
              Вход : AL = номер дисковода (0=1, 1=В, и т.д.)
                     BX = указатель на список параметров
                     CX = -1 (указывает на расширенный (> 32 Мбайт)
                             формат)
              Возврат: CF = 0, если успешная передача
                       CF = 1, если неуспешная передача
              Примечание: При возврате код ошибки РОР AX. Коды ошибок
                          те же, что и приведенные выше
                          Структура списка параметров:
            rba   dd ?     ; первый сектор (32-разряда; 0 начальный
                           ; адрес) для  считывания/записи
            count  dw ?    ; количество секторов для считывания/записи
            buffer dd ?    ; буфер данных


              Прерывание  27h  -  Завершиться и остаться резидентным
              ──────────────────────────────────────────────────────
                                  [1] [2] [3] [4]
                                  ───────────────
              Вход : CS : = адрес сегмента программы PSP
                     DX = адрес, по которому может быть загружена сле-
                          дующая программа (самый большой адрес,
                          который должен остаться резидентным + 1)
              Возврат : нет
              Примечание: После прерывания "int 27h" файлы не закрыва-
                          ют.  Функция 31h по обработке прерывания 21h
                          является  предпочитаемым   способом   вызова
                          программ  "завершиться  и остаться резидент-
                          ным"

           Прерывание  2Fh  -  Вызовы функции мультиплексного прерывания
           ─────────────────────────────────────────────────────────────
                                      [3] [4]
                                      ───────
              Вход : AX = Управление программой мультиплексирования
                          0100h = Получить состояние установки
                                  принтера (PRINT)
                          0101h = Запустить файл для распечатки на
                                  принтер
                          0102h = Удалить из очереди файл, ожидающий
                                  печати
                          0103h = Удалить из очереди все файлы,
                                  ожидающие печати
                          0104h = Приостановить распечатку и возвратить
                                  его состояние
                          0105h = Конец состояния распечатки (PRINT)
                          0200h = Получить  состояние  установки

                                      - П-90 -
                                  ASSIGN (НАЗНАЧИТЬ)
                          1000h = Получить  состояние  установки
                                  многопользовательского режима исполь=-
                                  зования файлов (SHARE)
                          В700h = Получить состояние установки
                                  дополнительных каталогов для поиска
                                  данных (APPEND)
                     DS : DX = Указатель на исполняемый пакет, если
                               AX = 0101h (0+ указатель двойного слова
                               DWARD на спецификацию файла ASCIIZ  (не
                               универсальный); или указатель на специ-
                               фикацию  файла  ASCIIZ  с целью отмены,
                               если AX = 0102h
              Возврат: Если CF = 1, AX = код ошибки; иначе
                       Если AL = 0FFh, программа "устанавливается"
                       Если AL = 0, "программа не установлена"
                                    разрешение установки
                       Если AL = 1  "программа не установлена"
                                    установка не разрешатся

               Прерывание  67h  -  Менеджер расширенной памяти (EMS)
               ─────────────────────────────────────────────────────
                                    [2] [3] [4]
                                    ───────────
              Примечание: Прерывание 67h используется для LIM EMS спе-
                          цификации системы расширенной памяти  (EMS),
                          поддерживаемых драйверами Lotus/IBM/Microsoft
                          (LIM) во всех версиях  операционной  системы
                          MS-DOS,  начиная  с версии 2.0, но формально
                          зарезервированы  для  такого   использования
                          только в MS-DOS версий 4.0 и выше. Все номе-
                          ра  функций  EMS помещаются в регистр AH, и
                          коды ошибок состояния возвращаются в регистр
                          AH.  Коды ошибок и состояний перечислены ни-
                          же.


                  Коды ошибок/состояния LIM EMS 3.Х, 4.0 MS-DOS и
                 ────────────────────────────────────────────────
                                    AQA EEMS3.Х
                                    ───────────

              00h = Успешная операция
              80h = Внутренняя ошибка
              81h = Аппаратная неисправность
              83h = Недопустимый описатель
              84h = Неописанная запрошенная функция
              85h = Нет более доступных описателей
              86h = Ошибка при сохранении или восстановлении контекста
                    отображения
              87h = Запрошено больше страниц, чем имеется физически
              88h = Запрошено больше страниц, чем доступно в настоящее
                    время
              89h = Запрошено "нуль" страниц
              8Ah = Ошибочный номер логической страницы
              8Bh = Незаконный номер физической страницы
              8Ch = Область сохранения состояния аппаратного отображе-

                                      - П-91 -
                    ния страницы переполнена
              8Dh = Сохранить отображение страницы не удалось
              8Fh = Неопределенная подфункция
              90h = Неопределенный тип атрибута
              91h = Возможность не поддерживается
              92h = Успешный, но часть исходной области была затерта
              93h = Длина исходной области или области назначения пре-
                    вышает длину области, распределенной другому
                    исходному описателю или описателю назначения
              94h = Стандартные и расширенные области памяти перекры-
                    ваются
              95h = Смещение внутри логической страницы превышает раз-
                    мер логической страницы
              96h = Длина области превышает 1Мбайт
              97h = Исходные области EMS и области назначения EMS име-
                    ют одинаковые описатели и перекрываются
              98h = Тип исходной памяти или тип назначения  памяти  не
                    определен
              9Ah  =  Указанный  попеременный набор регистров карты не
                      поддерживается*
              9Bh = Все наборы регистров попеременного  отображения  в
                    данный момент распределены
              9Ch = Наборы регистров попеременного отображения не под-
                    держиваются
              9Dh  = Неописанный или нераспределенный* набор регистров
                     попеременного отображения
              9Eh = Выделенные каналы прямого доступа в память не под-
                    держиваются
              А0h = Нет такого имени описателя
              А1h = Повторное имя описателя
              А2h = Попытка прокрутить 1-Мегабайтное стандартное
                    адресное пространство
              А3h = Содержимое исходного массива искажено или  счетчик
                    отображаемых сегментов превышает общее количество
                    сегментов с управлением памятью в системе
              А4h = Доступ отвергнут операционной системой
         ──────────────────────
              * Здесь  приведен  один  из  вариантов  перевода  строки
                 "Alter mapregister set". (Примеч. переводчика.)


                       AH = 40h Получить состояние менеджера
                      ──────────────────────────────────────
              Вход : Нет
              Возврат: Нет (коды ошибок состояния, возвращенные в  ре-
                       гистр AH)
              Примечание:  Используйте только после установления того,
                           что драйверу EMS имеется


                  AH = 41h Получить адрес сегмента кадра страницы
                  ───────────────────────────────────────────────
              Вход : нет
              Возврат : BX = адрес сегмента кадра страницы



                                      - П-92 -
                  AH = 42h Получить адрес сегмента кадра страницы
                  ───────────────────────────────────────────────
              Вход : нет
              Возврат : BX = количество нераспределенных страниц
                        CX = общее количество страниц

                          AH = 43h  Распределить страницы
                          ──────────────────────────────
              Вход : BX = количество логических страниц для  распреде-
                          ления
              Возврат : DX = описатель


               AH = 44h  Отображать/не отображать страницы описателя
               ─────────────────────────────────────────────────────
              Вход : AL = Номер физической страницы
                     BX = логический номер страницы, т.е. - 1 для нео-
                          тображенной страницы
                     DX = описатель
              Возврат : нет

                           AH = 45h  Освободить страницы
                           ─────────────────────────────
              Вход : DX = описатель
              Возврат : нет


                             AH = 46h  Получить версию
                             ─────────────────────────
              Вход : нет
              Возврат : AL = номер версии в двоично-десятичном коде (BCD)


                     AH = 47h  Cохранить отображение страницы
                     ────────────────────────────────────────
              Вход : DX = описатель
              Возврат : нет

                    AH = 48h  Восстановить отображение страницы
                    ───────────────────────────────────────────
              Вход : DX = описатель
              Возврат : нет

                       AH = 4Bh  Получить счетчик описателя
                       ────────────────────────────────────
              Вход : нет
              Возврат : BX = количество описателей

                       AH = 4Ch  Получить страницы описателя
                       ─────────────────────────────────────
              Вход : DX = описатель
              Возврат : BX = количество логических страниц, выделенных
                             указанному описателю

                     AH = 4Dh  Получить все страницы описателя
                    ──────────────────────────────────────────
              Вход : ES : DI = указатель на массив страниц описателя

                                      - П-93 -
              Возврат  : BX = количество описателей, находящихся в ис-
                              пользовании

                        AX = 4Е00h  Получить карту страниц
                        ──────────────────────────────────
              Вход : ES : DI = указатель на массив карты страниц
              Возврат : состояние карты менеджера  расширенной  памяти
                        (ЕММ), хранимое в массиве карты страниц, ука-
                        занное с помощью ES : DI

                       AX = 4Е01h  Установить карту страниц
                       ────────────────────────────────────
              Вход : DS : DI = указатель на массив карты страниц
              Возврат : Установка состояния карты ЕММ по массиву карты
                        страниц

                  AX = 4Е02h  Получить и установить карту страниц
                  ───────────────────────────────────────────────
              Вход : ES : DI = указатель на назначенный массив
                               карты страниц
                     DS : SI = указатель на исходный массив
                               карты страниц
              Возврат  :  Установка  состояния  карты ЕММ по исходному
                          массиву карты страниц (DS  :  SI) назначенный
                          массив  карты страниц (ES : DI) обновляется
                          с помощью состояния отображения ЕММ

                 AХ = 4Е03h  Получить размер массива карты страниц
                 ─────────────────────────────────────────────────
              Вход : нет
              Возврат  : AL = количество байтов, необходимое исходному
                         или назначенному массиву карты страниц

              AX = 4F00h  Получить частичную карту страниц [EMS 4.0]
              ───────────────────────────────────────────────────────
              Вход : DS : SI = указатель на отображаемый массив
                               сегментов
                     ES : DI = указатель на назначенный массив
                               частичное карты страниц
              Возврат : Состояние частичной карты страниц  ЕММ  содер-
                        жится в назначенном массиве частичной карты
                        страниц (ES : DI)


          AX = 4F01h  Установить частичное отображение страниц [EMS 4.0]
          ──────────────────────────────────────────────────────────────
              Вход : DS : SI = указатель на исходный массив частичной
                               карты страниц
              Возврат : Состояние частичной карты страниц  ЕММ  обнов-
                        ляется по исходному массиву частичной  карты
                        страниц (DS : SI)

                AX = 4F02h  Получить размер массива частичной карты
                ───────────────────────────────────────────────────
                                 страниц [EMS 4.0]
                                 ─────────────────
              Вход : BX = количество страниц в массиве частичной карты

                                      - П-94 -
                          страниц
              Возврат : AL = количество байтов, необходимое для хране-
                             ния массива частичной карты страниц

             AH = 50h Отображать/Не отображать несколько страниц опи-
             ────────────────────────────────────────────────────────
                     сателя с помощью номера страниц [EMS 4.0]
                     ─────────────────────────────────────────
              Вход : AL = подфункция:
                          00h = физическая страница, указанная как номер
                                страницы
                          01h = физическая страницы, указанная адресом
                                сегмента
                     DX = описатель
                     CX  =  количество элементов в массиве отображения
                            логических страниц на физические
                     DS : SI = Указатель на  массив  карты  логических
                               страниц на физические
              Возврат: AH = код ошибки/состояния

                   AH = 51h Перераспределить страницы [EMS 4.0]
                   ────────────────────────────────────────────
              Вход : DX = описатель
                     BX = количество страниц, подлежащих распределению
                          для описателя
              Возврат:  BX = фактическое количество страниц, распреде-
                             ленных описателю

                 AX = 5200h  Получить атрибут описателя [EMS 4.0]
                ───────────────────────────────────────────────────
              Вход : DX = описатель
              Возврат : AL = 00h, если атрибут описателя непостоянен
                        AL = 01h, если атрибут описателя постоянен

                AX = 5201h  Установить атрибут описателя [EMS 4.0]
                ───────────────────────────────────────────────────
              Вход :  DX = описатель
                      ВL = 00h, если новый атрибут описателя
                                непостоянен
                      ВL = 01h, если новый атрибут описателя
                                постоянный
              Возврат : нет


                AX = 5202h  Получить возможности атрибута [EMS 4.0]
                ───────────────────────────────────────────────────
              Вход : Нет
              Возврат:  AL = 00h, если поддерживается постоянство
                                  атрибута
                        AL = 01h, если не поддерживается

                   AX = 5300h  Получить имя описателя [EMS 4.0]
                   ────────────────────────────────────────────
              Вход : DX = описатель
                     ES : DI = указатель на 8-й символьное имя  описа-
                               теля буфера назначения
              Возврат  : Имя описателя возвращается в буфер, указанный

                                      - П-95 -
                         с помощью ES : DI

                  AX = 5301h  Установить имя описателя [EMS 4.0]
                  ───────────────────────────────────────────────
              Вход : DX = описатель
                     ES : DI = указатель на 8-й символьное имя  описа-
                               теля исходного буфера
              Возврат  : Имя описателя устанавливается на основе имени
                         в буфере указанном с помощью ES : DI

                 AX = 5400h  Получить каталог описателей [EMS 4.0]
                 ─────────────────────────────────────────────────
              Вход : ЕS : DI = указатель на массив каталога описателей
              Возврат: AL = количество элементов в каталоге описателей

              AX = 5401h  Отыскать поименованный описатель [EMS 4.0]
              ──────────────────────────────────────────────────────
              Вход: DS : SI = указатель на восьми-символьное имя описа-
                              теля буфера поиска
              Возврат: DX = значение поименованного описателя

            AX = 5402h  Получить общее количество описателей [EMS 4.0]
            ──────────────────────────────────────────────────────────
              Вход : нет
              Возврат: BX = общее количество поддерживаемых описателей


                AH = 55h Изменить карту страниц и перейти [EMS 4.0]
                ───────────────────────────────────────────────────
              Вход : AL = Подфункция:
                          00h = физические страницы, указанные как но-
                                мер страницы
                          01h = физические страницы, указанные адресом
                                сегмента
                     DS : SI = Указатель на карту и структуру перехода
              Возврат: Помещается в целевой адрес (если AH = 00h)

                AH = 56h Изменить карту страниц и вызвать [EMS 4.0]
                ───────────────────────────────────────────────────
              Вход : AL = Подфункция:
                          00h = физические страницы, указанные как но-
                                мер страницы
                          01h = физические страницы, указанные адресом
                                сегмента
                     DX = описатель
                     DS : SI = Указатель на карту и структуру вызова
              Возврат: Целевой адрес вызывается (если AH = 00h)
              Примечание: Используйте RETF для возврата из  вызвавшего
                          адреса и восстановления содержимого карты

           AX = 5602h  Размер пространства стека карты страниц [EMS 4.0]
           ─────────────────────────────────────────────────────────────
              Вход : нет
              Возврат : BX = количество байтов пространства стека, не-
                        обходимое для функции "Изменить карту страниц
                        и вызвать"


                                      - П-96 -
               AH = 57h Переслать/обменять область памяти [EMS 4.0]
               ────────────────────────────────────────────────────
              Вход : AL = Подфункция:
                          00h = переслать область памяти
                          01h = обменяться областью памяти
                     DS : SI = Указатель на описатель области исход-
                                 ная/назначение
              Возврат : нет


                AX = 5800h  Получить отображаемый массив физических
                ───────────────────────────────────────────────────
                                 адресов [EMS 4.0]
                                 ─────────────────
              Вход : ЕS : DI = указатель на отображаемый массив  физи-
                               ческих адресов
              Возврат  : CX = количество элементов в отображаемом мас-
                              сиве физических адресов

                AX = 5801h  Получить число элементов отображаемого
                ──────────────────────────────────────────────────
                       массива физических адресов [EMS 4.0]
                       ────────────────────────────────────
              Вход :  нет
              Возврат  : CX = количество элементов в отображаемом мас-
                              сиве физических адресов

               AX = 5900h  Получить массив конфигурации технических
               ────────────────────────────────────────────────────
                                 средств [EMS 4.0]
                                 ─────────────────
              Вход : ЕS : DI = указатель на массив конфигурации техни-
                               ческих средств
              Возврат : Данные о технических  средствах  копируются  в
                        массив  конфигурации технических средств
                        (указанных с помощью ЕS : DI)

               AX = 5901h  Получить счетчик нераспределенных необра-
               ────────────────────────────────────────────────────
                            ботанных страниц [EMS 4.0]
                            ──────────────────────────
              Вход : нет
              Возврат : BX = количество нераспределенных  необработан-
                             ных страниц
                        DX = общее количество необработанных страниц


                 AH = 5Ah Распределить стандартные/необработанные
                 ────────────────────────────────────────────────
                                страницы [EMS 4.0]
                                ──────────────────
              Вход:  AL = Подфункция:
                          00h = распределить стандартные страницы
                          01h = распределить необработанные страницы
                     BX = количество страниц, подлежащих распределению
              Возврат : DX = описатель


                                      - П-97 -
           AX = 5B00h  Получить установку попеременного набора регистров
           ─────────────────────────────────────────────────────────────
                                  карт [EMS 4.0]
                                  ──────────────
              Вход : нет
              Возврат : Если BL = 0, ES : DI указывает на область сох-
                        ранения содержимого регистра карты
                        Если  BL  <>  0, BL = указатель на действующий
                        попеременный набор регистров карты

                AX = 5B01h  Установить попеременный набор регистров
                ───────────────────────────────────────────────────
                                  карт [EMS 4.0]
                                  ──────────────
              Вход : Если BL = 00h, ES : DI  =  указатель  на  область
                     сохранения содержимого регистра карты
                     Если  BL  <>  00h, BL = номер попеременного набора
                     регистров карты
              Возврат : нет

                  AX = 5B02h  Получить размер области сохранения
                  ───────────────────────────────────────────────
                           попеременной карты [EMS 4.0]
                            ───────────────────────────
              Вход : нет
              Возврат  :  DX  = количество байтов в области сохранения
                                содержимого регистра карты


               AX = 5B03h  Распределить попеременный набор регистров
               ─────────────────────────────────────────────────────
                                  карты [EMS 4.0]
                                  ───────────────
              Вход : нет
              Возврат : Если BL = 00h, отсутствуют попеременные номера
                        регистров карт
                        Если BL <> 00h, BL = номер распределенного по-
                        переменного набора регистров карты

                AX = 5B04h  Освободить попеременный набор регистров
                ───────────────────────────────────────────────────
                                  карты [EMS 4.0]
                                  ───────────────
              Вход : BL = номер попеременного набора регистров карты
              Возврат : нет


               AX = 5B05h  Распределить попеременный набор регистра
               ────────────────────────────────────────────────────
                                   DMA [EMS 4.0]
                                   ─────────────
              Вход : Нет
              Возврат : Если BL = 00h, наборы регистров DMA не поддер-
                        живаются
                        Если BL <> 00h, BL = номер распределенного на-
                        бора регистров DMA


                                      - П-98 -
             AX = 5B06h Позволить прямой доступ к памяти (DMA) в  по-
             ────────────────────────────────────────────────────────
                    переменном наборе регистров карты [EMS 4.0]
                    ───────────────────────────────────────────
              Вход : BL = номер набора регистров прямого доступа в па-
                          мять (DMA)
                     DL = номер канала прямого доступа в память (DMA)
              Возврат : нет


                AX = 5B07h Не разрешить DMA в  попеременном наборе
                ──────────────────────────────────────────────────
                             регистров карты [EMS 4.0]
                             ─────────────────────────
              Вход : BL = номер набора регистров DMA
              Возврат : нет

               AX = 5B08h  Освободить набор регистров DMA [EMS 4.0]
               ─────────────────────────────────────────────────────
              Вход : BL = номер набора регистров DMA
              Возврат : нет

          AH = 5Ch Подготовить для "теплой" начальной загрузки [EMS 4.0]
          ──────────────────────────────────────────────────────────────
              Вход : нет
              Возврат : нет


               AH = 5Dh Разрешить/не разрешить функции OS/E EMS 4.0]
               ─────────────────────────────────────────────────────
              Вход : AL = Подфункция
                          00h = позволить установку функции OS/E
                          01h = не дать возможность на установку функ-
                                ции OS/E
                          02h = возвратить ключ доступа
                      BX, CX = ключ доступа (требуемый только при пос-
                               ледующих вызовах)
              Возврат:  BX, CX = ключ доступа, возвращаемый только при
                        первом вызове подфункции 00h или 01h

