Глава 1. Системные ресурсы.

Раздел 3. Управление программами.

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

Программисты на ассемблере имеют возможность преобразовать свои программы из обычного формата EXE в формат COM. Файлы EXE имеют заголовок, содержащий информацию для привязки; DOS привязывает некоторые адреса программы при загрузке. С другой стороны, файлы COM существуют в таком виде, что привязка не требуется они хранятся уже в том виде, в котором загружаемая программа должна быть в памяти машины. По этой причине файлы EXE по меньшей мере на 768 байтов больше на диске, чем их COM эквиваленты (хотя при загрузке в память они будут занимать одинаковое место). Файлы COM также быстрее загружаются, поскольку не требуется привязки. Других преимуществ у них нет, а некоторые программы слишком сложны и слишком велики, чтобы их можно было преобразовать в тип COM.

Привязка - это процесс установки адресов, связанных с сегментным регистром. Hапример, программа может указывать на начало области данных следующим кодом: MOV DX,OFFSET DATA_AREA
MOV AX,SEG DATA_AREA
MOV DS,AX
Смещение в DX связано с установкой сегментного регистра DS. Hо какое значение должен принимать сам DS? Программа требует абсолютный адрес, но номер параграфа, в котором будет располагаться DATA_AREA зависит от того, в какое место в памяти будет загружена программа - а это зависит от версии MS DOS, а также от того, какие резидентные программы будут находиться в младших адресах памяти. По этой причине во время компоновки программы можно только установить некоторые сегментные значения через смещения относительно начала программы. Затем, когда DOS осуществляет привязку, значение начального адреса программы прибавляется к сегментным значениям, давая абсолютные адреса, требуемые в сегментном регистре. Hа рис. 1-6 показан процесс привязки.

Файлы COM не нуждаются в привязке, поскольку они хранятся в таком виде, что не нуждаются в фиксации сегмента. Все в программе хранится относительно начала кодового сегмента, включая все данные и стек. По этой причине вся программа не может превышать 65535 байт по длине, что соответствует максимальному смещению, которое существует в используемой схеме адресации (поскольку верхняя часть этого блока занята стеком, то реальное пространство доступное для кода и данных немного меньше чем 65535 байт, хотя стековый сегмент при необходимости может быть вынесен за границу 64K байтного блока). В файлах COM все сегментные регистры указывают на начало PSP; сравните с файлами EXE, где DS и ES инициализируются аналогичным образом, но CS указывает на первый байт следующий за PSP.

Для представления программы в виде файла COM требуется соблюдение следующих правил:

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

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

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


<~-1.3.5 Загрузка и запуск программных оверлеев.
Содержание
Глава 2. Таймеры и звук.-~>

Сайт управляется системой uCoz