РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты по данной тематике Номер выпуска: | 1564 | Дата выхода: | 22.09.2015, 14:21 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 13 / 5 | Вопросов / ответов: | 1 / 1 | Консультация # 188037: Разбираю код программы из учебника, программа формирует log-файл(report.txt) действий пользователя. В самом log-файле будут записи, такого формата: "Launch file ---> C:\AFDPRO\RESID19.COM". Все понятно, кроме одного: откуда в регистре DX в строке Move_string proc ... mov si,dx ... Move_strin... Консультация # 188037: Разбираю код программы из учебника, программа формирует log-файл(report.txt) действий пользователя. В самом log-файле будут записи, такого формата: "Launch file ---> C:\AFDPRO\RESID19.COM". Все понятно, кроме одного: откуда в регистре DX в строке
Move_string proc ... mov si,dx ... Move_string endp
берется смещение имени файла "C:\AFDPRO\RESID19.COM"
Вот сам код:
Код : ; RESID19.ASM - программа к Главе № 19 ; (С) Авторские права на файлы-приложения принадлежат автору книги ; "Ассемблер? Это просто! Учимся программировать под MS-DOS" ; Автор: Калашников Олег Александрович (e-mail: Assembler@Kalashnikoff.ru) ; http://www.Kalashnikoff.ru ; --- Ассемблирование (получение *.com файла) --- ;При использовании MASM 6.11 - 6.13: ;ML.EXE resid19.asm /AT ;При использовании TASM: ;TASM.EXE resid19.asm ;TLINK.EXE resid19.obj /t/x ; === Начало программы: === 286 CSEG segment assume cs:CSEG, ds:CSEG, ss:CSEG, es:CSEG org 100h Begin: jmp Init ;На метку инициализации ; === Обработчик 21h-ого прерывания === Int_21h_proc proc cmp ax,9889h jne Next_step xchg ah,al iret Next_step: pusha ;Сохраним регистры... push ds push es mov bx,ds ;BX=DS push cs ;Настроим сегментные регистры push cs pop es pop ds ;cmp ax, 0998h ; MY CODE!!! - wrong way! ;je Start_f cmp ax,4B00h ;Это запуск файла на выполнение? je Start_f cmp ah,39h ;Это создание каталога? je Create_dir cmp ah,3Ah ;Это удаление каталога? je Delete_dir cmp ah,3Bh ;Это смена каталога? je Change_dir cmp ah,3Ch ;Это создание файла? je Create_file cmp ax,3D02h ;Это открытие файла для чтения/записи? je Open_fl cmp ah,41h ;Это удаление файла? je Delete_file jmp short Go_21h ;Если другое, то передадим управление 21h-ому... Start_f: mov si,offset Start_filemess ;Строка для записи в наш log-файл. call Move_string ;Готовим строку и записываем ее в файл... jmp short Go_21h ;Передадим управление 21h-ому прерыванию... Create_dir: mov si,offset Create_dirmess call Move_string jmp short Go_21h Delete_dir: mov si,offset Delete_dirmess call Move_string jmp short Go_21h Change_dir: mov si,offset Change_dirmess call Move_string jmp short Go_21h Create_file: mov si,offset Create_filemess call Move_string jmp short Go_21h Open_fl: mov si,offset Open_filemess call Move_string jmp short Go_21h Delete_file: mov si,offset Delete_filemess call Move_string Go_21h: pop es ;Восстановим регистры... pop ds popa jmp dword ptr cs:[0FCh] ;Передаем управление прежнему 21h-ому Int_21h_proc endp ;=== Переносим строку и пишем информацию в файл === Move_string proc mov di,2 ;DS:SI указывают на строку ;ES:DI - на место в памяти, где будет формироваться строка... lodsw ;Получим длину строки (первый байт строки) mov cx,ax ;Длину строки в CX rep movsb ;Переместили строку по адресу ES:DI (Текущий сегмент:0002h) push ds mov ds,bx ;DS указывает на сегмент, где находится имя файла mov si,dx ;SI - на смещение Next_char: lodsb ;Получаем очередной символ or al,al ;Это конец строки с именем файла? Проверка на 0... jz Zero_found stosb ;Если еще не конец - заносим его в нашу формирующуюся строку jmp short Next_char ;Следующий символ... Zero_found: pop ds ;Имя файла перенесли! Восстановим DS. mov ax,0A0Dh ;Добавим возврат каретки/перевод строки. stosw dec di dec di mov word ptr cs:[0],di ;Занесем по 0-ому смещению длину готовой строки call Save_file ;Запишем готовую строку в наш log-файл... ret Move_string endp ;=== Пишем в файл === Save_file proc call Check_file ;Проверим, существует ли наш log-файл или нет... mov al,02h ;Открываем файл для чтения/записи call Open_file mov ax,4202h ;Устанавливаем указатель на конец файла xor cx,cx xor dx,dx int 3 mov ah,40h ;Функция записи в файл mov cx,cs:[0] ;Количество записываемых байт mov dx,2 ;Откуда будем писать (DS:DX) int 3 call Close_file ;Закрываем файл... ret Save_file endp ;=== Проверяем: существует ли нужный файл === Check_file proc xor al,al ;Пробуем открыть наш log-файл call Open_file jnc File_exists ;Если файл существует, то на метку File_exists ; === Атрибуты файла === ;00001 - только чтение ;00010 - спрятанный ;00100 - системный ;01000 - метка тома ;010000 - подкаталог ;100000 - архивный mov ah,3Ch ;Если файл не существует, то создадим его. mov cx,100010b ;Атрибут: архивный, спрятанный mov dx,offset File_name ;DS:DX указывают на имя файла int 3 jc Error_create ;Ошибка?.. mov Handle,ax ;Если успешно создали, то запомним номер файла File_exists: call Close_file ;Закрываем файл... Error_create: ret File_name db 'C:\report.txt',0 ;Наш log-файл Check_file endp ;=== Открытие файла === Open_file proc mov dx,offset File_name mov ah,3Dh int 3 jc Error_open mov bx,ax mov Handle,ax Error_open: ret Handle dw 0FFFFh Open_file endp ;=== Закрытие файла === Close_file proc pusha pushf cmp Handle,0FFFFh ;Нечего закрывать?.. je No_close mov ah,3Eh mov bx,Handle int 3 mov Handle,0FFFFh ;Закрываем и отмечаем, что нет открытых файлов... No_close: popa popf ret Close_file endp ;--- Сообщения резидента --- Start_filemess dw Start_filemessl db 'Launch file ---> ' ;db 'Запуск файла ---> ' Start_filemessl equ $-Start_filemess-2 Create_dirmess dw Create_dirmessl db 'Create folder ---> ' ;db 'Создание каталога ---> ' Create_dirmessl equ $-Create_dirmess-2 Delete_dirmess dw Delete_dirmessl db 'Delete folder ---> ' ;db 'Удаление каталога ---> ' Delete_dirmessl equ $-Delete_dirmess-2 Change_dirmess dw Change_dirmessl db 'Change folder to ---> ' ;db 'Смена каталога на ---> ' Change_dirmessl equ $-Change_dirmess-2 Create_filemess dw Create_filemessl db 'Create file ---> ' ;db 'Создание файла ---> ' Create_filemessl equ $-Create_filemess-2 Open_filemess dw Open_filemessl db 'Open file for read/write ---> ' ;db 'Открытие файла для чтения/записи ---> ' Open_filemessl equ $-Open_filemess-2 Delete_filemess dw Delete_filemessl db 'Deleta file ---> ' ;db 'Удаление файла ---> ' Delete_filemessl equ $-Delete_filemess-2 ; === Инициализация (подготовка и настройка резидента) === Init: mov ax,9889h ;Проверим, в памяти ли мы уже или еще нет int 21h cmp ax,8998h jne Set_resident mov ah,9 ;Если в памяти, то выведем соответствующее сообщение mov dx,offset In_memory int 21h ret ;...И вернемся в DOS Set_resident: ;Если нас в памяти нет, то установим резидент ; 21h-ое... mov ax,3521h int 21h ;Получим и сохраним адрес (вектор) 21h прерывания mov word ptr cs:[0FCh],bx mov word ptr cs:[0FEh],es mov ax,es ;Установим старый вектор 21h-прерывания на 3... push 0 ;(вырубим отладчик) pop es mov es:[3*4],bx mov es:[3*4+2],ax mov ax,2521h mov dx,offset Int_21h_proc int 3 ;"Повесим" нашу процедуру на 21h прерывание call Check_file ;А есть ли наш log-файл? mov ah,9 mov dx,offset Mess_hello int 21h mov dx,offset Init int 27h ;Оставим программу резидентной в памяти. In_memory db 'Программа уже загружена в память!!!',0Ah,0Dh,0Ah Mess_hello db 'Резидент к книге "Ассемблер? Это просто! Учимся программировать", Глава № 19.',0Ah,0Dh,0Ah db 'Автор: Калашников Олег Александрович (Assembler@Kalashnikoff.ru),',0Ah,0Dh db 'http://www.Kalashnikoff.ru, Россия, Москва, 2000 год.',0Ah,0Dh,'$' CSEG ends end Begin Дата отправки: 19.09.2015, 13:44 Вопрос задал: Посетитель - 398958 (Посетитель) Всего ответов: 1 Страница онлайн-консультации » Консультирует Коцюрбенко Алексей aka Жерар (Советник): Здравствуйте, Посетитель - 398958!
Для тех функций прерывания 21h, которые используют имя файла (39h, 3Ah, 3Bh, 3Ch, 3Dh, 41h, 43h, 4Bh, 4Eh, 56h и некоторые другие) адрес строки с именем файла передаётся через DS:DX. В данном обработчике DS сразу сохраняется в BX, а DX не изменяется, после чего для всех перехватываемых функций вызывается процедура Move_string, которая использует пару регистров BX и DX для получения сегмента и смещения строки с именем файла. Для функции 4Bh это будет имя запускаемой программы, для функций 39h, 3Ah, 3Bh - имя каталога, для остальных - имя файла.
Оценить выпуск | Задать вопрос экспертам главная страница | стать участником | получить консультацию техническая поддержка | восстановить логин/пароль Дорогой читатель! Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно! МЫ РАБОТАЕМ ДЛЯ ВАС! |
Комментариев нет:
Отправить комментарий