Answer the question
In order to leave comments, you need to log in
Why does the program terminate incorrectly?
The task was to write a resident program for DOS that plays notes from an array (1sec for each note)
The program starts, notes are played in the background. but as soon as the notes end, DOS stops responding to anything
.model tiny
.code
org 100h
.386
start:jmp load
ppresenceflag dw 1260h
old dd 0
outSound dw ?
la dw 2711
;массив частот соответсвующих нотам
notes dw 1B8h, 1BEh, 1EDh, 20BH, 22AH,24BH, 26EH, 293H,2BAH, 2E3H,310H,33EH,370H
counter db 18
i dw 0
isItFirst db 1
;процедура, проигрывающая звук
bip proc
pusha
mov al,0b6H;управляющтй бит
out 43H,al
mov ax,outSound;частота
out 42H,al;младшая
mov al,ah
out 42H,al;старшая
in al,61H
mov ah,al
or al,3
out 61H,al
popa
ret
bip endp
;процедура задержки
void proc
pusha
and al,11111100b
out 61h,al
mov cx,04h
mov dx,93e0h
mov ah,86h
int 15h
popa
ret
void endp
handler:
handler proc
pushf ; создание в стеке структуры для IRET
call cs:old ; вызов старого обработчика прерываний
push ds ; сохранение модифицируемых регистров
push es
push ax
push bx
push cx
push dx
push di
push cs
pop ds
;для отсчета минтуы используется счетчик counter
;тк прерывание срабатывает 18 раз в секнуду
;смена звучащей ноты изменяется только тогда когда
;counter становится равным 0
dec counter
cmp counter,0
jne met1
;воспроизведениие ноты
;и смена ноты на следующуюю
mov bx,i
mov ax,notes[bx]
mov outSound, ax
call bip
add i,2
mov counter,18
cmp i, 24
jle met1
add i,2
call void
;выход из обработчика прерывания
met1:
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
iret
handler endp
end_handler:
;не резидентная часть программы
;получаем адрес обработчика прерывания
load:mov ax, 351Ch
int 21h
cmp bx,ppresenceflag; флаг присутствия, если программа
; уже есть в памяти повтораная запись не будет производиться
jne exit
;сохранение контекста старого обработчика прерывания
mov word ptr old, bx
mov word ptr old+2,es
mov ax,251Ch
mov dx,offset handler; получаем адрес метки handler
int 21h
mov ax,3100h
mov dx,(end_handler-start+10Fh)/16; получение размера
;обработчика прерывания в параграфах
int 21h
;выход из программы с сохранением нового обработчика прерывания
exit:
mov ax,3100h
int 21h
ret
end start
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question