Вопрос № 19813: Здравствуйте!
Пишу резидентный калькулятор. Исходник в приложении.
Проблема в следующем - резидент не работает! Не могу понять
почему после перехода на процедуру Calculator прога виснет. Как
мне кажеться проблема с вводом строки. Можн...
Вопрос № 19813
Здравствуйте!
Пишу резидентный калькулятор. Исходник в приложении.
Проблема в следующем - резидент не работает! Не могу понять
почему после перехода на процедуру Calculator прога виснет. Как
мне кажеться проблема с вводом строки. Можно ли в резиденте
читать с клавы с помощью 0Ah функции int 21h ? Или может проблема
все таки не в вводе? Помогите плз!
И еще, может у кого есть готовая процедура вывода числа с плавающей
точкой на екран? Как, после того как вычисления сделаны, снова вернуть
командную строку Доса, и при этом оставить прогу резидентной?
Заранее большое спасиба за все ответы!
;;;;;;;;;;;;;;;;;;;;;;файл resident.asm
.MODEL Tiny
.286
.CODE
ORG 100h
Start:
jmp SetIntVec ; встановлення обробника переривань
INCLUDE calc.asm
stdout equ 1
alt_q equ 1000h
endmes db "Program was erased..."
endmesl equ $-endmes
Handler09 PROC ; обробник переривання
push bx ds ; зберігаєм BX и DS
push cs
pop ds ; DS = CS
mov ax,cs
mov ds,ax
mov ax,40h
mov es,ax
; обробка символа з кільцевого буфера без прямого видобування
mov bx,es:1Ah
mov ax,es:[bx]
cmp ax,alt_q
je altq
cmp ah,1Fh ; ALT-S show
jne next
call Calculator ;
jmp home
next:
cmp ah,23h ; ALT-H hide
jne home
home:
pop ds bx ; відновлюєм BX і DS
; Передаєм управління старому обробнику
db 0EAh ; jmp large
RealAddr09 dd ? ; Адрес переходу
altq:
; відновити вектор без застосування функцій DOS
mov ax, 0
mov es, ax
mov ax, word ptr RealAddr09
mov word ptr es:24h, ax
mov ax, word ptr RealAddr09 + 2
mov word ptr es:26h, ax
; завершити роботу обробника / вивести повідомлення
mov ax, cs
mov ds, ax
mov ah, 9
mov dx, offset endmes
int 21h
; вивести повідомлення
mov ah, 40h
mov bx, stdout
mov cx, endmesl
mov dx, offset endmes
int 21h
jmp home
Handler09 ENDP ; кінець обробника int 09h
TSREnd = $ ; кінець резидентної частини
mes db 'Program is now resident...',10,13
meslen equ $-mes
SetIntVec:
mov ax, 3509h
int 21h ; получаємо вектор переривання 09h
mov word ptr RealAddr09[0], bx ; і зберігаємо його ...
mov word ptr RealAddr09[2], es ; в RealAddr09
mov ah,25h ; AL ми не міняли
lea dx,Handler09
int 21h ; встановлюємо новий обробник переривань int 09h
; вивести повідомлення
mov ah,40h
mov bx,stdout
mov cx,meslen
mov dx, offset mes
int 21h
mov ah,49h
mov es,ds:[2Ch] ; сегмент, змінні середовища
int 21h ; звільняжмо його
lea dx,TSREnd
int 27h ; виходимо зберігаючи резидентну частину
END Start
Приложение:
Отправлен: 16.04.2005, 07:53
Вопрос задал: x3m (статус: Посетитель)
Всего ответов отправлено: 3
Отвечает: Евгений Иванов
Здравствуйте, x3m!
в обработчике прерывания не сохраняются регистры, а точнее AX и другие.
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 16.04.2005, 08:56
Отвечает: DSota
Здравствуйте, x3m!
1. Никаких прерываний int21h быть не должно, пользуйся int16h
2. push bx ds - очень мало - Сохранять нужно все используемые регистры (включая сопроцессор)
3. См. ниже
4. При отсутствии ошибок в calc.asm (не смотрел) и соблюдении п.п. 1 и 2 все будет работать...
Приложение:
Ответ отправил: DSota (статус: Студент)
Отправлен: 18.04.2005, 11:32
Отвечает: Стас
Здравствуйте, x3m!
Ты вызываешь процедуру CALC из прерывания INT9 - т.е. у тебя запрещены все прерывания и клава работать не будет. Пока корректно не выйдешь из Int9.
Т.е. тебе надо переместить вызов CALC скажем в int2f(по флагу), а в Int9 поставить флаг.
Ответ отправил: Стас (статус: Практикант)
Отправлен: 19.04.2005, 00:44