Загрузка в верхнюю часть памяти
Применение прерывания DOS INT 27H является предпочтительным
способом включения в систему постоянных функций типа драйверов
устройств. Это - удобный способ сделать программу постоянной частью
системы. Пользователь может включить программу в файл AUTOEXEC.BAT,
тогда она будет загружаться автоматически. Такую автоматическую
загрузку можно использовать, когда в вашей системе имеется
специальное устройство ввода-вывода. DOS будет загружать драйвер
этого устройства при каждой загрузке системы. Вы можете даже
предпочесть собственную версию процедуры буферизации печати,
поскольку вы хотите, чтобы она постоянно загружалась в систему.
Однако выход в DOS с фиксацией программы в ОЗУ работает не
всегда. Фирма IBM предлагает три операционные системы для
персональных ЭВМ: DOS, которая и рассматривается в данной книге,
CP/M-86 фирмы Digital Research и UCSD p-System фирмы SofTech
Microsystems. Кроме указанных систем, предлагаемых фирмой IBM,
несколько независимых разработчиков распространяют свои системы.
Чтобы создать драйвер устройства, который работал бы со всеми этими
системами, нужно использовать нечто отличного от метода,
применяемого для DOS.
Допустим, у вас имеется специализированное устройство печати,
которое вы хотите продавать как приспособление к IBM PC. Поскольку
ваш принтер - отноительно дешевое устройство, для него потребуется
больше управления со стороны BIOS, чем для принтера фирмы IBM. Вы
конструируете принтер и устройство подсоединения и пишете BIOS
программу для поддержки его работы. Если вы пользуетесь
прерыванием INT 27H, то ваше устройство можно передавать только
пользователям, имеющим на своей персональной ЭВМ DOS. Необходим
такой способ загрузки драйвера устройства, который бы работал во
всех операционных системах.
Способ загрузки, годный не только для DOS, называется загрузкой
в верхние адреса оперативной памяти. При этом управление системой
перехватывается непосредственно после процедуры самоконтроля при
включении питания. Это может быть реализовано при помощи
специальной дискеты загрузки. Программа будет записана на дискету,
которая вставляется в дисковод перед включением питания.
Подпрограмма загрузки, входящая в BIOS, загружает драйвер
устройства с дискеты в верхнюю часть оперативной памяти. Затем
можно изменить размер области данных сообщаемый BIOS в соответствии
с имеющимся объемом оперативной памяти. При загрузке программы в
верхние адреса размер доступной оперативной памяти уменьшается.
Если после этого загрузить стандартную операционную систему, будет
восстановлено нормальное функционирование ЭВМ. Все операционные
системы фирмы IBM учитывают объем памяти BIOS при определении
границ оперативной памяти. Указанные системы не затрагивают
программ, загруженных в верхние адреса. Если система удовлетворяет
указанным требованиям, то можно пользоваться загрузкой в верхние
адреса оперативной памяти.
Приведем пример для иллюстрации описанного приема. На Фиг. 10.2
представлен листинг ассемблирования двух подпрограмм. Первая
подпрограмма осуществляет инициализацию и загрузку драйвера
устройства. Вторая подпрограмма является собственно драйвером
устройства. Позже станет ясным, почему удобнее было разделить эту
программу на две части.
A
Microsoft (R) Macro Assembler Version 5.00 1/1/80 01:21:50
Фиг. 10.2(а) Загрузчик для создания псевдо-диска Page 1-1
PAGE ,132
TITLE Фиг. 10.2(а) Загрузчик для создания псевдо-диска
0000 NEW_DISK SEGMENT
0000 DISK_BIOS LABEL FAR
0003 ORG 3
0003 OLD_VECTOR LABEL WORD
0003 NEW_DISK ENDS
0000 ABS0 SEGMENT AT 0
004C ORG 13H*4
004C DISK_VECTOR LABEL WORD
0410 ORG 410H
0410 EQUIPMENT LABEL WORD
0413 ORG 413H
0413 MEMORY_SIZE LABEL WORD
= 00A0 DISK_SIZE EQU 160
7C00 ORG 7C00H ; Место,в которое заносится загрузчик ДОС
7C00 BOOT_RECORD LABEL FAR
7C00 ABS0 ENDS
0000 CODE SEGMENT
ASSUME CS:CODE,DS:ABS0
7C00 ORG 7C00H
7C00 8C C8 MOV AX,CS
7C02 8E D8 MOV DS,AX
7C04 8E C0 MOV ES,AX
7C06 8D 36 7C00 R LEA SI,BOOT_RECORD
7C0A 8D 3E 7A00 R LEA DI,BOOT_RECORD-200H ; Место,на которое переносится
7C0E B9 0200 MOV CX,512 ; загрузчик ДОС
7C11 F3/ A4 REP MOVSB ; Перенесение загрузчика
7C13 E9 7A16 R JMP NEXT_LOCATION-200H
7C16 NEXT_LOCATION:
Фиг. 10.2 программа создания псевдо-диска (начало)
7C16 83 06 0410 R 40 ADD EQUIPMENT,40H ; Увеличение числа дисководов
7C1B A1 0413 R MOV AX,MEMORY_SIZE
7C1E 2D 00A0 SUB AX,DISK_SIZE
7C21 A3 0413 R MOV MEMORY_SIZE,AX ; Уменьшение доступной ДОС памяти,необхо-
7C24 B1 06 MOV CL,6 ; димое для размещения псевдо-диска
7C26 D3 E0 SHL AX,CL ; Умножение на 1024/16
7C28 8E C0 MOV ES,AX ; Сегментная часть адреса нового диска
7C2A B8 0201 MOV AX,201H ; Чтение сектора в эту область
7C2D BB 0000 MOV BX,0
7C30 B9 0002 MOV CX,2
7C33 BA 0000 MOV DX,0
7C36 CD 13 INT 13H
7C38 72 1A JC BOOT_ERROR
ASSUME ES:NEW_DISK
7C3A A1 004C R MOV AX,DISK_VECTOR
7C3D 26: A3 0003 R MOV OLD_VECTOR,AX
7C41 A1 004E R MOV AX,DISK_VECTOR+2 ; Сохранение старого вектора пре-
7C44 26: A3 0005 R MOV OLD_VECTOR+2,AX ; рывания 13h
7C48 C7 06 004C R 0000 MOV DISK_VECTOR,0 ; Установка вектора прерывания 17h
7C4E 8C 06 004E R MOV DISK_VECTOR+2,ES ; на новое место
7C52 EB 07 JMP SHORT REBOOT ; Чтение загрузчика с другой дискеты
7C54 BOOT_ERROR:
7C54 8D 36 7A93 R LEA SI,ERROR_MSG-200H ; Печать сообщения об ошибке
7C58 E8 7C81 R CALL PRINT_MSG
7C5B REBOOT:
7C5B 8D 36 7AA5 R LEA SI,BOOT_MSG-200H ; Печать сообщения о загрузке ДОС
7C5F E8 7C81 R CALL PRINT_MSG
7C62 WAIT_BOOT:
7C62 B4 00 MOV AH,0
7C64 CD 16 INT 16H ; Ожидание ввода с клавиатуры
7C66 3C 20 CMP AL,' ' ; Ожидается ввод пробела
7C68 75 F8 JNE WAIT_BOOT
7C6A B8 0201 MOV AX,201H
7C6D BB 7C00 MOV BX,7C00H
7C70 B9 0001 MOV CX,1
7C73 BA 0000 MOV DX,0
7C76 8E C2 MOV ES,DX ; Ввод на стандартное место загрузчика
7C78 CD 13 INT 13H
7C7A 72 D8 JC BOOT_ERROR
7C7C EA 7C00 ---- R JMP BOOT_RECORD
7C81 PRINT_MSG PROC NEAR
7C81 2E: 8A 04 MOV AL,CS:[SI] ; Взять символ для печати
7C84 46 INC SI
7C85 3C 24 CMP AL,'$' ; Проверка на символ конца вывода
7C87 75 01 JNE OUTPUT
7C89 C3 RET
7C8A OUTPUT:
7C8A B4 0E MOV AH,14
7C8C BB 0000 MOV BX,0
7C8F CD 10 INT 10H ; Вывод на дисплей через BIOS
7C91 EB EE JMP PRINT_MSG
7C93 8E E8 A8 A1 AA A0 20 ERROR_MSG DB 'Ошибка загрузки',13,10,'$'
A7 A0 A3 E0 E3 A7 AA
A8 0D 0A 24
Фиг. 10.2 программа создания псевдо-диска (продолжение)
7CA5 82 E1 E2 A0 A2 EC E2 BOOT_MSG DB 'Вставьте новую дискету с ДОС',13,10
A5 20 AD AE A2 E3 EE
20 A4 A8 E1 AA A5 E2
E3 20 E1 20 84 8E 91
0D 0A
7CC3 A8 20 AD A0 A6 AC A8 DB 'и нажмите на пробел',10,13,'$'
E2 A5 20 AD A0 20 AF
E0 AE A1 A5 AB 0A 0D
24
7CD9 PRINT_MSG ENDP
7CD9 CODE ENDS
END
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:06:49
Фиг. 10.2(б) Программа обслуживания псевдо-диска Page 1-1
PAGE ,132
TITLE Фиг. 10.2(б) Программа обслуживания псевдо-диска
0000 CODE SEGMENT
ASSUME CS:CODE
;--------------------------------------------
; Эта программа находится в секторе 1 трека 0
; псевдо-диска. Чтение и запись на устройство 2
; переадресуется на эту программу
;--------------------------------------------
0000 DISK PROC FAR
= 0140 DISK_SIZE EQU 320 ; Размер псевдо-диска в сектрах
0000 EB 05 90 JMP START_BIOS
0003 ???????? ORIGINAL_VECTOR DD ?
0007 START_BIOS:
0007 80 FA 02 CMP DL, 2 ; Программа обрабатывает только обращения
000A 74 05 JE L1 ; к устройству (дисководу) 2
000C OLD_BIOS:
000C 2E: FF 2E 0003 R JMP ORIGINAL_VECTOR ; Переход на стандартную программу
0011 L1:
0011 3C 01 CMP AL, 1
0013 76 F7 JBE OLD_BIOS
0015 80 FC 04 CMP AH, 4
0018 72 06 JB READ_WRITE ; Обрабатываются только команду чтения и
; записи
001A OK_RETURN:
001A B4 00 MOV AH, 0 ; Код возврата - 0
001C F8 CLC ; Сброс C-флага - нет ошибки
001D CA 0002 RET 2
0020 READ_WRITE:
0020 53 PUSH BX ; Сохранение регистров
0021 51 PUSH CX
0022 52 PUSH DX
0023 56 PUSH SI
0024 57 PUSH DI
0025 1E PUSH DS
0026 06 PUSH ES
Фиг. 10.2 программа создания псевдо-диска (продолжение)
;----- Вычисление адреса расположения требуемой записи в псевдо-диске
0027 50 PUSH AX ; Сохранение кода требуемой операции
0028 B0 08 MOV AL, 8 ; Число секторов на треке
002A F6 E5 MUL CH
002C B5 00 MOV CH, 0
002E 03 C1 ADD AX, CX ; Прибавление номера сектора
0030 80 FE 00 CMP DH, 0 ; Проверка на номера стороны
0033 74 03 JE HEAD_0
0035 05 0140 ADD AX, 320 ; Переключение на второю сторону
0038 HEAD_0:
0038 48 DEC AX
0039 3D 0140 CMP AX, DISK_SIZE ; Вычисленное значение правильно?
003C 76 0E JBE DISK_OK
003E RECORD_NOT_FOUND:
003E 58 POP AX ; Восстановление регистров
003F 07 POP ES
0040 1F POP DS
0041 5F POP DI
0042 5E POP SI
0043 5A POP DX
0044 59 POP CX
0045 5B POP BX
0046 B4 04 MOV AH, 4 ; Ошибка: сектор не найден
0048 F9 STC
0049 CA 0002 RET 2 ; Возврат с указанием об ошибке
004C DISK_OK:
004C B1 05 MOV CL, 5
004E D3 E0 SHL AX, CL ; Определение расположения данных на
0050 8C C9 MOV CX, CS ; псевдо-диске
0052 03 C8 ADD CX, AX ; В регистре CX сегментная часть адреса
; данных на диске
0054 51 PUSH CX
0055 8B D3 MOV DX, BX ; В регистре DX адрес передачи
0057 B1 04 MOV CL, 4
0059 D3 EA SHR DX, CL
005B 8C C1 MOV CX, ES
005D 03 D1 ADD DX, CX ; В регистре DX сегментная часть адреса
; передаваемых данных
005F 59 POP CX
0060 83 E3 0F AND BX, 0Fh ; Выделение младших 4 разрядов
0063 58 POP AX ; Восстановление код требуемой операции
0064 80 FC 02 CMP AH, 2
0067 74 11 JE READ_OPN
0069 WRITE_OPN:
0069 8C CE MOV SI, CS
006B 3B CE CMP CX, SI ; Проверка на запись поверх этой программы
006D 74 1B JE ALL_DONE
006F 8E C1 MOV ES, CX
0071 BF 0000 MOV DI, 0
0074 8E DA MOV DS, DX
0076 8B F3 MOV SI, BX ; Установка параметров передачи
0078 EB 09 JMP SHORT DO_MOVE
007A READ_OPN:
007A 8E D9 MOV DS, CX
Фиг. 10.2 программа создания псевдо-диска (продолжение)
007C BE 0000 MOV SI, 0
007F 8E C2 MOV ES, DX
0081 8B FB MOV DI, BX
0083 DO_MOVE:
0083 8A E8 MOV CH, AL ; Число слов в секторе
0085 B1 00 MOV CL, 0
0087 FC CLD
0088 F3/ A5 REP MOVSW ; Пересылка данных
008A ALL_DONE:
008A 07 POP ES ; Восстановление регистров
008B 1F POP DS
008C 5F POP DI
008D 5E POP SI
008E 5A POP DX
008F 59 POP CX
0090 5B POP BX
0091 B4 00 MOV AH, 0 ; Нормальное окончание
0093 F8 CLC
0094 CA 0002 RET 2
0097 DISK ENDP
0097 CODE ENDS
END
Фиг. 10.2 (а) Процедура загрузки для виртуального диска;
(b) Программа драйвера виртуального диска.
Драйвер устройства, приведенный в рассматриваемом примере,
реализует модель диска в оперативной памяти. Мы возьмем 160К
памяти системы и будем исполльзовать ее не как оперативную
память, а как дискету. Мы выбрали именно 160К потому, что это
минимальный объем дискеты фирмы IBM. Очевидно, при большем объеме
оперативной памяти можно моделировать дискету большего объема.
Подпрограмму псевдо-диска можно использовать для повышения
производительности программ, производящих интенсивный обмен с
диском. Например, если поместить на псевдо-диск ассемблер и
исходный код программы, ассемблирование будет произведено не за
минуты, а за секунды. Производительность некоторых программ может
быть повышена более чем на порядок. Платой за такое повышение
производительности являются 160K байт оперативной памяти, отводимые
под псевдо-диск. Если в системе, которая в основном используется
для редактирования и ассемблирования, имеется 256 кбайт памяти, то
в действительности для ассемблера достаточно всего лишь 96 кбайт.
Оставшиеся 160 кбайт можно использовать для моделирования диска в
оперативной памяти. Следует помнить, что содержимое такого диска
теряется при отключении питания, поэтому, прежде чем окончить
работу, убедитесь, что информация скопирована на настоящую
дискету.
Первая подпрограмма на Фиг. 10.2 - процедура загрузки. Ее
код находится в секторе 1 дорожки 0 загрузочной дискеты. Как
поместить программу туда, будет объяснено позже. Подпрограмма POST
при завершении считывает содержимое сетора 1 дорожки 0 в память,
по адресу 0:7C00H. Затем POST передает управление по первому
адресу этой записи. Таким образом система фирмы IBM загружает в
память DOS или любую другую операционную систему. А мы как раз и
собираемся, загружать свою собственную простую операционную
систему.
Сегмент NEW_DISK определяет адрес подпрограммы-драйвера
устройства, также представленной на втором листинге (см. Фиг.
10.2). Поскольку наши подпрограммы ассемблируются отдельно, этот
сегмент для связи процедуры загрузки и драйвера устройства во время
выполнения. Сегмент ABS0 локализует векторы прерываний, заменяемые
в процедуре загрузки. В сегменте CODE, содержатся команды,
загружаемые с дискеты. Сегмент CODE - единственная часть
приведенной программы, находящаяся на загрузочной дискете.
Первое, что делает программа инициализации - пересылает себя по
адресу 0:7A00H. Затем, в процессе инициализации, процедура
перезагружает систему, чтобы загрузить настоящую операционную
систему. Эта загрузка производится по адресу 0:7C00H. Если бы
процедура инициализации не переносила себя на другое место, она бы
считывала следующую запись загрузки в ту область памяти, где
находится сама.
С адреса NEXT_LOCATION процедура инициализации инсталирует
драйвер устройства. Она изменяют флаги оборудования для указания на
наличие дополнительного дисковода по сравнению с установкой внешних
переключателей. Это "убеждает" операционную систему, что диск в
оперативной памяти является частью технического обеспечения. При
инициализации значение MEMORY_SIZE уменьшается на 160 кбайт,
которые резервируются для моделирования диска. Это предотвращает
использование предназначенной для него памяти. Кроме того,
программа подсчитывает значение сегмента для этой области в 160
кбайт, чтобы знать, куда загружать драйвер устройства. Когда это
выполнено, подпрограмма инициализации загружает в зарезервиро-
ванную память содержимое сектора 2 дорожки 0 загрузочной дискеты.
Как поместить драйвер устройства в сектор 2 будет описано при
размещении программы загрузки в секторе 1.
После чтения процедуры драйвера устройства, подпрограмма
инициализации изменяет вектор прерывания BIOS дискеты BIOS (INT
13H), чтобы он указывал на новый драйвер устройства. Как и в
предыдущем примере, эта процедура сохраняет старый вектор. Новому
драйверу этот вектор нужен чтобы при необходимости считывать данные
с настоящей дискеты, а не с ее модели. Наконец, наша программа
загружает систему. Она предлагает пользователю вставить системную
дискету, ждет утвердительного ответа и считывает запись загрузки.
(Если бы процедура предварительно не произвела пересылку программы,
то сейчас она была бы испорчена). Если все идет нормально, то
процедура осуществляет переход по первому адресу записи загрузки, в
результате чего управление получает стандартная операционная
система.
Прежде чем двинуться дальше, рассмотрим, как поместить
процедуру загрузки на новую загрузочную дискету. Во-первых,
необходима пустая отформатированная дискета. Она и станет
загрузочной. Листинг на Фиг. 10.3 показывает, что ассемблирование и
редактирование связей процедуры загрузки происходят, как обычно.
Вызовите программу DOS DEBUG и загрузите процедуру инициации.
Она загружается со смещением 7C00H, установленным программой DEBUG.
Регистры устанавливаются таким образом, чтобы использовать BIOS для
записи одного сектора дискеты. Это выполняет трехбайтовая
программа, находящаяся по адресу 200H. Если после записи нет
состояния ошибки, то запись инициализации уже на дискете.
Для записи драйвера устройства в сектор 2 выполните следующие
шаги, показанные на Фиг. 10.3. С помощью программы DEBUG мы
загружаем в память драйвер псевдодиска. Команда записи программы
DEBUG помещает код драйвера в сектор с относительным номером 1
(сектор 2 дорожки 0) дискеты, находящейся на дисководе A:.
Аналогичный способ можно было бы применить и для занесения на
дискету записи инициализации.
Такой способ формирования вызова BIOS в программе DEBUG
для записи на дискету может использоваться почти для всех функций
BIOS. Проследить, что именно происходит при вызове BIOS, можно с
помощью программы DEBUG. Можно установить регистры для вызова и
написать несложную трехбайтовую программу, осуществляющую
программное прерывание и производящую возврат в DEBUG. Этот прием
удобен также для тестирования собственного драйвера устройства.
Вернемся к процедуре драйвера псевдо-диска во второй части Фиг.
10.2. Заметим, что процедура загрузки сохранила исходный вектор
дискеты (INT 13H) в этом сегменте со смещением 3. Подпрограммы-
драйвера используют этот вектор для реализации всех функций
дискеты, которые не реализуются псевдо-диском. В приведенной
подпрограмме предполагается, что псевдо-диск находится на дисководе
2. На запрос любого другого дисковода процедура передает управление
BIOS, используя приэтом сохраненный в ORIGINAL_VECTOR исходный
вектор. Аналогично и запрос на смену дискеты передается BIOS. Если
функция, запрашиваемая для псевдо-дисковода, не считывание и не
запись, то драйвер псевдо-диска не производит никаких действий, и
происходит возврат с нормальным кодом завершения. Псевдо-диск
не требует форматирования, а поскольку у нас нет контроля ошибок,
то не остается ничего проверять.
Если запрашиваемой операцией является считывание или запись,
драйвер вычисляет адрес соответствующего псевдо-сектора в памяти.
При обращении за границу диска поцедура возвращает запись об ошибке
отсуствия адреса. Код драйвера устанавливает регистры источника и
назначения в соответствии с направлением операции. Наконец,
команда REP MOVSW передает данные между псевдо-диском и буфером
пользователя. Рассматриваемая программа всегда устанавливает
нормальный код завершения и производит возврат в вызывающую
программу.
Данный пример показывает, как реализовать моделирование диска,
однако он не готов для продуктивного использования. Для того, чтобы
стать утилитой общего назначения, эта программа должна быть
преобразована для обеспечения работы с любым прсевдоустройством, а
не только со вторым. Программу можно было бы изменить для работы с
сектором любой длины, хотя обычно этого не требуется. Фактически,
если моделирование диска применяется только при работе с DOS,
процедура инициализации должна форматировать дискету, записав
A
A>MASM BOOT,,,;
The IBM Personal Computer MACRO Assembler
Version 1.00 (C)Copyroght IBM Corp 1981
Warning Severe
Errors Errors
0 0
A>B:LINK BOOT,,,;
IBM Personal Computer Linker
Version 1.00 (C)Copyroght IBM Corp 1981
Warning: No STACK segment
Therhe was 1 error detected
A>MASM DISK,,,;
The IBM Personal Computer MACRO Assembler
Version 1.00 (C)Copyroght IBM Corp 1981
Warning Severe
Errors Errors
0 0
A>B:LINK DISK,,,;
IBM Personal Computer Linker
Version 1.00 (C)Copyroght IBM Corp 1981
Warning: No STACK segment
Therhe was 1 error detected
A>DEBUG BOOT.EXE
-R
AX=0000 BX=0000 CX=7CD3 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=06D7 ES=06D7 SS=06E7 CS=06E7 IP=0000 NV UP DI PL NZ NA PO NC
06E7:0000 0000 ADD [BX+SI],AL DS:0000=CD
-U7C00 7C05
06E7:7C00 8CC8 MOV AX,CS
06E7:7C00 8CD8 MOV DS,AX
06E7:7C00 8CC0 MOV ES,AX
-RAX
AX 0000
:301
-RBX
BX 0000
:7C00
-RCX
CX 7CD3
:1
-RDX
DX 0000
:
-RES
ES 06D7
:6E7
-E200
O6D7:0200 OO.CD 00.13 00.CC ;*** Здесь вставьте загрузочную дискету
-g=100
AX=0000 BX=7C00 CX=0001 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=06D7 ES=06D7 SS=06E7 CS=06E7 IP=0102 NV UP EI PL NZ NA PE NC
06E7:0102 CC INT 3
-NDISK.EXE ;*** Здесь вставьте программную дискету
-L
-UD 10
06E7:0000 EB05 JMPS 0007
06E7:0002 90 NOP
06E7:0003 0000 ADD [BX+SI],AL
06E7:0005 0000 ADD [BX+SI],AL
06E7:0007 80FA02 CMP DL,02
06E7:000A 7405 CMP 0011
06E7:000C 2E SEG CS
06E7:000D FF2E0300 JMP L,[0003] ;*** Здесь вставьте загрузочную дискету
-W0 0 1 1
-Q
A>
A
Фиг. 10.3 Шаги подготовки загрузки в верхние
адреса памяти
справочник и таблицу размещения файлов FAT. При нынешнем виде этой
процедуры после загрузки DOS вы должны "форматировать" диск C:. Для
псевдо-диска не требуеися физического форматирования, но утилита
FORMAT записывает таблицу FAT и каталог, необходимые для
функционирования DOS.
Эта процедура обеспечивает также сохранение процедуры-драйвера
устройства в псевдо-секторе 1 на дорожке 0. Система DOS не
использует указанный сектор дисковода C:, однако другие системы
могут это делать. Вы вооозможно, заметили, что программа псевдо-
диска предотвращает запись в смоделированный сектор дорожки 0, так
что программа по крайней мере не уничтожит саму себя.
Вообще говоря, метод загрузки в верхние адреса оперативной
памяти довольно сложен. Необходима загрузка с двух дискет, что
требует от оператора дополнительных манипуляций. Если не
предполагается использование программы в каких-либо других
системах, кроме DOS, то гораздо удобнее использовать прерывание INT
27H. В противном случае загрузка в верхние адреса оперативной
памяти может оказаться единственно возможным способом.
Содержание