1.3.6 Преобразование программ из типа .EXE в тип .COM.

   Программисты  на  ассемблере имеют  возможность  преобразовать
свои программы из обычного  формата  EXE в формат COM.  Файлы EXE
имеют заголовок, содержащий информацию для привязки; DOS привязы-
вает некоторые адреса программы при  загрузке.  С другой стороны,
файлы  COM существуют в таком виде, что привязка не  требуется  -
они хранятся уже в том  виде,  в  котором  загружаемая  программа
должна быть в памяти машины. По этой причине файлы EXE по меньшей
мере на 768 байтов больше на  диске, чем их COM эквиваленты (хотя
при загрузке в память они будут занимать одинаковое место). Файлы
COM также быстрее загружаются,  поскольку  не требуется привязки.
Других преимуществ у них нет, а некоторые программы слишком слож-
ны и слишком велики, чтобы их можно было преобразовать в тип COM.
   Привязка - это процесс установки адресов, связанных с сегмент-
ным  регистром.   Например, программа может указывать  на  начало
области данных следующим кодом:
   MOV   DX,OFFSET DATA_AREA
   MOV   AX,SEG DATA_AREA
   MOV   DS,AX
Смещение в DX связано с  установкой  сегментного регистра DS.  Но
какое  значение должен принимать сам DS? Программа требует  абсо-
лютный адрес, но номер  параграфа,  в котором будет располагаться
DATA_AREA зависит от того, в какое место в памяти будет загружена
программа - а это  зависит  от  версии  MS  DOS, а также от того,
какие  резидентные  программы будут находиться в младших  адресах
памяти. По этой причине во время компоновки программы можно толь-
ко установить некоторые сегментные значения через смещения  отно-
сительно начала программы.  Затем, когда DOS осуществляет привяз-
ку, значение начального адреса программы  прибавляется к сегмент-
ным  значениям, давая абсолютные адреса,  требуемые в  сегментном
регистре. На рис. 1-6 показан процесс привязки.
   Файлы  COM  не нуждаются в привязке, поскольку они хранятся  в
таком виде, что не нуждаются в фиксации сегмента. Все в программе
хранится относительно начала кодового сегмента, включая все  дан-
ные и стек. По  этой  причине  вся  программа  не может превышать
65535  байт  по длине, что соответствует максимальному  смещению,
которое существует  в  используемой  схеме  адресации  (поскольку
верхняя часть этого блока занята стеком, то реальное пространство
доступное для кода и данных  немного  меньше чем 65535 байт, хотя
стековый  сегмент при необходимости может быть вынесен за границу
64K байтного блока).  В файлах COM все сегментные регистры указы-
вают на начало PSP; сравните с файлами EXE, где DS и ES инициали-
зируются  аналогичным  образом,  но  CS  указывает на первый байт
следующий за PSP.
   Для  представления программы в виде файла COM требуется соблю-
дение следующих правил:

   1.  Не оформляйте программу в  виде  процедуры.  Вместо этого,
поместите в самое начало метку, вроде START, и завершите програм-
му оператором END START.
   2. Поместите в начале программы оператор ORG 100H. Этот опера-
тор указывает начало кода (т.е.  устанавливает счетчик  комманд).


Программы COM  начинаются  с  100H,  что  является первым байтом,
следующим  за PSP, поскольку CS указывает на начало PSP,  которое
расположено на 100H байт ниже. Для того чтобы начать выполнение с
любого другого места поместите по адресу 100H инструкцию JMP.
   3.   Оператор  ASSUME должен устанавливать DS, ES и  SS  таким
образом, чтобы они совпадали со значением  для кодового сегмента,
например, ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG.
   4.  Данные программы могут помещаться в любом месте программы,
до тех пор, пока они не перемешаны с кодом.  Лучше начинать прог-
раммы  с области данных, поскольку макроассемблер может  выдавать
сообщения об ошибках при первом  проходе,  если имеются ссылки на
идентификатор  данных, который еще не обнаружен.  Для перехода  к
началу кода используйте в качестве первой команды программы инст-
рукцию JMP.
   5.   Нельзя  использовать фиксацию сегментов типа  MOV  AX,SEG
NEW_DATA. Достаточно указания одного смещения метки. В частности,
нужно  опускать обычный код, используемый в начале программы  для
установки сегмента данных, MOV AX,DSEG / MOV DS,AX.
   6. Стековый сегмент  полностью  опускается  в  начальном коде.
Указатель стека инициализируется на вершину адресного пространст-
ва 64K,  используемого  программой  (напоминаем,  что стек растет
вниз в памяти). В программах COM он должен быть сделан меньше чем
64K, SS и SP могут быть изменены. Имейте ввиду, что при компонов-
ке программы компоновщик выдаст сообщение об ошибке, указывающее,
что сегмент стека отсутствует. Игнорируйте его.
   7. Завершите программу либо  инструкцией RET, либо прерыванием
20H.   Прерывание  20H - это стандартная функция  для  завершения
программы и возврата управления  в  DOS. Даже когда программа за-
вершается  инструкцией RET, на самом деле используется прерывание
20H.  Это происходит потому, что  вершина стека первоначально со-
держит 0.  При выполнении завершающей инструкции программы RET, 0
выталкивается из  стека,  переназначая  счетчик  команд на начало
PSP.  Находящаяся в этой ячейке функция 20H, выполняется как сле-
дующая инструкция программы,  вызывая  передачу управления в DOS.
Все это означает, что Вам не  надо  при старте программы помещать
на стек DS и 0 (PUSH DS / MOV AX,0 / PUSH AX), как это  требуется
для EXE файлов.

   После того как  программа  сконструирована  таким образом, ас-
семблируйте и компонуйте ее как обычно.  Затем преобразуйте ее  в
форму COM c помощью утилиты EXE2BIN, имеющейся в MS DOS. Если имя
программы, построенной компоновщиком MYPROG.EXE, то просто введи-
те команду EXE2BIN MYPROG. В  результате  Вы получите программный
файл с именем MYPROG.BIN.  Все что Вам останется после этого сде-
лать - переименовать этот  файл  в  MYPROG.COM.   Вы можете также
сразу использовать команду EXE2BIN MYPROG MYPROG.COM, для получе-
ния файла с расширением COM.

   Низкий уровень.

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


CSEG          SEGMENT
              ORG 100H
              ASSUME CS:CSEG, DS:CSEG, SS:CSEG
;---данные
START:        JMP  SHORT BEGIN  ;переход к коду
MESSAGE1      DB   'The dip switches are set for $'
MESSAGE2      DB   'disk drive(s).$'
;---печать первой части сообщения
BEGIN:        MOV  AH,9    ;функция 9 прерывания 21H - вывод
              MOV  DX,OFFSET MESSAGE1  ;строки
              INT  21H     ;выводим строку
              PUSH AX      ;сохраняем номер функции на будущее
;---получаем установку переключателей из порта A микросхемы 8255
              IN   AL,61H  ;получаем байт из порта B
              OR   AL,10000000B  ;устанавливаем бит 7
              OUT  61H,AL        ;заменяем байт
              IN   AL,60H        ;получаем установку переключат.
              AND  AL,11000000B  ;выделяем старшие 2 бита
              MOV  CL,6          ;подготовка к сдвигу AL вправо
              SHR  AL,CL         ;сдвигаем 2 бита в начало
              ADD  AL,49         ;добавляем 1, чтобы считать с 1
                                 ;и 48 для перевода в ASCII
              MOV  DL,AL         ;помещаем результат в DL
              MOV  AL,61H        ;должны восстановить порт B
              AND  AL,01111111B  ;сбрасываем бит 7
              OUT  61H,AL        ;возвращаем байт
;---печать числа накопителей
              MOV  AH,2          ;функция 2 прерывания 21H
              INT  21H           ;печатаем число из DL
;---печать второй половины сообщения
              POP  AX            ;берем номер функции со стека
              MOV  DX,OFFSET MESSAGE2
              INT  21H           ;выводим строку
              INT  20H           ;завершение программы
CSEG          ENDS
              END START

 

Вы находитесь в разделе: 
Также вам будет интересно:

Добавить коментарий