Книга: О.А.Калашников. Ассемблер Это Просто. Учимся программировать

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
background image

Часть III. Файловая оболочка, вирус, резидент 

274 

Все  просто!  Более  того,  обратите  внимание,  что  и  перемещаться  по  каталогу  

в памяти достаточно удобно. Хотим получить имя пятого файла в цепочке? Произ-
водим нехитрые вычисления: 5  2 = 10. Умножаем на 2 потому, что смещение за-
нимает  2 байта.  Таким  образом,  получаем  смещение  пятого  файла  в  сегменте 

Seg_files

. Остается только вывести его на экран. 

Реально наша оболочка заносит не только имя файла + ASCII 0, но и его статус 

(текущий,  отмеченный)  и  размер.  Сюда  же  можно  добавить  еще  атрибуты  и  дату 
создания/изменения файла. 

Вот, собственно, и весь алгоритм. Теоретически все просто, но на практике мо-

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

28.3. Новые переменные в оболочке 

Рассмотрим  еще  несколько  новых  переменных,  которые  задействованы  в  обо-

лочке: 

Current_file 
Start_file 
Out_fstat 

Первая переменная 

Current_file

 хранит в себе смещение текущего файла, т. е. 

файла,  на  котором  установлен  курсор.  Так  удобней  и  быстрее  будет  искать  теку-
щий файл. 

Вторая  переменная 

Start_file

  содержит  смещение  файла,  с  которого  следует 

выводить  файлы  на  экран.  Наша  оболочка  может  отображать  на  экране  21 файл. 
Если  же  в  каталоге  больше  файлов,  то,  дойдя  до  нижнего или верхнего файла на 
экране, необходимо "прокрутить" список файлов. Верхний/нижний файл на экране 
убирается,  а  на  его  месте  появляется  следующий/предыдущий.  Переменная 

Start_file

  как  раз  и  будет  хранить  смещение  файла,  с  которого  нужно выводить 

на экран все последующие файлы.  

Обратите внимание, что под словом "прокрутка" понимается не так называемый 

скроллинг, а запись файлов поверх себя. Дело в том, что скроллинг осуществляется 
с помощью прерывания 

10h

, что существенно тормозит работу. Мы будем пользо-

ваться нашим способом, который не требует вызова прерывания. Назовем этот спо-
соб "псевдоскроллинг". 

Третья переменная 

Out_fstat

 хранит состояние вывода одного файла, а именно 

данные о том, чистить ли строку перед выводом или нет. Зачем чистить строку пе-
ред выводом файла? Предположим, что список файлов прокручивается на экране. 
Названия файлов будут размещаться на экране так, как показано в табл. 28.2. 

Таблица 28.2. Размещение файлов на экране 

M 

A 

I 

N 

. 

A 

S 

M 

O 

T 

H 

E 

R 

. 

A 

S 

M 

background image

Глава 28. Алгоритм считывания имен файлов в память 

275 

Таким образом, после прокрутки списка файлов вниз, название файла main.asm 

"ляжет" поверх названия other.asm, а на экране мы увидим буквально следующее: 

main.asmm 

От названия файла, которое располагалось на этом месте до прокрутки, останет-

ся символ "m". Чтобы избежать этого, мы перед выводом очередного файла чистим 
(забиваем пробелами) строку на экране. 

Переменная 

Out_fstat

  сообщает  процедуре  о  том,  следует  ли  чистить  строку 

перед тем, как вывести очередной файл или нет. Почему в одних случаях мы будем 
чистить строку на экране, а в других — нет? 

Если чистить строку каждый раз, то создастся эффект мерцания файлов на экра-

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

Например, пользователь нажимает клавишу <Insert> на названии верхнего фай-

ла, что приводит к отметке файла, т. е. на экране название будет выделено светло-
желтым цветом (рис. 28.4).  

Рис. 28.4. Выделение файла 

Делается это следующим образом. У нас существует процедура вывода файлов 

(

Out_files

,  files.asm),  которая  выводит  список  файлов,  начиная  с  позиции 

Start_file

 и до конца (либо всего 21 файл). Как уже отмечалось, в буфер заносит-

ся не только имя найденного файла, но и его статус, а все файлы изначально имеют 
нулевой статус, т. е. не являются ни отмеченными, ни текущими. После перечиты-
вания  каталога  мы  автоматически  делаем  первый  файл  текущим  (статус 1).  Теку-
щий файл
 — тот, на названии которого стоит курсор.  

Допустим, пользователь нажал клавишу <Insert>. Статус текущего файла меня-

ется на 2, файл становится отмеченным. Первый байт в буфере для файла (его ста-

background image

Часть III. Файловая оболочка, вирус, резидент 

276 

тус) отмечается как 2. Следующему файлу присваиваем статус 1 (текущий) и вызы-
ваем процедуру 

Out_files

. Процедура 

Out_files

 проверяет статус первого файла. 

Если это 1, то файл выводится с обычными атрибутами (как будто на него указыва-
ет курсор), если 2 — как отмеченный (светло-желтым цветом), если статус иной, то 
файл выводится и как отмеченный, и как текущий. И так с каждым файлом. 

Таким образом, присвоив нужный статус тому или иному файлу, мы вызываем 

процедуру 

Out_files

, которая обновит файлы на экране. 

Если не было "прокрутки" файлов, то мы вызываем 

Out_files

, при этом заносим  

в переменную 

Out_fstat

 число 0, указывая процедуре 

Out_files

 на то, что чистить 

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

Если же произошла прокрутка файлов, то вызываем процедуру 

Out_files

, при 

этом заносим в 

Out_fstat

 число 1, указывая процедуре чистить строку перед выво-

дом каждого файла.  

28.4. Обработка клавиш <PageUp>  
и <PageDown> 

При нажатии одной из этих клавиш программа имитирует нажатие клавиши < > 

или < > столько раз, сколько файлов отображено на экране. 

28.5. Обработка клавиш <Home> и <End> 

Процедуры 

Up_pressed

 и 

Down_pressed

 (нажатие клавиш < > и < >) устанавли-

вают флаг переноса, если достигнуты конец или начало списка файлов. Работа же 
самих процедур показана в листинге 28.3.  

Листинг 28.3. Процедуры обработки клавиш <Home> и <End> 

... 
; === Клавиша Home ASCII 49h === 
(01) K_Home proc 
;Выводить будем до тех пор, пока процедура Up_pressed не вернет 
;установленный флаг переноса (Carry Flag) 
(02) Next_khome: 
(03)     call Up_pressed 
(04)     jnc Next_khome 
(05)     ret 
(06) K_Home endp 
 
; === Клавиша End ASCII 49h === 
(07) K_end proc 
(08) Next_kend: 

background image

Глава 28. Алгоритм считывания имен файлов в память 

277 

(09)     call Down_pressed 
(10)     jnc Next_kend 
(11)     ret 
(12) K_End endp 
... 

Таким  образом,  нажатие  на  клавишу  <Home>  или  <End> —  не  что  иное,  как 

имитация нажатия клавиш < > или < > до тех пор, пока процедуры не достигнут 
начала или конца списка файлов. При достижении первого или последнего файла 
устанавливается флаг переноса, который сигнализирует о том, что больше файлов 
нет. Именно поэтому мы и вызываем процедуру нажатия клавиш < > или < > до 
тех пор, пока не будет установлен флаг переноса. 

background image

Глава 29 

Загрузка и запуск программ 

 
Данная глава полностью посвящена функции 

4Bh

 прерывания 

21h

. Эта функция 

выполняет загрузку и запуск программ. Запустить программу на ассемблере — за-
дача не такая простая, как может показаться с первого взгляда, и нередко по дан-
ной  теме  возникает  много  вопросов.  Поэтому  рассмотрим  запуск  программ  под-
робно. 

Обратите  внимание,  что  в  приложении  находятся  три  небольших  файла:  4bh-

1.asm,  4bh-2.asm  и  test.asm.  Но  не  спешите  их  сразу  ассемблировать  и  запускать! 
Желательно прочитать эту главу до конца. 

29.1. Подготовка к запуску программы  
и ее загрузка 

Прежде чем запустить программу, необходимо тщательно подготовиться, а именно: 

1.  Выделить память для загружаемой программы. 
2.  "Ужать" стек, если это COM-файл. 
3.  Сохранить необходимые регистры. 
4.  Подготовить EPB. 
5.  Подготовить строку с именем файла, который будем загружать. 
6.  Подготовить командную строку. 
7.  Сохранить сегментные регистры, если необходимо. 
8.  Сохранить стековые регистры 

ss

 и 

sp

 в переменных. 

9.  Запустить программу, вызвав прерывание 

21h

. 

С  момента  вызова  прерывания 

21h

  наша  программа  (родительская)  находится  

в памяти до тех пор, пока запущенная (порожденная) программа не отработает. Как 
только  последняя  завершила  работу,  управление  получает  наша  (родительская) 
программа. Дальше необходимо сделать следующее: 
1.  Восстановить стековые регистры 

ss

 и 

sp

. 

2.  Восстановить  сохраненные  в  стеке  регистры  (сегментные  и  пр.,  если  их  сохра-

няли). 

3.  Произвести другие необходимые действия. 

Вот, собственно, и все. 

Источник: https://files.student-it.ru/previewfile/2839