Новичок
Профиль
Группа: Участник
Сообщений: 9
Регистрация: 2.3.2006
Репутация: нет Всего: нет
|
В общем задали такое задание: Сигнальный таймер обратного отсчета с предустановкой и сбросом. Объяснение: Необходимо вводить время, через которое таймер должен сработать, затем программа должна уйти в фоновый режим (DOS) и уже оттуда отслеживать наступило ли время срабатывания или нет. Если наступило - нужно секунд 10 попищать и выйти.... Прогу вроде худо - бедно написал, а вот как ее в резидентскую после установки времени превратить, да еще и выйти по окончанию времени - я не знаю... почитал пару книжек - все равно не могу допедрить... Помогите пожалуйста... Буду рад даже простейшей резидентской проге с комментами и объяснением для тех кто в танке как и че таботает.. или ссылке на какой нить сайт, где про резиденты все все написано и куча примеров приведино простых.. Ниже приведен код частично сделанной программы (вводится время через которое сработает таймер, затем как только это время наступает - на экран вылазит надпись - Time out!!! ) Код | .model tiny .code .186 ; для pusha/popa и сдвигов org 100h
start proc near ; сохранить адрес предыдущего обработчика прерывания 1Ch mov ax,351Ch ; АН = 35h, AL = номер прерывания int 21h ; функция DOS: определить адрес обработчика mov word ptr old_int1Ch,bx ; прерывания mov word ptr old_int1Ch+2,es ; (возвращается в ES:BX) ; установить наш обработчик mov ax,251Ch ; АН = 25h, AL = номер прерывания mov dx,offset int1Ch_handler ; DS:DX - адрес обработчика int 21h ; установить обработчик прерывания 1Ch
;**********************************************************************
mov dx, offset name_prog ; вывести название программы mov ah,9h int 21h
mov ah,9h int 21h mov dx, offset hour_print ; вывести предустановку часов mov ah,9h int 21h xor cx,cx mov ah,1h ; ввод единиц int 21h call decoder ; п\п преобразования ASCII кода в число add al,cl ; часы находятся в упакованном BCD mov buffer_hours,al ; виде в регистре buffer_hours ;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ установка часов завершена~ ~ ~ ~ ~ ~ ~ ~ ~ ~
mov dx, offset min_print ; вывести предустоновку минут mov ah,9h int 21h mov ah,1h ; ввод десятков int 21h call decoder_1 ; п\п преобразования ASCII кода в число rol al,4 ; циклический сдвиг влево на 4 бита xor cx,cx ; обнуление регистра cx mov cl,al ; в cl хранится число десятков mov ah,1h ; ввод единиц int 21h call decoder ; п\п преобразования ASCII кода в число add al,cl ; часы находятся в упакованном BCD mov buffer_min,al ; виде в регистре buffer_min ;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ установка минут завершена~ ~ ~ ~ ~ ~ ~ ~ ~ ~
mov dx, offset sec_print ; вывести предустоновку секунд mov ah,9h ;+++ int 21h ;+++
mov ah,1h ; ввод десятков int 21h call decoder_1 ; п\п преобразования ASCII кода в число rol al,4 ; циклический сдвиг влево на 4 бита xor cx,cx ; обнуление регистра cx mov cl,al ; в cl хранится число десятков mov ah,1h ; ввод единиц int 21h call decoder ; п\п преобразования ASCII кода в число add al,cl ; часы находятся в упакованном BCD mov buffer_sec,al ; виде в регистре buffer_sec ;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ установка секунд завершена~ ~ ~ ~ ~ ~ ~ ~ ~ ~
;печать времени
mov dx, offset name_prov ; проверка часов mov ah,9h int 21h
mov cl, buffer_hours and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_hours and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h mov dx, offset name_probel ; ::::: mov ah,9h int 21h mov cl, buffer_min and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_min and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h mov dx, offset name_probel ; ::::: mov ah,9h int 21h
mov cl, buffer_sec and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_sec and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ чтение и операции над секундами~ ~ ~ ~ ~ ~ ~ ~ ~ ~ mov ah,02h ; чтение системного времени INT 1Ah ;jc metka ; выдать сообщение об ошибке если время не прочитано
mov al,buffer_sec add al, dh daa jc then1 ; если результат сложения больше 99,то на then1 mov buffer_sec,al ; если меньше то ror al,4h and al,00001111b ;выделяем десятки sub al,00000110b ;вычитаем 6 jb endif1 ;если результат отрицателен and buffer_sec,00001111b rol al,4h add buffer_sec,al jmp then2
then1: add al, 01000000b ; прибавить "40" mov buffer_sec,al then2: mov al,buffer_min add al,1h daa mov buffer_min,al endif1:
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ чтение и операции над минутами~ ~ ~ ~ ~ ~ ~ ~ ~ ~ mov ah,02h ; чтение системного времени INT 1Ah ;jc error_sys ; выдать сообщение об ошибке если время не прочитано
mov al,buffer_min add al, cl daa jc then3 ; если результат сложения больше 99,то на then1 mov buffer_min,al ; если меньше то ror al,4h and al,00001111b ;выделяем десятки sub al,00000110b ;вычитаем 6 jb endif2 ;если результат отрицателен and buffer_min,00001111b rol al,4h add buffer_min,al jmp then4
then3: add al, 01000000b ; прибавить "40" mov buffer_sec,al then4: mov al,buffer_hours add al,1h daa mov buffer_hours,al endif2:
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ чтение и операции над часами~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ;jc error_sys ; выдать сообщение об ошибке если время не прочитано
mov ax,02h ; чтение системного времени INT 1Ah mov al,buffer_hours add al, ch daa mov buffer_hours,al
;печать времени срабатывания таймера
mov dx, offset name_prov ; проверка часов mov ah,9h int 21h
mov cl, buffer_hours and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_hours and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h mov dx, offset name_probel ; ::::: mov ah,9h int 21h
mov cl, buffer_min and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_min and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h mov dx, offset name_probel ; ::::: mov ah,9h int 21h
mov cl, buffer_sec and cl,11110000b ror cl,4h add cl,30h mov dl,cl mov ah,2 int 21h mov cl,buffer_sec and cl,00001111b add cl,30h mov dl,cl mov ah,2 int 21h ;***************************************************************************
mov ah,1 int 21h ; ожидание нажатия на любую клавишу ; конец программы
; восстановить предыдущий обработчик прерывания 1Ch mov ax,251Ch ; АН = 25h, AL = номер прерывания mov dx,word ptr old_int1Ch+2 mov ds,dx mov dx,word ptr cs:old_int1Ch ; DS:DX - адрес обработчика int 21h
ret
old_int1Ch dd ? ; здесь хранится адрес предыдущего обработчика start_position dw 0 ; позиция на экране, в которую выводится текущее время
temp_print db 0Dh, 0Ah, ' PROBA______ $' buffer_min db 1 ; максимальный размер буфера ввода buffer_sec db 1 ; максимальный размер буфера ввода buffer_hours db 1 ; максимальный размер буфера ввода name_prog db 0Dh, 0Ah 'Timer $' ; название программы hour_print db 0Dh, 0Ah, 'Hour $' min_print db 0Dh, 0Ah, 'Min $' sec_print db 0Dh, 0Ah, 'Sec $' error_text db 0Dh, 0Ah, 'Undefined simbol $' error_sys_text db 0Dh, 0Ah, 'System time is fail $' error_sys_clock db 0Dh, 0Ah, 'clock is already stand $' name_prov db 0Dh, 0Ah, 'Vvedennoe vremja $' name_probel db ' : $' name_bud db 0Dh, 0Ah, ' Vremja budilnika $' ;**********************************************************************************
decoder proc near sub al,30h ; преобразование из ASCII в число вычитанием 30 ;jb error_ ; если меньше 30 - сообщение об ошибке cmp al,9 ; сравнение с числом 9 ;ja error_ ; если больше 9 - сообщение об ошибке ret decoder endp decoder_1 proc near sub al,30h ; преобразование из ASCII в число вычитанием 30 ;jb error_ ; если меньше 30 - сообщение об ошибке cmp al,5 ; сравнение с числом 5 ;ja error_ ; если больше 5 - сообщение об ошибке ret decoder_1 endp
start endp
; обработчик для прерывания 1Ch ; выводит текущее время в позицию start_position на экране int1Ch_handler proc far pusha ; обработчик аппаратного прерывания push es ; должен сохранять ВСЕ регистры push ds push cs ; на входе в обработчик известно только pop ds ; значение регистра CS mov ah,02h ; Функция 02h прерывания 1Ah: int 1Ah ; чтение времени из RTC, jc exit_handler ; если часы заняты - в другой раз
; AL = час в BCD-формате call bcd2asc ; преобразовать в ASCII, mov byte ptr output_line[2],ah ; поместить их в mov byte ptr output_line[4],al ; строку output_line
mov al,cl ; CL = минута в BCD-формате call bcd2asc mov byte ptr output_line[10],ah mov byte ptr output_line[12],al
mov al,dh ; DH = секунда в BCD-формате call bcd2asc mov byte ptr output_line[16],ah mov byte ptr output_line[18],al
mov cx,output_line_l ; число байт в строке - в СХ push 0B800h pop es ; адрес в видеопамяти mov di,word ptr start_position ; в ES:DI mov si,offset output_line ; адрес строки в DS:SI cld rep movsb ; скопировать строку
;****************************************************************** mov ah,02h ; Функция 02h прерывания 1Ah: int 1Ah ; чтение времени из RTC, cmp dh, buffer_sec jne metka mov ah,02h ; Функция 02h прерывания 1Ah: int 1Ah ; чтение времени из RTC, cmp cl, buffer_min
jne metka mov ax,02h ; Функция 02h прерывания 1Ah: int 1Ah ; чтение времени из RTC, cmp ch, buffer_hours jne metka mov dx, offset error_text ; вывести название программы mov ah,9h int 21h mov ax,4c00h
int 21h metka:
exit_handler: pop ds ; восстановить все регистры pop es popa jmp cs:old_int1Ch ; передать управление предыдущему обработчику
; процедура bcd2asc ; преобразует старшую цифру упакованного BCD-числа из AL в ASCII-символ, ; который будет помещен в АН, а младшую цифру - в ASCII-символ в AL bcd2asc proc near mov ah,al and al,0Fh ; оставить младшие 4 бита в AL shr ah,4 ; сдвинуть старшие 4 бита в АН or ah, 30h or al,30h ret bcd2asc endp
; строка " 00h 00:00 " с атрибутом 1Fh (белый на синем) после каждого символа output_line db ' ',1Fh,'0',1Fh,'0',1Fh,'h',1Fh db ' ',1Fh,'0',1Fh,'0',1Fh,':',1Fh db '0',1Fh,'0',1Fh,' ',1Fh output_line_l equ $ - output_line
int1Ch_handler endp
end start
|
|