Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Dos7book

.pdf
Скачиваний:
97
Добавлен:
09.02.2015
Размер:
5 Мб
Скачать
☆

Глава 9: Примеры композиции исполняемых файлов

листинга детально изложена в разделе 9.07-01. На всякий случай полезно проверить длину созданного файла либо командой DIR (3.10), либо по данным в панелях файл-менеджера Volcov Commander (6.25).

При пользовании программой TURN_OFF.COM нужно иметь ввиду, что большинство компьютеров выпуска 1990-х годов не оснащено средствами APM BIOS, и потому проигнорирует заложенные в программу вызовы. Кроме того, нельзя напрямую обращаться к APM BIOS из "окна DOS" операционной системы Windows. Программу TURN_OFF.COM следует вызывать только из среды DOS, причем ее удобно вызывать через меню файл-менеджера, например так, как показано в последних строках файла VC.MNU в разделе 6.25-02.

С позиции пользования, конечно, было бы целесообразно предусмотреть в программе TURN_OFF.COM выдачу сообщения об ошибках, например, о вызове из "окна DOS" или об отсутствии в компьютере средств APM BIOS. Но тогда программа не была бы настолько проста. Однако исправить ситуацию несложно. Например, опознавание среды Windows реализовано в строках 13A – 141 файла из раздела 9.10-02. Многочисленные варианты выведения сообщений об ошибках показаны в разделах 9.06, 9.08 и 9.10. Ознакомившись с упомянутыми примерами, Вы сможете сами потом усовершенствовать файл TURN_OFF.COM.

Примечание 1: если в момент выключения электропитания кэш-буфер драйвера SMARTDRV.EXE (5.06-01) не пуст, то остающиеся там данные пропадают. Это может случиться как при выключении посредством программы TURN_OFF.COM, так и при неожиданном пропадании напряжения в электросети. Если драйвер SMARTDRV.EXE все же приходится применять, то можно намеренно сбрасывать данные из кэш-буфера на диск перед вызовом программы TURN_OFF.COM, но лучше кэширование операций записи вообще запретить.

9.06Программа ввода данных в переменную окружения

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

Предлагаемая программа заменяет значение существующей переменной окружения другими данными, и потому названа Reassign.com. Она действует в кооперации со встроенной командой SET (3.26) командного интерпретатора, не

– 509 –

Глава 9: Примеры композиции исполняемых файлов

дублируя ее функции. Команда SET создает переменную окружения, первая цифра значения которой определяет операцию для программы Reassign.com:

1– сообщить размер набольшего свободного блока XMS-памяти;

2– принять ввод данных с клавиатуры;

3– сообщить букву текущего логического диска.

Последующие знаки в значении подготовленной переменной могут быть любыми, но их наличие определяет место для тех данных, которые возвратит программа Reassign.com. Если этого места недостаточно для размещения запрошенной величины, то на экран будет выведено сообщение об ошибке. Если результат не заполнит все предоставленное место, то оставшаяся часть будет заполнена знаками пробела (20h).

При загрузке DOS на незнакомый компьютер буквенное обозначение текущего диска, назначаемое системой BIOS, бывает заранее неизвестно. Операция 3 программы Reassign.com поможет определить, какая буква назначена тому логическому диску, с которого производится загрузка:

set disk=33 Reassign disk

echo Current disk is %disk%

Подготовленное значение 33 переменной disk будет заменено буквой текущего диска, например, D:. Когда буква текущего диска известна, вся дальнейшая адресация в конфигурационных файлах может быть адаптирована автоматически.

Следующей проблемой адаптивных процедур загрузки является определение размера RAM-диска, на который должна быть перенесена DOS, поскольку заранее объем памяти компьютера обычно неизвестен. Но функция 1 программы

Reassign.com даст ответ:

set xms=11111 Reassign xms

echo Largest free XMS memory block is %xms% kb

Последняя строка приведенного примера покажет результат на экране. Теперь Вы готовы задать размер RAM-диска, и программа Reassign.com примет задаваемое Вами значение посредством своей функции 2:

echo Specify the size of RAM-disk in kb: set ramdisk=22222

Reassign ramdisk

Tdsk.exe R: %ramdisk% 512 /M /F:2

В ходе исполнения операции 2 программа Reassign.com пригласит Вас ввести желаемое значение. Неправильно набранные знаки можно убрать нажатием

– 510 –

Глава 9: Примеры композиции исполняемых файлов

клавиши Backspace. Ввод данных закончится по нажатию клавиши ENTER. В

последней строке приведенного примера введенное Вами значение будет подставлено в перечень параметров программы Tdsk.exe (5.05-02), которая создаст RAM-диск указанного объема. Конечно, найдется много других поводов применить программу Reassign.com, помимо тех, которые показаны здесь.

Важно отметить, что все представленные выше примеры не будут работать из командных строк файл-менеджеров NC (Norton Commander), VC (Volcov Commander) и тому подобных. Причина в том, что файл-менеджеры, как правило, исполняют каждую строку в отдельном пространстве окружения, вследствие чего значения переменных, заданные командой SET, от предшествующей строки к следующей не передаются. Но в обычной "чистой" командной строке DOS и в составе batch-файлов команды исполняются в общем пространстве окружения, так что ввод данных во всех представленных примерах будет происходить правильно.

Программа REASSIGN.COM получается в результате исполнения отладчиком DEBUG.EXE последовательности команд. Эту последовательность надо записать в текстовый командный файл REASSIGN.SCR с помощью программы редактирования текстов, как показано во вводной статье к главе 9. Словесные комментарии при наборе текста можно опустить. Обратите внимание на пустую строку в ассемблерном тексте – восьмую с конца. Она выводит отладчик из режима ассемблирования (7.01-04) и потому в файле REASSIGN.SCR обязательно должна быть сохранена. Затем файл REASSIGN.SCR надо переслать на исполнение отладчику DEBUG.EXE через перенаправление ввода, например, так:

Debug.exe < Reassign.scr

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

a 100

;************* Программа Reassign.com **************

;********* Секция 1: начальные приготовления ; 110 - адрес перехода со строки 104

cmp

SP,2010

; 100

Выделено

менее 8 кбайт?

jbe

0110

;*104

Åñëè äà,

оставим как есть

mov

SP,1FFE

; 106

Вершину стека - на 8 кбайт

mov

BX,0200

; 109

Запросим

8 кбайт памяти

mov

AH,4A

; 10C

Вызов функции создания

int

21

; 10E

 

свободного MCB

mov

DX,03A8

;=110

Сообщение 4 (help)

cmp byte ptr

[005D],20

; 113

1-é áàéò

в FCB заполнен?

jz

0151

;*118

Если нет, выведем help

– 511 –

Глава 9:

Примеры композиции исполняемых файлов

cmp byte ptr

[005D],3F

; 11A

1-й байт - знак вопроса?

jz

0151

 

;*11F

Если да, выведем help

cld

 

 

; 121

Зададим счет вверх (DF=UP)

;********** Секция 2: Результаты поиска переменной

call

0173

 

;*122

Вызовем подпрограмму поиска

cmp byte ptr

[0165],F7

; 125

Ошибки 1-го и 2-го циклов?

ja

0151

 

;*12A

Выйдем, если имеются

mov

DX,0345

 

;*12C

Введем адрес 2-го сообщения

les

DI,[00F8]

; 12F

Адрес переменной - в ES:DI

ES:

 

 

; 133

Считываем 1-й знак

mov

BL,[DI]

 

; 134

значения переменной

cmp

BL,31

 

; 136

Нижняя граница: функция 1

jb

0151

 

;*139

Выйдем, если значение меньше

cmp

BL,33

 

; 13B

Верхняя граница: функция 3

ja

0151

 

;*13E

Выйдем, если значение больше

shl

BL,1

 

; 140

x2, т.к. адрес - это 2 байта

mov

BH,00

 

; 142

Подготовим BX к переходу

call

[BX+0105]

;*144

Вызов основных функций

jz

0151

 

;*148

ZR - вывод сообщения

jb

015F

 

;*14A

CY - errorlevel èç DH

;************* Секция 3: завершение программы.

;151 - переходы от 118, 11F, 12A, 139, 13E, 148

;15F - адрес перехода со строк 14A, 14F

call

01F9

;*14C

Подпрограмма копирования

jmp

015F

;*14F

Переход к завершению

mov

BX,DX

;=151

DS:DX - адрес сообщения

mov

CX,[BX-02]

; 153

CX = число знаков

mov

BX,0001

; 156

BX = ссылка на STDOUT

mov

AH,40

; 159

Вызов функции посылки

int

21

; 15B

сообщения в STDOUT

mov

DH,F0

; 15D

Errorlevel = F0h

mov

AL,DH

;=15F

Восстановим errorlevel

mov

AH,4C

; 161

Вызов функции

int

21

; 163

завершения программы

 

;************** Секция 4: блок данных.

 

; 165 - адрес записи в 125, 1D1, 1D6, 1F4, 205

dw

00FC

 

 

;167 = (2*31 + 105) в строке 144, 221, 22D

;169 - в строках 225, 236, 240, 247, 252, 280 dw 0213,029A,02DC,0000,0000,0000

;************** Секция 5: поиск и проверка PSP

;173 - адрес вызова от строк 122, 1A3

;19F - адрес перехода со строки 197

;1A6 - переходы от строк 17A, 183, 18F, 19D

–512 –

Глава 9:

Примеры композиции исполняемых файлов

xor

DI,DI

 

;=173

Обнулим регистр DI

ES:

 

 

; 175

Начинается ли сегмент

cmp word ptr

[DI],20CD

; 176

с команды CD20?

jnz

01A6

 

;*17A

Выйдем, если PSP не опознан

ES:

 

 

; 17C

Имеется ли команда CD21 в

cmp word ptr

[0050],21CD

; 17D

ячейке 0050h?

jnz

01A6

 

;*183

Выйдем, если PSP не опознан

push

ES

 

; 185

Сохраним адрес PSP

ES:

 

 

; 186

Загрузим сегментный адрес

mov

ES,[002C]

; 187

окружения в регистр ES

call

01B3

 

; 18B

Подпрограмма поиска имени

pop

ES

 

; 18E

Восстановим адрес PSP в ES

jz

01A6

 

;*18F

Выйдем, если имя не найдено

mov

AX,ES

 

; 191

Сегментный адрес PSP - в AX

mov

DI,0016

 

; 193

Равен ли адрес в ES:[0016]

scasw

 

 

; 196

адресу данного PSP в AX?

jnz

019F

 

;*197

Если нет, это PSP-родитель

mov

DI,0010

 

; 199

Равен ли адрес в ES:[0010]

scasw

 

 

; 19C

адресу данного PSP в AX?

jz

01A6

 

;*19D

Если да, ничего мы не нашли

ES:

 

 

;=19F

Загрузим в ES сегментный

mov

ES,[DI-02]

; 1A0

адрес родительского PSP

call

0173

 

; 1A3

Вызовем проверку этого PSP

ret

 

 

;=1A6

Возврат из подпрограммы

;************* Секция 6: подпрограмма поиска имени

;1A7 - адрес перехода со строк 1C8, 1CF

;1B3 - адрес вызова со строки 18B

;1DF - адрес перехода со строк 1B1, 1BA

mov

CX,0100

;=1A7

Зададим число

сравнений

mov

AL,00

; 1AA

Сравниваем со

значением 00

repnz

 

; 1AC

Повтор, пока не найдем 00

scasb

 

; 1AD

Сравниваем [ES:DI] с AL=00

cmp

CX,0000

; 1AE

Если число сравнений

jz

01DF

;*1B1

исчерпано,

кончаем поиск

mov

DX,0318

;=1B3

Точка входа в

цикл поиска

ES:

 

; 1B6

Если [DI]==00h, значит

cmp byte ptr

[DI],00

; 1B7

окружение просмотрено

jz

01DF

;*1BA

все, кончаем поиск

mov

SI,005D

; 1BC

Адрес имени -

â DS:SI

mov

CX,000A

; 1BF

Зададим число

сравнений в CX

repz

 

; 1C2

Повтор до первого различия

cmpsb

 

; 1C3

Сравниваем [DS:SI] с [ES:DI]

cmp byte ptr

[SI-01],20

; 1C4

Имя кончается

пробелом?

jnz

01A7

;*1C8

Перейдем к следующему имени

 

 

 

– 513 –

 

Глава 9:

Примеры композиции исполняемых файлов

ES:

 

 

; 1CA Стоит ли после имени

cmp byte ptr

[DI-01],3D

; 1CB

знак равенства?

jnz

01A7

 

;*1CF Перейдем к следующему имени

sub byte ptr

[0165],04

;*1D1 Сдвиг адреса записи

mov

SI,[0165]

;*1D6 Адрес записи - в регистр SI

mov

[SI],DI

 

; 1DA Адрес значения переменной

mov

[SI+02],ES

; 1DC Сегментный адрес окружения

ret

 

 

;=1DF Возврат из подпрограммы

;******** Секция 7: подпрограмма копирования

;1E0 - адрес перехода со строки 210

;1E5 - адрес перехода со строки 1F1

;1F3 - адрес перехода со строк 1E9, 1EE

;1F9 - адрес вызова со строки 14C

;1FB - адрес перехода со строки 202

;204 - адрес перехода со строки 1FF

CS:

 

;=1E0

Загрузим

адрес источника

lds

SI,[00F8]

; 1E1

 

в регистры DS:SI

ES:

 

;=1E5

Есть ли еще место

cmp byte ptr

[DI],00

; 1E6

ïî

адресу назначения?

jz

01F3

;*1E9

Åñëè íåò

- в следующий цикл

cmp byte ptr

[SI],00

; 1EB

Есть ли знаки в источнике?

jz

01F3

;*1EE

Åñëè íåò

- в следующий цикл

movsb

 

; 1F0

Скопируем один байт

jmp

01E5

;*1F1

Проверим

следующий байт

CS:

 

;=1F3

Сменим адрес

add word ptr

[0165],0004

; 1F4

назначения

mov

AL,20

;=1F9

Точка входа в подпрограмму

ES:

 

;=1FB

Есть ли место

cmp byte ptr

[DI],00

; 1FC

по адресу заполнения?

jz

0204

;*1FF

Если нет, кончим заполнять

stosb

 

; 201

Пробел -

в адрес назначения

jmp

01FB

;*202

Проверим

следующий байт

CS:

 

;=204

Загрузим

номер

mov

SI,[0165]

; 205

 

ячейки в SI

CS:

 

; 209

Загрузим

адрес назначения

les

DI,[SI]

; 20A

 

в регистры ES:DI

cmp

SI,00F8

; 20C

Номер ячейки - последний?

jnz

01E0

;*210

Åñëè íåò

- возврат в цикл

ret

 

; 212

Возврат из подпрограммы

;****** Секция 8: функция 1, объем XMS-памяти

;213 - адрес вызова в ячейке 167

;256 - адрес перехода со строк 23E, 247, 250

;25B - адрес перехода со строки 263

;269 - адрес перехода со строки 277

–514 –

Глава 9: Примеры композиции исполняемых файлов

;275 - адрес перехода со строки 272

;284 - адрес перехода со строки 27E

;285 - адрес перехода со строк 21A, 234

mov

AX,4300

;=213

Точка входа в функцию 1

int

2F

; 216

Проверим, установлен ли

cmp

AL,80

; 218

XMS-драйвер Himem.sys?

jnz

0285

;*21A

Выйдем, если не установлен

mov

AX,4310

; 21C

Запрос адреса вызова

int

2F

; 21F

Адрес вызова - в ES:BX

mov

[0167],BX

; 221

Смещения адреса вызова

mov

[0169],ES

; 225

Сегмент адреса вызова

mov

BL,00

; 229

Зададим 00h в регистре BL

mov

AH,08

; 22B

Код запроса объема

call far

[0167]

; 22D

Запрос к Himem.sys

cmp

BL,00

; 231

Запрос исполнен успешно?

jnz

0285

;*234

Выйдем, если не успешно

mov byte ptr

[0169],00

; 236

Зададим errorlevel = 00

cmp

AX,1900

; 23B

если XMS-памяти для

jb

0256

;*23E

6 Mb диска недостаточно

inc byte ptr

[0169]

; 240

Зададим errorlevel = 01

cmp

AX,4900

; 244

åñëè 5600 Kb XMS-äèñê

jb

0256

;*247

может быть создан

inc byte ptr

[0169]

; 249

Зададим errorlevel = 02

cmp

AX,8C00

; 24D

если XMS-диск ограничен

jb

0256

;*250

объемом 16 Mb, а если

inc byte ptr

[0169]

; 252

íåò, òî errorlevel = 03

mov

BP,SP

;=256

Фиксируем состояние SP

mov

BX,000A

; 258

Зададим делитель

xor

DX,DX

;=25B

Очистим DX перед делением

div

BX

; 25D

Разделим на 0Ah

push

DX

; 25F

Затолкнем остаток в стек

cmp

AX,0000

; 260

Процесс деления закончен?

jnz

025B

;*263

Если нет - следующий цикл

les

DI,[00F8]

; 265

Адрес переменной - в ES:DI

pop

AX

;=269

Вытолкнем разряд из стека

add

AL,30

; 26A

Переведем цифру в код ASCII

mov

SI,DI

; 26C

SI фиксирует факт записи

ES:

 

; 26E

Есть ли свободное место

cmp byte ptr

[DI],00

; 26F

по адресу назначения?

jz

0275

;*272

Обойдем запись, если нет

stosb

 

; 274

Запишем цифру, увеличим DI

cmp

SP,BP

;=275

Все остатки вытолкнуты?

jb

0269

;*277

Если нет, вытолкнем еще

mov

DX,036F

;*279

3-е сообщение об ошибке

 

 

 

– 515 –

 

Глава 9:

Примеры композиции исполняемых файлов

cmp

DI,SI

 

; 27C Áûëà ëè

запись пропущена?

jz

0284

 

;*27E

 

 

 

mov

DH,[0169]

; 280 Считаем

errorlevel â DH

ret

 

 

;=284

 

 

 

mov

DH,FF

 

;=285 Errorlevel

= FF

stc

 

 

; 287

Завершение

с ошибкой

ret

 

 

; 288

Возврат

èç

подпрограммы

;******* Секция 9: функция 2, ввод с клавиатуры

;289 - адрес перехода со строки 2AD

;29A - переходы от 169, 28D, 291, 295, 2B4, 2BD

;2BF - адрес перехода со строки 2A8

;2C7 - адрес перехода со строк 2A3, 2C3

ES:

 

;=289

Сначала проверим,

cmp byte ptr

[DI],00

; 28A

заполнен ли буфер

jz

029A

;*28D

Åñëè äà, æäåì 1Bh, 0Dh, 08h

cmp

AL,20

; 28F

Знаки ниже 20h в

jb

029A

;*291

переменную не вводим

cmp

AL,3D

; 293

Знак равенства в

jz

029A

;*295

переменную не вводим

int

29

; 297

Отобразим введенный знак

stosb

 

; 299

Копируем знак в буфер ES:DI

mov

AH,10

;=29A

Точка входа в функцию 2

int

16

; 29C

Считываем знак с клавиатуры

mov

DH,FF

; 29E

Errorlevel = FFh

cmp

AH,01

; 2A0

Нажата ли клавиша ESC?

jz

02C7

;*2A3

Если да, то не копируем

cmp

AH,1C

; 2A5

Нажата ли клавиша ENTER?

jz

02BF

;*2A8

Если да, выходим и копируем

cmp

AH,0E

; 2AA

Нажата клавиша BackSpace?

jnz

0289

;*2AD

Если нет, вернемся в цикл

ES:

 

; 2AF

Проверим, не будет ли адрес

cmp byte ptr

[DI-01],3D

; 2B0

в регистре DI указывать

jz

029A

;*2B4

на точку до начала буфера

mov

AX,2008

; 2B6

Вывод знака возврата и

call

02D2

;*2B9

пробела через INT 29

dec

DI

; 2BC

Уменьшим указатель в DI

jmp

029A

;*2BD

Вернемся к началу цикла

cmp

DI,[00F8]

;=2BF

Изменилось ли число в DI?

jz

02C7

;*2C3

Если нет, оставим DH = FFh

mov

DH,00

; 2C5

Если да, установим DH = 00

mov

AX,0A0D

;=2C7

Вывод знаков перевода

call

02D2

;*2CA

строки через INT 29

cmp

DH,20

; 2CD

Установим флаги

cmc

 

; 2D0

Реверсируем флаг переноса

 

 

 

– 516 –

Глава 9: Примеры композиции исполняемых файлов

ret

 

; 2D1

Возврат из подпрограммы

 

;***** Секция 10: функция 2, подпрограмма вывода

 

; 2D2 - адрес вызова со строк 2B9, 2CA

 

; 2D5 - адрес возврата в цикле со строки 2D9

mov

CX,0003

;=2D2

Установим число повторений

int

29

;=2D5

Выведем знак на экран

xchg

AL,AH

; 2D7

Обменяем коды знаков

loop

02D5

;*2D9

Проверим условие цикла

ret

 

; 2DB

Возврат из подпрограммы

 

;***** Секция 11: функция 3, определение буквы диска

;2DC - записан в ячейку 16B

;2EE - адрес перехода со строки 2E9

;2F6 - адрес перехода со строки 30C

;305 - адрес перехода со строки 2FE

;30E - адрес перехода со строк 2F9 и 308

mov

AH,19

;=2DC

Точка входа в функцию 3

int

21

; 2DE

Определим текущий диск

mov

DL,AL

; 2E0

Скопируем номер диска в DL

add

AL,41

; 2E2

Преобразуем в букву диска

stosb

 

; 2E4

Скопируем букву в ES:DI

ES:

 

; 2E5

и увеличим число в DI

cmp byte ptr

[DI],00

; 2E6

Проверим, заполнен ли буфер

jz

02EE

;*2E9

Если да, не добавим ":"

mov

AL,3A

; 2EB

Введем код ":" в AL

stosb

 

; 2ED

Скопируем ":" в буфер ES:DI

mov

DH,00

;=2EE

Предустановим errorlevel

push

DI

; 2F0

Сохраним DI в стеке

mov

AX,0803

; 2F1

Запрос адреса 1-й DDT

int

2F

; 2F4

Адрес 1-й DDT - в DS:DI

cmp

[DI+04],AL

;=2F6

Это флоппи-диск?

ja

030E

;*2F9

Если нет, то дальше не ищем

cmp

[DI+04],AH

; 2FB

Если дисковод тот же,

jz

0305

;*2FE

то его не учитываем

mov

AH,[DI+04]

; 300

Запомним номер дисковода

inc

DH

; 303

Увеличим число дисководов

cmp word ptr

[DI],FFFF

;=305

Данная DDT - последняя?

jz

030E

;*308

Если да, то дальше не ищем

lds

DI,[DI]

; 30A

Адрес следующей DDT в DS:DI

jmp

02F6

;*30C

Исследуем DDT дальше

pop

DI

;=30E

Восстановим DI

push

CS

; 30F

Восстановим первоначальное

pop

DS

; 310

состояние DS

cmp

DH,FF

; 311

Сбросим флаг ZF в NZ

clc

 

; 314

Сбросим флаг переноса

 

 

 

– 517 –

Глава 9: Примеры композиции исполняемых файлов

ret

 

; 315 Возврат из подпрограммы

 

;********************* Секция 12: тексты сообщений

dw

002B

 

; 318 - 1-е сообщение, вызвано от 1B3

db

0D

0A 'ERROR: specified name hasn'

db

27

't been found' 0D 0A

dw

0028

 

; 345 - 2-е сообщение, вызвано от 12C

db

0D

0A 'ERROR: invalid value of the'

db

20

'variable' 0D 0A

dw

0037

 

; 36F - 3-е сообщение, вызвано от 279

db

0D

0A 'ERROR: no space for new value,'

db

20

'old one is too short' 0D 0A

dw

0138

 

; 3A8 - 4-е сообщение (help), вызвано от 110

db

0D

0A 09 'Reassign.com overwrites value'

db

20

'of existing variable' 0D 0A 'Usage:'

db

0D

0A 09 'Reassign Anyname' 0D 0A 'Anyn'

db

'ame - name example (up to 8 letters) o'

db

'f a variable' 0D 0A 'The first in its'

db

20

'value must be a digit 1, 2 or 3 - i'

db

't defines function:' 0D 0A 09 '1 - get'

db

20

'size of largest free XMS block' 0D 0A

db

09

'2 - accept keyboard' 27 's input' 0D

db

0A

09 '3 - get current disk letter' 0D 0A

 

; 4E0

 

n Reassign.com rbx

0000 rcx 03E0 w

q

Ассемблерный текст программы Reassign.com начинается в секции 1 с высвобождения памяти, которая заведомо не потребуется при исполнении программы (подробнее – в примечании 5 к A.12-7). Затем в строках 110 – 11F выполняется проверка параметров командной строки, которые командный интерпретатор автоматически впишет в первый блок FCB (примечание 4 к A.07-1), начиная со смещения 005Dh, причем там строчные буквы уже переведены в

– 518 –

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]