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

ВУЗ: Не указан

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

Просмотров: 29262

Скачиваний: 1690

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
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. Размещение файлов на экране 

 


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.  Произвести другие необходимые действия. 

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