Как очистить буфер, используемый функцией 3Fh

Тема в разделе "WASM.ASSEMBLER", создана пользователем Xf1sh, 25 дек 2005.

  1. Xf1sh

    Xf1sh New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    5
    Адрес:
    Underground
    У меня возникла одна проблемка при использовании функии 3Fh.

    Мне нужно ввести символы с консоли, используя только эту функцию. Я передаю ей в качестве параметров handle консоли (0) в BX. Эта функция, как я знаю, использует системный буфер для чтения введенных символов. Но если пользователь вводит через пробел число символов больше чем указанное в CX (я указываю 1, потому что мне надо считывать посимвольно) при повторном обращении к этой функции (при повторном запуске проги), буфер не очищается и используются символы, которые были введены до этого. Мне нужно как-то сделать, чтобы при новом обращении к этой функции буфер очищался. Может кто знает как это можно сделать?? Еще я хотел бы узнать адрес системного буфера для этой функции.
     
  2. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Кусок кода можно?
     
  3. Xf1sh

    Xf1sh New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    5
    Адрес:
    Underground
    DSEG SEGMENT PARA 'data'

      buf db ?

    DSEG ENDS



    CSEG SEGMENT

    ASSUME CS:CSEG,DS:lol: SEG

    ; Инициализация

    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:\>

    Т. е. внешне она не ждет ввода от пользователя
     
  4. Spiteful

    Spiteful New Member

    Публикаций:
    0
    Регистрация:
    24 янв 2004
    Сообщения:
    33
    перед вызовом 3fh попробуй вызвать

    mov ah,0ch

    int 21h

    не совсем помню, но возможно надо в al записать 01, или 06

    Адрес буфера клавиатуры 40:001E
     
  5. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Spiteful, если верить TechHelp-у, функция 0Ch очищает буферы только для функций 01, 06, 07, 08 и 0Ah.



    Буфер для функции 3Fh можно очистить так:
    Код (Text):
    1.  
    2.     xor bx,bx
    3.     mov dx,offset SwapBuf; просто ненужный кусок памяти
    4.     mov cx,SwapBufSize   ; его размер (не ноль)
    5.  
    6. @Loop:
    7.     mov ah,3Fh
    8.     int 21h
    9.  
    10.     cmp ax,cx   ; проверяем, сколько байт считано
    11.     je  @Loop   ; если столько, сколько заказывали,
    12.             ; значит, данные еще есть (наверное)
    13.  
     
  6. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Поправочка: может получиться так, что длина строки (вместе с последним 0Dh) кратна SwapBufSize. Тогда приведенный мной код после считывания этой строки потребует ввести еще одну. Есть несколько способов решения проблемы:

    - заранее узнать длину строки (правильно, но скучно и громоздко);

    - выбрать такой размер SwapBuf, чтобы он заведомо прекрыл строку, тогда читать придется лишь один раз (ненадежно);

    - если AX == CX, то проверять последний символ в считанном блоке: если это 0Dh, значит строка считана целиком (правильно, если введена только одна строка).



    Если стандартный ввод читает не с клавиатуры, а из файла, то в буфере может оказаться несколько строк. Тогда подходит лишь первый способ (определение размера).
     
  7. Xf1sh

    Xf1sh New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    5
    Адрес:
    Underground
    ava





    Как можно заранее узнать длину строки? Я это не очень представляю. Перехватывать прерывание?

    И хорошо бы еще узнать адрес этого буфера...

    Я попробывал тот кусок кода, что ты дал. У меня изначально такие условия, что надо считывать только по одному символу, т. е. в cx при вызове 3Fh надо всегда указыать 1.

    Если пользователь вводит 3 символа через пробел, то в ax все равно возвращается 1. Таким образом получается что программа зацикливается...

    Короче, я так понимаю надо как-то проверять на наличие в буфере (адрес которого передается в dx) 0Dh.
     
  8. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Как можно заранее узнать длину строки?



    Так же, как можно узнать длину любого открытого файла (функция 42h). В конце концов ты читаешь стандартный ввод, как файл.



    Таким образом получается что программа зацикливается...



    У меня не зацикливается (ибо нет причин для этого).



    Считываешь столько символов (по одному), сколько тебе нужно, затем проверяешь, сколько символов еще осталось (42h), считываешь все лишнее, и готово - буфер пуст.
     
  9. Xf1sh

    Xf1sh New Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    5
    Адрес:
    Underground
    ava Спасибо за помощь ;) Я еще не пробывал то, что ты сказал насчет функции 42h. Если у меня поличится все таки очистить этот долбаный буфер, я расскажу.