mov al, #2 ;
mov cl, al ;
and cl, 0f ;маскирование для выделения младшего разряда
add cl, 030 ;преобразование его в ASCII код
sar al, 4 ;сдвиг на 4 разряда
mov ch, al
and ch, 0f ;маскирование
add ch, 030 ;преобразование в ASCII код
print #1, ch ;запись результата в
print #1+2, cl ;видеобуфер
pop cx, ax ;восстановление ресурсов
#em
jmp main
old_addr dd ?
main:
;сохраняем адрес старого обработчика (прерывание №8, от таймера)
mov ax, 035 by 8
int 021
mov w old_addr, bx
mov w old_addr+2, es
;загружаем адрес нового обработчика (прерывание №8, от таймера)
lea dx, timerIsr
mov ax, 025 by 8
int 021
;ждем нажатия клавиши
wait_esc:
mov ah, 0
int 016
cmp ah, 1
jne wait_esc
;восстанавливаем старый обработчик
lds dx, old_addr
mov ax, 025 by 8
int 021
int 020
;собственный обработчик
timerIsr:
push ax, ds, es
;читаем часы
mov al, 4
out 70h, al
in al, 71h
;печатаем часы
print_sm 0, al
print 4, ':'
;читаем минуты
mov al, 2
out 70h, al
in al, 71h
;печатаем минуты
print_sm 6, al
print 10, ':'
;читаем секунды
mov al, 0
out 70h, al
in al, 71h
;печатаем секунды
print_sm 12, al
pop ax, ds, es
;переход на системный обработчик (cs - нужно??..)
cs jmp old_addr
Результаты испытаний:
3.3. Транзитная программа вывода текущего времени или даты в зависимости от выбранной клавиши с выходом по клавише.
Текст программы для QNX:
#include <stdio.h>
//для работы с прерываниями
#include <sys/neutrino.h>
//для обработки ошибок
#include <errno.h>
//для работы с сигналами
#include <signal.h>
//для работы с портом клавиатуры
#include <hw/inout.h>
#include <time.h>
//обработчик прерывания от клавиатуры
const struct sigevent* klav_int (void *area, int id);
void SIGUSR1_date(int signo);
void SIGUSR2_time(int signo);
struct sigevent klav_exit;
struct sigevent klav_date;
struct sigevent klav_time;
int main (void) {
int inter_id;
//обработчики сигналов
signal (SIGUSR1, SIGUSR1_date);
signal (SIGUSR2, SIGUSR2_time);
//запрос на использование привиллегированного ввода/вывода
//(для возможности использования прерываний)
ThreadCtl(_NTO_TCTL_IO,0);
//макрос для определения типа "сигнал" структуры sigevent
SIGEV_SIGNAL_INIT(&klav_exit,SIGKILL);
SIGEV_SIGNAL_INIT(&klav_date,SIGUSR1);
SIGEV_SIGNAL_INIT(&klav_time,SIGUSR2);
//подключние обработчика прерывания
inter_id=InterruptAttach(1, klav_int, NULL,0,0);
//проверка на наличие ошибок
if (inter_id == -1) {
printf("%s\n",strerror(errno));
return 1;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.