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

Dos7book

.pdf
Скачиваний:
75
Добавлен:
09.02.2015
Размер:
5.1 Mб
Скачать

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

благодаря проверке в строке 1E5 для восстановления состояния линии A20 будут применены именно те средства, с помощью которых это состояние было изменено.

В начальных строках секции 9 производится выбор подходящего сообщения об успешном завершении программы. Команды в строках 20B – 215 выводят это сообщение на экран. Последним следует вызов стандартной функции завершения программы в строках 218 – 21A.

После своего завершения программа GS_limit.com оставит код уровня ошибки,

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

GS_limit on > nul

if errorlevel 7 echo Processor runs in V86 mode

if not errorlevel 7 echo Processor runs in real mode

Последняя особенность завершения программы GS_limit.com состоит в том, что независимо от характера выполненной операции число, оставляемое в регистре GS, сохраняет статус селектора. Это дает возможность экспериментировать с адресацией до тех пор, пока любой акт записи в регистр GS не вернет его содержимому обычный статус сегментного адреса.

9.10-02 Программа вывода дампа по линейному адресу.

Представленная здесь программа GS_dump.com показывает на экране 128-байтовый дамп участка памяти почти так же, как это делает отладчик Debug.exe в ответ на команду "D" (6.05-04). Главное отличие состоит в том, что для выведения дампа программа GS_dump.com использует не обычные адреса, состоящие из сегмента и смещения, а 32-битовые линейные адреса, позволяющие обращаться к любому участку 4-Гигабайтового адресного пространства, если, конечно, сегментная защита заранее отключена программой GS_limit.com (9.10-01).

Когда сегментная защита действует, программа GS_dump.com покажет дамп в "разрешенных" пределах относительно сегментного адреса в регистре GS. Если же заданный адрес вызовет срабатывание защиты, то на экран будет выведено соответствующее сообщение об ошибке.

Помимо очевидного демонстрационного эффекта, программа GS_dump.com предоставляет ответы на ряд нетривиальных вопросов, неизбежно возникающих при попытках практически осуществить линейную адресацию в DOS.

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

GS_dump.com FFFE0

– 559 –

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

Указанный адрес воспринимается как абсолютный, то есть отсчитываемый от нуля независимо от числа в регистре GS. Кроме адреса, в командной строке может быть указан один из двух допустимых дополнительных параметров:

A

не изменять состояние линии A20 адресной шины;

R

обнулить сегментный регистр GS.

Командная строка с дополнительным параметром выглядит, например, так

GS_dump.com FFFE0 A

Когда линия A20 не активна, вызов программы GS_dump.com с параметром "A" покажет "заворот" адресного пространства с адреса 100000h. По умолчанию программа GS_dump.com активизирует линию A20 и всегда показывает адресное пространство открытым независимо от ее исходного состояния.

Чтобы скомпилировать исполняемый файл программы GS_dump.com, нужно

набрать с помощью программы редактирования приведенный ниже ассемблерный текст и сохранить его в отдельном файле, например, под именем GS_dump.scr.

Словесные комментарии в ассемблируемых строках при наборе текста можно опустить. Обратите внимание на пустую строку в ассемблерном тексте восьмую с конца. Она выводит отладчик из режима ассемблирования (7.01-04) и потому в файле GS_dump.scr обязательно должна быть сохранена. Потом файл GS_dump.scr надо переслать на исполнение отладчику Debug.exe через перенаправление ввода, например, так:

Debug.exe < GS_dump.scr

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

a 100

 

 

 

 

;************* Программа GS_dump.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

push

CS

;=110

Подготовим

pop

DS

; 111

DS = CS

db

66

 

 

– 560 –

Глава 9:

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

xor

BX,BX

 

; 113

Подготовим EBX=0

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

; 12F - адрес перехода со строки 125

pushf

 

 

; 115

Загрузим в стек 2 копии

pushf

 

 

; 116

исходного состояния флагов

pop

CX

 

; 117

Выгрузим копию в CX

xor

CH,70

 

; 118

Инвертируем биты 0C, 0D, 0E

push

CX

 

; 11B

Перешлем измененные биты

popf

 

 

; 11C

через стек в регистр

pushf

 

 

; 11D

флагов, а потом снова

pop

AX

 

; 11E

через стек в AX

popf

 

 

; 11F

Вернем исходные состояния

xor

AX,CX

 

; 120

Установим несовпавшие биты

test

AH,40

 

; 122

Наш процессор 16-битовый?

jz

012F

 

;*125

Если нет, проверим защиту

mov

AL,02

 

; 127

Если да, то переход на

mov

DX,03D6

 

;*129

выход с индикацией

jmp

02BF

 

;*12C

сообщения 03D6

test

AH,30

 

;=12F

Установлен защищенный режим?

jz

0163

 

;*132

Если нет, обойдем секцию 3

;********* Секция 3: проверки защищенного режима

; 14B - адрес перехода со строки 141

mov word ptr

[03D4],0483

;*134

Изменим адрес сообщения

mov

AX,1687

 

; 13A

Вызов функции обнаружения

int

2F

 

; 13D

сервера DPMI

or

AX,AX

 

; 13F

Сервер DPMI загружен?

jnz

014B

 

;*141

Если нет, перейдем дальше

mov

AL,08

 

; 143

Если да, то выход из

mov

DX,03FB

 

;*145

программы с индикацией

jmp

02BF

 

;*148

сообщения 03FB

push

DS

 

;=14B

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

mov

DS,BX

 

; 14C

Сегмент таблицы прерываний

mov

DS,[019E]

; 14E

Загрузим сегмент EMM

cmp word ptr

[0014],4249

; 152

Версия EMM от фирмы IBM ?

pop

DS

 

; 158

Восстановим сегмент DS

jz

0163

 

;*159

Продолжим, если EMM от IBM

mov

AL,02

 

; 15B

Если нет, то выход из

mov

DX,041E

 

;*15D

программы с индикацией

jmp

02BF

 

;*160

сообщения 041E

;********* Секция 4: получение линейного адреса

;163 - адрес перехода со строк 132, 159

;16A - адрес назначения цикла со строки 19C

;17B - адрес перехода со строки 175

;188 - адрес перехода со строки 17E

561 –

 

Глава 9:

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

 

; 194 - адрес перехода со строк 16F, 179

mov

CX,0004

;=163

Установим сдвиг 4 бита

cld

 

; 166

Счет SI на увеличение

mov

SI,005D

; 167

Зададим стартовый адрес

lodsb

 

;=16A

Загрузим один байт в AL

sub

AL,30

; 16B

Преобразуем знак ASCII

cmp

AL,09

; 16D

Если это десятичная цифра,

jbe

0194

;*16F

то добавим ее к EBX

sub

AL,07

; 171

Преобразуем коды букв A-F

cmp

AL,0A

; 173

Отсечем знаки до буквы A

jb

017B

;*175

Перейдем выяснять причину

cmp

AL,0F

; 177

Выберем буквы A-F и

jbe

0194

;*179

добавим к числу в EBX

cmp

SI,005E

;=17B

Это первая итерация?

jnz

0188

;*17E

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

mov

AL,01

; 180

Если да, то выход из

mov

DX,04F1

;*182

программы с индикацией

jmp

02BF

;*185

сообщения 04F1

cmp

AL,E9

;=188

Последний знак - пробел 20h?

jz

019E

;*18A

Тогда все, больше знаков нет

mov

AL,01

; 18C

Если знак - не пробел, то

mov

DX,04CB

;*18E

выход из программы с

jmp

02BF

;*191

выводом сообщения 04CB

 

 

;=194

Префикс 32-битового операнда

db

66

 

 

shl

BX,CL

; 195

Сдвиг EBX 4 бита влево

or

BL,AL

; 197

Вставим знак в регистр BL

cmp

SI,0064

; 199

Достигнута ли 8-я итерация?

jbe

016A

;*19Ñ

Если нет, повторить цикл

;********* Секция 5: активизация линии A20

;19E - адрес перехода со строки 18A

;1С3 - адрес перехода со строки 1AС

;1D3 - адрес перехода со строки 1A3

;1D8 - адрес перехода со строки 1C6

cmp byte ptr

[006D],41

;=19E

Имеется ли параметр "A"?

jz

01D3

;*1A3

Если да, оставим линию A20

mov

AX,4300

; 1A5

Теперь посмотрим,

int

2F

; 1A8

установлен ли

cmp

AL,80

; 1AA

драйвер

Himem.sys

jnz

01C3

;*1AC

Åñëè íåò, òî

переход

push

BX

; 1AE

Сохраним значение BX

mov

AX,4310

; 1AF

Найдем адрес

вызова

int

2F

; 1B2

функций

Himem.sys

mov

[03C0],BX

;*1B4

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

 

 

 

– 562 –

 

Глава 9:

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

mov

[03C2],ES

;*1B8

функций Himem.sys

mov

AH,05

 

; 1BC

Вызовем функцию

call far

[03C0]

 

;*1BE

активизации линии A20

pop

BX

 

; 1C2

Восстановим значение BX

call

02D3

 

;=1C3

Активна ли линия A20?

jnz

01D8

 

;*1C6

Если да, то переход

mov word ptr

[03C2],0001

;*1C8

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

mov

AL,FF

 

; 1CE

Активизируем линию A20

call

02EB

 

;*1D0

подпрограммой 02EB

call

02D3

 

;=1D3

Активна ли линия A20?

jz

01DD

 

;*1D6

Если да, дезактивируем

mov byte ptr

[0445],24

;=1D8

сообщение 0445

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

;1DD - адрес перехода со строки 1D6

;1E6 - адрес перехода со строки 1E2

cmp byte ptr

[006D],52

;=1DD

Параметр "R" указан?

jz

01E6

;*1E2

Если да, не считываем GS

 

 

 

; 1E4

= MOV SI,GS

db

8C

EE

 

 

 

 

 

;=1E6

= MOV GS,SI

db

8E

EE

 

 

 

 

 

; 1E8

= PUSH GS

db

0F

A8

 

 

pop

[03D0]

;*1EA

Запомним GS в 3D0

call

0339

;*1EE

Пошлем 0Dh 20h в STDOUT

call

0349

;*1F1

Выведем 3D0 на экран

mov

DX,0445

;*1F4

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

call

0330

;*1F7

сообщение 0445

mov

DX,045B

;*1FA

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

call

0330

;*1FD

сообщение 045B

;********* Секция 7: вычисление начала отсчета

db

66

 

 

 

xchg

SI,BX

; 201

Переведем адрес в ESI

mov

BX,SI

; 203

Вернем в BX только 2 байта

and

BX,000F

; 205

Выберем самую правую цифру

neg

BL

 

; 209

Получим начало отсчета

and

SI,FFF0

; 20B

Теперь ESI - базовый адрес

db

66

 

 

 

mov

DI,SI

; 210

Скопируем ESI в EDI

db

66

 

 

 

xchg

[03D0],DI

;*213

Обменяем GS с EDI

db

66

 

 

 

shl

DI,CL

; 218

В EDI - линейный адрес GS

mov

DX,[03D4]

;*21A

Подготовим номер сообщения

 

 

 

 

– 563 –

 

Глава 9:

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

db

66

 

 

 

sub

SI,DI

; 21F

Вычислим смещение

â ESI

jnb

0226

;*221 Если меньше нуля,

сменим

mov

DX,0460

;*223

номер сообщения

íà 0460

;********* Секция 8: замена флагов и указателей ; 226 - адрес перехода со строки 221

 

 

;=226

Префикс 32-битного операнда

db

66

 

 

pushf

 

; 227

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

mov

BP,SP

; 228

Указатель стека - в BP

mov

AL,[BP+02]

; 22A

Считаем и сохраним

mov

[03C4],AL

;*22D

третий байт флагов

and byte ptr

[BP+02],FE

; 230

Сбросим флаг выравнивания

db

66

 

 

popf

 

; 235

EFLAGS - обратно во флаги

in

AL,21

; 236

Считаем маску порта 21h

mov

[03C5],AL

; 238

и запомним ее

or

AL,60

; 23B

Установим биты 05 и 06

out

21,AL

; 23D

Запретим IRQ5 и IRQ6

mov

[03C8],DS

;*23F

Заполним сегменты в адресах

mov

[03CC],DS

;*243

обработчиков прерываний

push

BX

; 247

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

mov

AL,0D

; 248

Заменим адреса обработчиков

call

03A0

;*24A

прерывания INT 0D

call

03A0

;*24D

и прерывания INT 0E

pop

BX

; 250

Восстановим содержимое BX

;********* Секция 9: пробное считывание

; 251 - адрес назначения цикла со строки 289

mov

[03CE],SI

;=251

Сохраним SI для сравнения

db

65 67

 

 

lodsb

 

; 257

Попытаемся считать байт

cmp

SI,[03CE]

;*258

Изменилось ли значение SI?

jnz

0266

;*25C

Если да - в основной цикл

call

0342

;*25E

Индицируем линейный адрес

call

0321

;*261

Вычислим следующий адрес

jmp

0286

;*264

Переход к проверке адреса

;********* Секция 10: основной цикл вывода строки

;266 - адрес перехода со строки 25C

;26E - адрес назначения цикла со строки 273

;278 - адрес назначения цикла со строки 27D

;286 - адрес перехода со строки 264

 

 

;=266

Префикс 32-битного

операнда

db

66

 

 

 

dec

SI

; 267

Восстановим индекс

â SI

 

 

 

– 564 –

 

Глава 9:

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

call

0349

 

;*268

Индицируем линейный адрес

call

0318

 

;*26B

Промежуточная коррекция

call

0362

 

;=26E

Индицируем байт из AL

inc

BL

 

; 271

Увеличим счет байтов на 1

loop

026E

 

;*273

1-й цикл вывода строки

call

0309

 

;*275

Промежуточная коррекция

call

0379

 

;=278

Индицируем байт кодом ASCII

inc

BL

 

; 27B

Увеличим счет байтов на 1

loop

0278

 

;*27D

2-й цикл вывода строки

call

0339

 

;*27F

Пошлем 0Dh 20h в STDOUT

mov

DX,[03D4]

;*282

Заменим адрес сообщения

cmp

BL,80

 

;=286

Данная строка последняя?

jb

0251

 

;*289

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

;********* Секция 11: возврат к исходному состоянию

; 2B4 - адрес перехода со строки 2AB

mov

AL,0D

 

; 28B

Восстановим обработчики

call

03A0

 

;*28D

прерывания INT 0D

call

03A0

 

;*290

и прерывания INT 0E

mov

AL,[03C5]

;*293

Считаем прежнюю маску и

out

21,AL

 

; 296

пошлем ее в порт 21h

db

66

 

 

 

pushf

 

 

; 299

Считаем EFLAGS в стек

mov

BP,SP

 

; 29A

Указатель стека - в BP

mov

AL,[03C4]

;*29C

Считаем и восстановим

mov

[BP+02],AL

; 29F

прежний 3-й байт флагов

db

66

 

 

 

popf

 

 

; 2A3

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

cmp word ptr

[03C2],0001

;*2A4

Проверим метку линии A20

jb

02BA

 

;*2A9

Если 0000, A20 не трогаем

ja

02B4

 

;*2AB

К A20 - с помощью Himem.sys

mov

AL,FD

 

; 2AD

Восстановим A20 с помощью

call

02EB

 

;*2AF

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

jmp

02BA

 

;*2B2

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

mov

AL,06

 

;=2B4

Вызов функции закрытия A20

call far

[03C0]

 

;*2B6

драйвером Himem.sys

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

;2BA - адрес перехода со строк 2A9, 2B2

;2BF - выход со строк 12C, 148, 160, 185, 191

mov

DX,0442

;=2BA

Сообщение "конец строки"

mov

AL,00

; 2BD

Код успешного завершения

push

AX

;=2BF

Сохраним код ошибки

mov

AH,09

; 2C0

Вывод завершающего

int

21

; 2C2

сообщения на экран

pop

AX

; 2C4

Восстановим код ошибки

 

 

 

– 565 –

 

Глава 9:

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

mov

AH,4C

;

2C5

Вызов функции завершения

int

21

;

2C7

и возврат в DOS

 

;******* Секция 13: обработчики исключений 0D и 0E

;2C9 - должен быть указан в ячейке 3CA

;2CC - должен быть указан в ячейке 3C6

mov

DX,04A5

;=2C9

Адрес вызова Int 0E

mov

BP,SP

;=2CC

Адрес вызова Int 0D

add word ptr

[BP+00],+03

; 2CE

Корректируем адрес

iret

 

; 2D2

возврата и возвращаемся

;******** Секция 14: проверка состояния линии A20

; 2D3 - адрес вызова из строк 1C3, 1D3

push

DS

;=2D3

Сохраним состояния

push

CX

; 2D4

регистров DS и CX

db

66

 

 

xor

SI,SI

; 2D6

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

push

SI

; 2D8

Сохраним в стеке SI=0

mov

DS,SI

; 2D9

Теперь DS:SI=0000:0000

mov

DI,F0F1

; 2DB

Установим ES:DI=F0F1:F0F0

mov

ES,DI

; 2DE

чтобы получить адрес

dec

DI

; 2E0

F0F10h + F0F0h = 100000h

cld

 

; 2E1

Зададим счет на увеличение

mov

CX,0010

; 2E2

Предел счета - 16 байт

repz

 

; 2E5

Повторяем до несовпадения

cmpsb

 

; 2E6

Адреса "свернуты" ?

pop

SI

; 2E7

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

pop

CX

; 2E8

регистров и возвращаемся,

pop

DS

; 2E9

сохраняя результат в

ret

 

; 2EA

состоянии флага ZF

 

;***** Секция 15: подпрограмма управления линией A20

 

; 2EB - адрес вызова из строк 1D0, 2AF

 

push

AX

;=2EB

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

call

02FD

;*2EC

Ждем готовности

 

mov

AL,D1

; 2EF

1-й байт команды

 

out

64,AL

; 2F1

посылаем в

ïîðò 64h

call

02FD

;*2F3

Ждем готовности

 

pop

AX

; 2F6

2-й байт команды из AX

out

60,AL

; 2F7

посылаем в

ïîðò 60h

call

02FD

;*2F9

Ждем пока контроллер

ret

 

; 2FC

сработает и

возвращаемся

 

;********* Секция 16: ожидание готовности контроллера

;2FD - адрес вызова из строк 2EC, 2F3, 2F9

;301 - адрес циклического возврата со строки 305

push

CX

;=2FD

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

mov

CX,FFFF

; 2FE

Запишем в CX число циклов

 

 

 

– 566 –

 

Глава 9:

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

in

AL,64

;=301 Считаем состояние порта 64h

test

AL,02

; 303

Проверим бит готовности

loopnz

0301

;*305 Если порт не готов, повторим

pop

CX

; 307

Восстановим CX и вернемся

ret

 

; 308

в вызывающую программу

;********* Секция 17: промежуточная коррекция

 

; 309 - адрес вызова из строки 275

 

; 318 - адрес вызова из строки 26B

sub

BL,10

;=309

Вернем счет на строку назад

push

BX

; 30C

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

mov

BL,10

; 30D

10h = величина приращения

db

66

 

 

add

[03D0],BX

;*310

Корректируем линейный адрес

db

66

 

 

sub

SI,BX

; 315

Скорректируем смещение

pop

BX

; 317

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

call

0393

;=318

Дважды пошлем знак

call

0393

;*31B

пробела в STDOUT

mov

CL,10

; 31E

Предустановим счет байтов

ret

 

; 320

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

;********* Секция 18: перевод строки дампа

;321 - адрес вызова из строки 261

;330 - адрес вызова из строк 1F7, 1FD

;339 - адрес вызова из строк 1EE, 27F

add

BL,10

;=321

Увеличим счет байтов на 16

push

BX

; 324

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

mov

BL,10

; 325

Зададим приращение на 16

db

66

 

 

add

[03D0],BX

;*328

Коррекция линейного адреса

db

66

 

 

add

SI,BX

; 32D

Коррекция смещения

pop

BX

; 32F

Восстановим содержимое BX

mov

DI,DX

;=330

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

mov

AH,09

; 332

Функция вывода

int

21

; 334

сообщения в STDOUT

mov byte ptr

[DI],24

; 336

Дезактивируем сообщение

mov

AL,0D

;=339

Пошлем команду возврата к

call

0395

;*33B

началу строки в STDOUT

call

0393

;*33E

Пошлем пробел в STDOUT

ret

 

; 341

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

;********* Секция 19: индикация числа из ячейки 3D0

;342 - адрес вызова из строки 25E

;349 - адрес вызова из строк 1F1, 268

;354 - адрес перехода со строки 35E

567 –

Глава 9:

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

; 361 - адрес перехода со строки 347

mov

DI,DX

;=342

Дезактивировано ли

cmp byte ptr

[DI],24

; 344

запрошенное сообщение?

jz

0361

;*347

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

mov

AL,0A

;=349

Пошлем команду перевода

call

0395

;*34B

строки в STDOUT

push

BX

; 34E

Сохраним содержимое BX

xor

BL,BL

; 34F

Отключим проверку предела

mov

DI,03D3

; 351

В DI - адрес старшего байта

mov

AL,[DI]

;=354

Выведем байт в AL

call

0368

;*356

Вызовем трансляцию байта AL

dec

DI

; 359

Перейдем к следующему байту

cmp

DI,03D0

;*35A

Это последний байт?

jnb

0354

;*35E

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

pop

BX

; 360

Восстановим содержимое BX

ret

 

;=361

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

;********* Секция 20: подпрограмма трансляции AL

 

; 362 - адрес вызова из строки 26E

 

; 368 - адрес вызова из строки 356

call

0393

;=362

Воспроизведем пробел

db

67 65

 

 

lodsb

 

; 367

GS:[32-битовый адрес]

push

CX

;=368

Сохраним содержимое CX

mov

CL,04

; 369

Сдвиг 4 бита зададим в CL

shl

AH,CL

; 36B

Очистим младшие 4 бита AH

shl

AX,CL

; 36D

Разделим полубайты из AL

shr

AL,CL

; 36F

Очистим старшие 4 бита AL

pop

CX

; 371

Восстановим содержимое CX

call

0384

;*372

Вызов индикации AH

call

0384

;*375

Вызов индикации AL

ret

 

; 378

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

;********* Секция 21: индикация одного знака

;379 - адрес вызова из строки 278

;384 - адрес вызова из строк 372, 375

;38E - адрес перехода со строк 37E, 382, 38A

;393 - адрес вызова из строк 318, 31B, 33E, 362

;395 - адрес вызова из 33B, 34B, переход от 391

 

 

;=379

Считаем в AL один знак из

db

67 65

 

 

lodsb

 

; 37B

GS:[32-битный адрес]

cmp

AL,20

; 37C

Значение до 20h или больше?

ja

038E

;*37E

Значения AL < 20h заменим

mov

AL,2E

; 380

точками и перейдем к

jmp

038E

;*382

проверке границ

 

 

 

– 568 –

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