![]() |
|
|
![]()
|
|
| boxcar |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 24.4.2006 Репутация: нет Всего: нет |
Товарищи,помогите плиз...
; .model tiny .code .186 ; для pusha/popa и сдвигов org 100h ; COM-программа start proc near Произвести инициализацию драйвера ; сохраненить адреса предыдущего обработчика прерывания 1Ch push es mov ax,351Ch ; AH=35h, AL=номер прерывания int 21h mov word ptr old_int1Ch,bx mov word ptr old_int1Ch+2,es pop es ; установить новый обработчик mov ax,251Ch ; AH=25h, AL=номер прерывания mov dx,offset int1Ch_handler ; DS:DX - адрес обработчика int 21h ; установить обработчик прерывания 1Ch ; собственно программа(command.com) mov sp,length_of_program+100h+200h ; переместим стек на 200h после ; конца программы (дополнтельные 100h - для PSP) mov ah,4Ah mov bx,((length_of_program+100h+200h) shr 4)+1 int 21h ; освободим всю память после конца программы и стека ; заполним поля EPB, содержащие сегментные адреса mov ax,cs mov word ptr EPB+4,ax ; сегментный адрес командной строки mov word ptr EPB+8,ax ; сегментный адрес первого FCB mov word ptr EPB+0Ch,ax ; сегментный адрес второго FCB mov ax,4B00h ; функция DOS 4Bh mov dx,offset command_com ; адрес ASCIZ-строки с именем command.com mov bx,offset EPB int 21h ; исполнить программу call print_al ; конец программы ; восстановление предыдущего обработчика прерывания 1Ch mov ax,251Ch mov dx,word ptr cs:old_int1Ch+2 mov ds,dx mov dx,word ptr cs:old_int1Ch int 21h int 20h old_int1Ch dd ? ; здесь хранится адрес предыдущего обработчика command_com db 'C:\COMMAND.COM',0 ; имя файла EPB dw 0000 ; использовать текущее окружение dw offset commandline,0 ; адрес командной строки dw 005Ch,0,006Ch,0 ; адреса FCB, переданных нашей программе commandline db 01,20h,0Dh start_position dw 0 ; позиция на экране, в которую выводится время start endp ; обработать прерывания 1Ch ; выводит текущее время в позиции start_position ; int1Ch_handler proc far pusha ; обработчик аппаратного прерывания push es ; сохранить ВСЕ регистры и флаги push ds push cs ; на входе в обработчик определён только CS pop ds mov ah, 02h ; функция 02h прерывания 1Ah int 1ah ; прочитать время из RTC jc exit_handler ; если часы заняты - в другой раз ; CH = число часов в BCD формате mov al, ch 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; преобразовать в ASCII символы mov byte ptr output_line[10],ah; вывести кол-во минут mov byte ptr output_line[12],al mov al, dh ; DH = число секунд в BCD формате call bcd2asc; преобразовать в ASCII символы mov byte ptr output_line[16],ah; вывести кол-во секунд mov byte ptr output_line[18],al mov cx,output_line_l ; число байт в строке в CX push 0B800h pop es ; адрес в видеопамяти mov di,word ptr start_position ; в ES:SI mov si,offset output_line ; адрес строки в DS:DI cld rep movsb ; скопировать строку exit_handler: pop ds ; восстановить все регистры pop es popa jmp cs:old_int1Ch ; передать управление предыдущему ; обработчику ; процедура bcd2asc ; преобразует старшую цифру упакованного BCD-числа в AL в ASCII символ в AH, ; а младшую цифру в ASCII символ в AL bcd2asc proc near mov ah, al and ah, 11110000b sar ah, 4 and al, 00001111b add ax, 3030h ret bcd2asc endp output_line db ' ',1Fh,'0',1Fh,'0',1Fh,'h',1Fh ; строка " 00h 00:00 " db ' ',1Fh,'0',1Fh,'0',1Fh,':',1Fh ; с атрибутом 1Fh db '0',1Fh,'0',1Fh,' ',1Fh ; после каждого символа output_line_l equ $-output_line int1Ch_handler endp print_al: mov dh,al and dh,0Fh ; DH - младшие 4 бита shr al,4 ; AL - старшие call print_nibble ; вывести старшую цифру mov al,dh ; теперь AL содержит младшие 4 бита print_nibble: ; процедура вывода 4 бит (шестнадцатеричной цифры) cmp al,10 ; три команды, переводящие цифру в AL sbb al,69h ; в соотвествующий ASCII код das ; (см. описание команды das) mov dl,al ; код символа в DL mov ah,2 ; номер функции DOS в AH int 21h ; вывод символа ret ; этот ret работает два раза length_of_program equ $-start end start 2. Модуль для изменения времени .model tiny .code .386 org 100h start: ; Ввести первое число: mov ah, 09h mov dx, offset msg_01 ;вывести "Введите текущий час: " int 21h call vvod ;вызвать Vvod cmp ah, 0ffh je start ; Записать введенное число в регистр СH mov ch, al ; Ввести второе число: mov ah, 09h mov dx, offset msg_02 ;вывести , "Введите текущую минуту: " int 21h call vvod ;вызвать Vvod cmp ah, 0ffh je start mov cl, al ; Ввести третье число: mov ah, 09h mov dx, offset msg_03 ;вывести "Введите текущую секунду: " int 21h call vvod ;вызвать Vvod cmp ah, 0ffh je start mov dh, al ; Установить время: mov dl, 0 mov ah, 2dh int 21h ret msg_01 db 0ah, 0dh, "Введите текущий час: ",'$' msg_02 db 0ah, 0dh, "Введите текущую минуту: ", '$' msg_03 db 0ah, 0dh, "Введите текущую секунду: ", '$' err_msg db 0ah, 0dh, "Ошибка , введите еще раз", '$' ;вывести "Ошибка , введите еще раз", ; процедура Vvod vvod: ; Ввести первую цифру: mov ah, 01h int 21h sub al, 30h ; Если ввели не цифру - ошибка cmp al, 9 ja err mov bl, 10 mul bl mov bl, al ; Ввести вторую цифру: mov ah, 01h int 21h sub al, 30h cmp al, 9 ja err add al, bl ret err: mov ah, 09h mov dx, offset err_msg int 21h mov ah, 0ffh ret end start ; Это драйвер системного таймера(часов). Часы появляются в правом верхнем углу. Что надо дописать,чтобы они появлялись и в других углах с промежутком в 2 минуты? Можно даже приблизительно,необязательно,чтобы это дело работало... Заранее,спасибо.. |
|||
|
||||
![]()
|
| Правила форума "Asm для Windows/DOS" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Asm для Windows/Dos | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |