Консультация № 29821
19.11.2005, 19:50
0.00 руб.
0 3 2
;Посмотрите пожалуйста что тут неправильно?????
;???????????

.286
.model tiny
CODSEG segment
assume cs:CODSEG
org 100h
_start:
jmp _Init

Int_08h dd ?

_Timer: ;Обработчик прерывания Int 08h {
pusha ;
pushf ;
call cs:[Int_08h] ;
call _Sound ;
popa ;
iret ; }

_Init:
mov ax,3508h ;Сохраняем{
int 21h ;
;
mov word ptr cs:[Int_08h],bx ;
mov word ptr cs:[Int_08h+2],es ; }

push cs ;Заменяем {
pop ds ;
;
mov dx,offset _Timer ;
mov ax,2508h ;
int 21h ; }

xor ax,ax ;Ждём нажатия клавиши
int 16h ;

mov dx,offset Int_08h ;Востанавливаем{
mov ax,2508h ;
int 21h ; }
.exit ;Выход

_Sound:
mov ah,02 ;Звуковой сигнал{
mov dl,07 ;
int 21h ;
ret ; }

CODSEG ends
end _start
;Так вот! Первый раз прога запускается нормально и всё работает( динамик
;"шуршит", а по нажатии любой клавиши программа завершается).
;фсё самое интересное начинается со следующих запусков:
;Второй раз прога запускается и НИКАКОВА звука (зато фсё также безотказно
;завершается по нажатии какой-либо кнопки)
;И наконец третий раз:фсё виснет, нет никакой реакции на нажатие кнопок
;и динамик ПИЩИТ без конца (причём пищит в разнобой, невтакт)
;и остаётся только нажать на RESET
;Если кто знает что делать пожалуйста ответьте, а то как-то надоело при каждой
;отладке и запуске делать перезагрузку (фсё таки не в дОС‘e сижу, а в Винде)

Обсуждение

давно
Советник
419
1012
19.11.2005, 23:04
общий
это ответ
Здравствуйте, Петров Максим Викторович!
так и будет.
звук нужно делать вот так
всего хорошего.

proc sound
push ax ;#
push cx
in al,61h
or al,3
out 61h,al
mov al,0B6h
out 43h,al
mov ax,4000 ;частота,чем > x,тем < частота(F). x=1,193,180/F Гц
out 42h,al
mov al,ah
out 42h,al

xor ax,ax
out 40h,al
mov al,ah
out 40h,al

xor cx,cx
loop $

mov ax,3500
out 42h,al
mov al,ah
out 42h,al

xor cx,cx
loop $

mov ax,1000
out 42h,al
mov al,ah
out 42h,al

xor cx,cx
loop $

mov ax,2500
out 42h,al
mov al,ah
out 42h,al

xor cx,cx
loop $

mov ax,1500
out 42h,al
mov al,ah
out 42h,al

xor cx,cx
loop $

in al,61h
and al,0FCh
out 61h,al

pop cx ax
ret
endp
Неизвестный
20.11.2005, 01:39
общий
что заметил с ходу:1)mov dx,offset Int_08h ;Востанавливаем{mov ax,2508h ;int 21h ; } Обсолютно не верно!Нужно: в dx поместить старый оффсет -mov dx,word ptr cs:[Int_08h],bxв ds старый сегмент:mov ds,word ptr cs:[Int_08h+2]и тогда mov ax,2508hint 21h2) Вызывать int из аппаратных(а иногда и софтверных) int крайне не рекомендуется, а иногда и прямо запрещено.
Неизвестный
20.11.2005, 10:51
общий
это ответ
Здравствуйте, Петров Максим Викторович!
Во-первых:
8 прерывание - прерывание таймера и вызывается 18,2 раза в секунду. Его вообще нежелательно изменять. Тем более работать с обработчиком прерывания на уровне прерываний.
Во-вторых:
pusha ;
pushf ;
...
popa ;
iret;
Ты ложишь в стек все регистры общего назначения, а достаёшь регистр флагов,
Стек - засорил!
iret - это две команды
popf
retf
правильнее будет
pushf
pusha
...
popa
iret
Форма ответа