По мотивам недавней темы...
Пример выполнения определенного кода при любом выходе из программы (.EXIT, CTRL/C, ?MON-F-Ошибка):
Код:
$E16LS ==: 316 ;СМЕЩЕНИЕ ДО ТАБЛИЦЫ EMT 340-357
$JOBNU ==: 322 ;ТЕКУЩИЙ НОМЕР ЗАДАНИЯ
E6.EXI =: 20 ;ХУК ДЛЯ .EXIT
.MCALL .PRINT ;СИСТЕМНЫЕ МАКРОСЫ
START:: MOV @#$SYPTR,R5 ;ПОЛУЧАЕМ АДРЕС RMON
ADD R5,JOBNU ;СОХРАНЯЕМ АДРЕС JOBNUM
ADD $E16LS(R5),R5 ;ПОЛУЧАЕМ АДРЕС ТАБЛИЦЫ EMT
MOV E6.EXI(R5),R0 ;ПОЛУЧАЕМ АДРЕС ПОДПРОГРАММЫ
ADD R5,R0 ;...ОБРАБОТКИ .EXIT
MOV R0,E6EXI ;СОХРАНЯЕМ
MOV #EHOOK,R0 ;УСТАНАВЛИВАЕМ ХУК
SUB R5,R0 ;...
MOV R0,E6.EXI(R5) ;...ДЛЯ .EXIT
JMP R0 ;КОМАНДА, ВЫЗЫВАЮЩАЯ ПАДЕНИЕ
EHOOK:: TST @(PC)+ ;ФОНОВОЕ ЗАДАНИЕ АКТИВНО?
JOBNU:: .WORD $JOBNU ;
BNE 10$ ;НЕТ
;+
;ЗДЕСЬ ПОМЕЩАЕМ ЛЮБОЙ КОД КОТОРЫЙ ДОЛЖЕН ВЫПОЛНЯТЬСЯ ПРИ ЛЮБОМ ВЫХОДЕ
;ИЗ ФОНОВОГО ЗАДАНИЯ. ДЛЯ .EXIT ИМЕЕТ ЗНАЧЕНИЕ РАВЕН R0 НУЛЮ ИЛИ НЕТ.
;ПОСКОЛЬКУ МЫ ЛОВИМ ТОЛЬКО СВОЙ ОСТАНОВ, ПРОСТО СЧИТАЕМ, ЧТО ЕМУ НЕ НУЖНО
;БЫТЬ РАВНЫМ НУЛЮ (НЕ ВЫПОЛНЯТЬ .HRESET ПО ВЫХОДУ).
;-
.PRINT #EXMSG ;ПЕЧАТАЕМ СООБЩЕНИЕ
MOV @#$SYPTR,R0 ;ПОЛУЧАЕМ АДРЕС RMON
ADD $E16LS(R0),R0 ;ПОЛУЧАЕМ АДРЕС ТАБЛИЦЫ EMT
MOV E6EXI,-(SP) ;УБИРАЕМ
SUB R0,@SP ;...ХУК
MOV (SP)+,E6.EXI(R0) ;...ДЛЯ .EXIT
10$: JMP @(PC)+ ;ВЫПОЛНЯЕМ .EXIT
E6EXI:: .BLKW ;
EXMSG: .ASCIZ <15><12>/*** BYE BYE ***/<15><12>
.END START
Код:
.EX ATEXIT
?MON-F-Trap to 10 001042
*** BYE BYE ***
.