Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Драйвер системного таймера(Ассемблер)

17K
24 апреля 2006 года
boxcar
1 / / 24.04.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 минуты? Можно даже приблизительно,необязательно,чтобы это дело работало...

Заранее,спасибо..
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог