Вывод времени. Защита резидента от повторной загрузки - Assembler
Формулировка задачи:
всем привет! снова имеется программа вывода времени, увы написанная не мной..
правда на сей раз занимает чуть больше ресурсов памяти..
возникает вопрос по копированию резидентной части..
резидентная часть вроде полностью не будет копироваться.. т.к. пропускаются команды сравнения 2+5=7 байт..
почему тогда указана полная длина резидентной части для копирования, т.е. не отнимаются те самые 7 байт? ведь в этом случае скопируются в дополнение к резидентной части еще семь байтов расположенных за ней, а там уже по-сути мусор инициализационной части..
RGB equ 1Fh VID EQU 0B800h ROW EQU 1 COL EQU 73 SEP EQU 3Ah TIME SEGMENT ORG 100h ASSUME CS:TIME,DS:TIME START: JMP INIT MOVEIT: PUSH DS PUSH ES PUSH SI PUSH DI MOV SI,CS MOV DS,SI MOV ES,SI MOV SI,(OFFSET NewInt1C) + 2 + 5 XOR DI,DI CLD MOV CX,attente-(OFFSET NewInt1C) REP MOVSB MOV AX,251Ch XOR DX,DX INT 21h POP DI POP SI POP ES POP DS NewInt1C PROC DEC BYTE PTR CS:attente JZ MOVEIT PUSH AX PUSH BX PUSH CX PUSH DX PUSH ES PUSH DI CLD MOV AX,VID MOV ES,AX MOV DI,(ROW-1)*160+(COL-1)*2 MOV AH,2 INT 1Ah MOV BX,CX MOV AL,BH MOV AH,RGB MOV CL,4 SHR AL,CL OR AL,30h STOSW MOV AL,BH AND AL,0Fh OR AL,30h STOSW MOV AL,SEP STOSW MOV AL,BL SHR AL,CL OR AL,30h STOSW MOV AL,BL AND AL,0Fh OR AL,30h STOSW MOV AL,SEP STOSW MOV AL,DH SHR AL,CL OR AL,30h STOSW MOV AL,DH AND AL,0Fh OR AL,30h STOSW POP DI POP ES POP DX POP CX POP BX POP AX DB 0EAh Int1COfs DW ? Int1CSeg DW ? NewInt1C ENDP attente DB 5 INIT: CLI MOV AX,351Ch INT 21h MOV Int1COfs,BX MOV Int1CSeg,ES MOV AH,9 MOV DX,OFFSET copyright INT 21h MOV AX,251Ch MOV DX,OFFSET NewInt1C INT 21h PUSH CS POP ES MOV ES,WORD PTR ES:2Ch MOV AH,49h INT 21h STI MOV AX,3100h MOV DX,6 INT 21h copyright db 13,10,'Time! 3.4 - Coded By Sam In 1994 - db The Flamoots Production - 96 Bytes In Memory!$' TIME ENDS END START
MOV SI,(OFFSET NewInt1C) + 2 + 5 XOR DI,DI CLD MOV CX,attente-(OFFSET NewInt1C) REP MOVSB
DEC BYTE PTR CS:attente - 5 байт JZ MOVEIT - 2 байта
Решение задачи: «Вывод времени. Защита резидента от повторной загрузки»
textual
Листинг программы
.MODEL Tiny .286 .CODE .STARTUP LOCALS IntNo = 08h ; номер прерывания HandlerOfs = 30h;40h;80h ; смещение, по которому будет копироваться обработчик (с отступом в 2-3 байта на инструкцию jmp), должно быть кратно 10h HandlerShift = HandlerOfs-100h ; разница нового и исходного смещения обработчика jmp InstallTSR ;----------------------------------------------------------------------------------------------------------------------- HandlerStart: ; начало обработчика прерывания (между этой меткой и HandlerEntry могут храниться данные) ORG $-1 VentilOfs DB ? VentilChars DB '\|/-' HandlerEntry: ; точка входа обработчика прерывания push ax push bx push ds push cs pop ds mov al,VentilOfs inc ax and al,3 mov VentilOfs,al lea bx,VentilChars xlat mov ah,1Eh push 0B800h pop ds mov ds:[0],ax pop ds pop bx pop ax RealInt DB 0EAh ; возвращаем управление прерыванию (jmp far) RealAddr DW ?,? HandlerEnd: ORG $-4 ;----------------------------------------------------------------------------------------------------------------------- InstallTSR: mov ah,9 lea dx,msgOk int 21h ; копируем наш код со смещением HandlerShift mov si,offset HandlerStart mov di,offset HandlerStart+HandlerShift mov cx,(HandlerEnd-HandlerStart+1)/2 rep movsw ; Освобождаем Environment mov ah,49h mov es,ds:[2Ch] int 21h ; Сдвигаем сегментный адрес mov ax,cs add ax,HandlerShift/16 mov ds,ax ; Получаем старый вектор прерывания mov ax,3500h + IntNo int 21h mov RealAddr[0],bx mov RealAddr[2],es ; Перехватываем прерывание mov ah,25h mov dx,offset HandlerEntry int 21h ; Остаёмся резидентными mov dx,offset HandlerEnd+HandlerShift int 27h msgOk DB 'TSR is installed!',13,10,'$' END
Объяснение кода листинга программы
Вот что получилось:
- В коде есть следующие переменные:
- IntNo — номер прерывания, равный 08h.
- HandlerOfs — смещение, по которому будет копироваться обработчик, равное 30h, 40h или 80h (должно быть кратно 10h).
- HandlerShift — разница нового и исходного смещения обработчика.
- VentilOfs — DB-переменная, содержащая смещение вентиля (находится между метками HandlerStart и HandlerEntry).
- VentilChars — DB-переменная, содержащая строку '|/-', которая будет выводиться на экран при каждом прерывании.
- RealInt — DB-переменная, содержащая возвращаемое значение прерывания, равное 0EAh.
- RealAddr — DW-переменная, содержащая адрес, на который будет возвращено управление при прерывании.
- Код выполняет следующие действия:
- Выводит на экран сообщение «TSR is installed!», затем символы «|/-» (символы вентиля) и символ доллара.
- Устанавливает обработчик прерывания на смещение HandlerStart с использованием регистра HandlerShift.
- Освобождает Environment.
- Сдвигает сегментный адрес на величину HandlerShift.
- Получает старый вектор прерывания.
- Перехватывает прерывание, проставляя в векторе прерывания адрес обработчика HandlerEntry.
- Остаётся резидентными, сохраняя в памяти адрес HandlerEnd с использованием регистра HandlerShift.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д