У меня возникла одна проблемка при использовании функии 3Fh. Мне нужно ввести символы с консоли, используя только эту функцию. Я передаю ей в качестве параметров handle консоли (0) в BX. Эта функция, как я знаю, использует системный буфер для чтения введенных символов. Но если пользователь вводит через пробел число символов больше чем указанное в CX (я указываю 1, потому что мне надо считывать посимвольно) при повторном обращении к этой функции (при повторном запуске проги), буфер не очищается и используются символы, которые были введены до этого. Мне нужно как-то сделать, чтобы при новом обращении к этой функции буфер очищался. Может кто знает как это можно сделать?? Еще я хотел бы узнать адрес системного буфера для этой функции.
DSEG SEGMENT PARA 'data' buf db ? DSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DSSEG ; Инициализация test proc far push ds xor ax,ax push ax mov bx,dseg mov ds,bx push ds pop es ########### Основной алгоритм ########## ; Очистка экрана mov ah,00h mov al,03h int 10h ; Вызов 3Fh, с которым и возникают проблемы mov ah,3Fh ; номер функции xor bx,bx ; handle mov cx,1 ; кол-во байт lea dx,buf ; адрес буфера int 21h ; Выход в DOS mov ah,4Ch int 21h CSEG ENDS END test После этого, если после запуска проги вводится два символа, например: C:\my_prog.exe 2 2 Все работает нормально, но если ее запустить еще раз, просто она проигнорирует обращение к функции и считает символы введенные раннее: C:\my_prog.exe C:\> Т. е. внешне она не ждет ввода от пользователя
перед вызовом 3fh попробуй вызвать mov ah,0ch int 21h не совсем помню, но возможно надо в al записать 01, или 06 Адрес буфера клавиатуры 40:001E
Spiteful, если верить TechHelp-у, функция 0Ch очищает буферы только для функций 01, 06, 07, 08 и 0Ah. Буфер для функции 3Fh можно очистить так: Код (Text): xor bx,bx mov dx,offset SwapBuf; просто ненужный кусок памяти mov cx,SwapBufSize ; его размер (не ноль) @Loop: mov ah,3Fh int 21h cmp ax,cx ; проверяем, сколько байт считано je @Loop ; если столько, сколько заказывали, ; значит, данные еще есть (наверное)
Поправочка: может получиться так, что длина строки (вместе с последним 0Dh) кратна SwapBufSize. Тогда приведенный мной код после считывания этой строки потребует ввести еще одну. Есть несколько способов решения проблемы: - заранее узнать длину строки (правильно, но скучно и громоздко); - выбрать такой размер SwapBuf, чтобы он заведомо прекрыл строку, тогда читать придется лишь один раз (ненадежно); - если AX == CX, то проверять последний символ в считанном блоке: если это 0Dh, значит строка считана целиком (правильно, если введена только одна строка). Если стандартный ввод читает не с клавиатуры, а из файла, то в буфере может оказаться несколько строк. Тогда подходит лишь первый способ (определение размера).
ava Как можно заранее узнать длину строки? Я это не очень представляю. Перехватывать прерывание? И хорошо бы еще узнать адрес этого буфера... Я попробывал тот кусок кода, что ты дал. У меня изначально такие условия, что надо считывать только по одному символу, т. е. в cx при вызове 3Fh надо всегда указыать 1. Если пользователь вводит 3 символа через пробел, то в ax все равно возвращается 1. Таким образом получается что программа зацикливается... Короче, я так понимаю надо как-то проверять на наличие в буфере (адрес которого передается в dx) 0Dh.
Как можно заранее узнать длину строки? Так же, как можно узнать длину любого открытого файла (функция 42h). В конце концов ты читаешь стандартный ввод, как файл. Таким образом получается что программа зацикливается... У меня не зацикливается (ибо нет причин для этого). Считываешь столько символов (по одному), сколько тебе нужно, затем проверяешь, сколько символов еще осталось (42h), считываешь все лишнее, и готово - буфер пуст.
ava Спасибо за помощь Я еще не пробывал то, что ты сказал насчет функции 42h. Если у меня поличится все таки очистить этот долбаный буфер, я расскажу.