Assembler - язык неограниченных возможностей


Пассивная резидентная программа - часть 2


initialize proc near cmp byte ptr cmd_len,3 ; проверить размер командной строки jne not_install ; (должно быть 3 - пробел, диск, двоеточие), cmp byte ptr cmd_line[2],':' ; проверить третий символ jne not_install ; командной строки (должно быть двоеточие), mov al,byte ptr cmd_line[1] and al,11011111b ; преобразовать второй ; символ к заглавной букве, cmp al,'А' ; проверить, что это не jb not_install ; меньше "А" и не больше cmp al,'Z' ; "Z", ja not_install ; если хоть одно из этих условий ; не выполняется - выдать информацию ; о программе и выйти, иначе - начать ; процедуру инициализации mov ax,3521h ; АН = 35h, AL = номер прерывания int 21h ; получить адрес обработчика INT 21h mov word ptr old_int21h,bx ; и поместить его в old_int21h mov word ptr old_int21h+2,es

mov ax,2521h ; AH = 25h, AL = номер прерывания mov dx,offset int21h_handler ; DS:DX - адрес нашего обработчика int 21h ; установить обработчик INT 21h mov ah,49h ; AH = 49h mov es,word ptr envseg ; ES = сегментный адрес блока с нашей ; копией окружения DOS int 21h ; освободить память из-под окружения mov dx,offset initialize ; DX - адрес первого байта за концом ; резидентной части программы int 27h ; завершить выполнение, оставшись ; резидентом

not_install: mov ah,9 ; АН = 09h mov dx,offset usage ; DS:DX = адрес строки с информацией об ; использовании программы int 21h ; вывод строки на экран ret ; нормальное завершение программы

; текст, который выдает программа при запуске с неправильной командной строкой: usage db "Использование: tsr.com D:",0Dh,0Ah db "Запрещает удаление на диске D:",ODh,OAh db "$" initialize endp end start

Если запустить эту программу с командной строкой D:, никакой файл на диске D нельзя будет удалить командой Del, средствами оболочек типа Norton Commander и большинством программ для DOS. Действие этого запрета, однако, не будет распространяться на оболочку Far, которая использует системные функции Windows API, и на программы типа Disk Editor, обращающиеся с дисками при помощи функций BIOS (INT 13h). Несмотря на то что мы освободили память, занимаемую окружением DOS (а это могло быть лишних 512 или даже 1024 байта), наша программа все равно занимает в памяти 352 байта из-за того, что первые 256 байт отводятся для блока PSP. Существует возможность оставить программу резидентной без PSP — для этого инсталляционная часть программы должна скопировать резидентную часть с помощью, например, movs в начало PSP. Но при этом возникает сразу несколько проблем: во-первых, команда INT 27h, так же как и функция DOS 31h, использует данные из PSP для своей работы, во-вторых, код резидентной части должен быть написан для работы с нулевого смещения, а не со 100h, как обычно, и, в-третьих, некоторые программы, исследующие выделенные блоки памяти, определяют конец блока по адресу, находящемуся в PSP программы — владельца блока со смещением 2. С первой проблемой можно справиться вручную, создав отдельные блоки памяти для резидентной и инсталляционной частей программы, новый PSP для инсталляционной части и завершив программу обычной функцией 4Ch или INT 20h. Реальные программы, делающие это, существуют (например, программа поддержки нестандартных форматов дискет PU_1700), но мы не будем чрезмерно усложнять наш первый пример и скопируем резидентную часть не в позицию 0, а в позицию 80h, то есть, начиная с середины PSP, оставив в нем все значения, необходимые для нормальной работы функций DOS.




Начало  Назад  Вперед