Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ASM - фильтр ввода цифр с клавиатуры 
:(
    Опции темы
Sanek123
Дата 20.5.2009, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 22.10.2008

Репутация: нет
Всего: нет



Вот исходник проги считающей значение по формуле и введенным с клавы цифрам.
Код

model large

CODE SEGMENT
    ASSUME cs:CODE,ds:DATA,ss:STACK

start:
    mov ax,DATA
    mov ds,ax        ; ввод х    
    mov dx,OFFSET mess
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,48
    mov ch,al
    mov ah,1
    int 21h
    sub al,48
    mov cl,al

    xor ax,ax
    mov al,ch
    mov bx,10
    mul bx
    xor ch,ch
    add ax,cx
    mov x,ax
    mov dx,OFFSET endstr
    mov ah,9
    int 21h
                ; ввод y
    mov dx,OFFSET mess1
    mov ah,9
    int 21h
    
    mov ah,1
    int 21h
    sub al,48
    mov ch,al
    mov ah,1
    int 21h
    sub al,48
    mov cl,al

    xor ax,ax
    mov al,ch
    mov bx,10
    mul bx
    xor ch,ch
    add ax,cx
    mul bx
    mov cx,ax

    mov ah,1
    int 21h
    sub al,48
    xor ah,ah
    add ax,cx
    mov y,ax
    mov dx,OFFSET endstr
    mov ah,9
    int 21h
                ; ввод z
    mov dx,OFFSET mess2
    mov ah,9
    int 21h
    mov ah,1
    int 21h
    sub al,48
    mov ch,al
    mov ah,1
    int 21h
    sub al,48
    mov cl,al

    xor ax,ax
    mov al,ch
    mov bx,10
    mul bx
    xor ch,ch
    add ax,cx
    mov z,ax
    mov dx,OFFSET endstr
    mov ah,9
    int 21h
                ; расчет
    mov ax,x
    add ax,y        ; (x+y)
    mov bx,z
    xor dx,dx
    div bx            ; (x+y)/z
    xor ah,ah
    add ax,x 
    add ax,y
                ; вывод
    mov di,OFFSET stout
_d2:
    xor dx,dx
    mov bx,10
    div bx
    add dl,48
    mov ds:di,dl
    dec di
    cmp ax,0
    jnz _d2
    mov dx,di
    inc dx
    mov ah,9
    int 21h


_d1:
    mov ah,4ch
    int 21h
CODE ENDS
        
DATA SEGMENT
mess    db "Введите x=",'$'
mess1    db "Введите y=",'$'
mess2    db "Введите z=",'$'
mess3    db "Результат =",'$'
rezult  dd 0
stout    db 0
endstr  db 13,10,'$'
x    dw 0
y    dw 0
z    dw 0
DATA ENDS

STACK SEGMENT STACK
    db 128 dup(?)
STACK ENDS
    end start

Тема такая что вводятся как цифры так и буквы, - и причем считает!
Каким образом установить фильтр ввода с клавы - чтоб вводились толь цифры?
Трудно тем, что никак не отввыкну от Pascal... Там бы я написал типа if (key not in '0..9') then? а здесь как работать с условием? с диапазоном? Умные книжки говорят что надо отслеживать аскии-код клавиши, но не говорят как! 

Это сообщение отредактировал(а) Sanek123 - 20.5.2009, 12:49
--------------------
Вас разыскивают бойцы 139-го порта...
PM MAIL   Вверх
ФедосеевПавел
Дата 20.5.2009, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Тут решением будет оформление ввода чисел в отдельную процедуру. Вводить по одному символу без отображения на экран. Потом проверить если символ из диапазона '0'...'9' то вывести на экран и выполнить преобразование в число.
Вводить можно int 21h ah=08h, выводить int 21h ah=02h.
Проверка диапазона примерно так
Код

@@EnterChar:
  mov ah, 08h ;ввод без отображения на экран
  int  21h
  cmp al, 0dh     ;если нажат Enter то конец ввода
  je  @@EndOfEnter
  cmp al, '0'
  jb    @@EnterChar
  cmp  al, '9'
  ja  @@EnterChar
  mov ah,02h  ;вывод символа на экран
  mov  dl, al
  int  21h
....................
обработка символа из диапазона '0'...'9'

Сейчас навскидку в форуме не вижу похожих примеров. Не совсем то, но близко процедура ReadInteger - тут нет фильтра. Или ещё примеры в FAQ
PM   Вверх
Sanek123
Дата 24.5.2009, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 22.10.2008

Репутация: нет
Всего: нет



Получилось вот так:
Код

.model large
.stack 128h
.data
    newstr  db 13,10,'$'
    mess_x  db "enter x = ",'$'
    mess_y  db "enter y = ",'$'
    mess_z  db "enter z = ",'$'
    mess_r  db "rezult: = ",'$'
    x       dw 0
.code
 start:
    mov ax, @data
    mov ds, ax
    jnz mess
    int 21h

 nillx:
    mov x, 0h

 mess:
    inc x
    cmp x,02h
    jb  messx
    cmp x, 03h
    jb  messy
    cmp x, 04h
    jb  messz    
    cmp x, 05h
    jb  messr
    cmp x,06h
    jb  exit

 messx: 
    mov ah,09h
    mov dx,offset newstr
    int 21h
    mov dx,offset mess_x
    int 21h
    jnz @enter

 messy: 
    mov ah,09h
    mov dx,offset newstr
    int 21h
    mov dx,offset mess_y
    int 21h
    jnz @enter

 messz:
    mov ah,09h
    mov dx,offset newstr
    int 21h 
    mov dx,offset mess_z
    int 21h
    jnz @enter

 messr: 
    mov ah,09h
    mov dx,offset newstr
    int 21h
    mov dx,offset mess_r
    int 21h
    mov    ax, 4c00h    
    int    21h


 @enter:
    mov ah, 08h 
    int 21h
    cmp al, 0dh    
    je  mess
    cmp al, '0'
    jb  @enter
    cmp al, '9'
    ja  @enter
    mov ah,02h  
    mov dl, al
    int 21h
    jnz @enter

 exit:
    mov    ax, 4c00h    
    int    21h

end start

Подскажите как теперь присвоить введнные числа пременным, например x,y,z и вывести резултат, скажем сложения всех трех на экран? Точнее я не понимаю где все эти значения храняться в каких регистрах?

Это сообщение отредактировал(а) Sanek123 - 24.5.2009, 22:52
--------------------
Вас разыскивают бойцы 139-го порта...
PM MAIL   Вверх
ФедосеевПавел
Дата 30.5.2009, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Sorry. Командировка.

Прости, но не вижу ввода числа - есть ввод символов из диапазона '0'-'9', но нет обработки введенного символа. Ещё раз посмотри в FAQ - конкретно процедуры ввода/вывода знаковых целых inint и outint.
Вот пример использования
Код

.model medium
.stack 128h
.data
newstr  db 13,10,'$'
mess_x  db "enter x = ",'$'
mess_y  db "enter y = ",'$'
mess_z  db "enter z = ",'$'
mess_r  db "rezult: = ",'$'

x       dw      ?
y       dw      ?
z       dw      ?
.code
Start:
        mov     ax, @data
        mov     ds, ax

        mov     ah, 09h
        lea     dx, newstr
        int     21h
        mov     ah, 09h
        lea     dx, mess_x
        int     21h
        call    inint       ;ввод числа в ax
        mov     x, ax       ;сохранение регистра ax в памяти x
........................................................................................
   ;аналогично для y и z
........................................................................................
   ;вычисление r=f(x,y,z)
........................................................................................
   ;вывод на экран результата
        mov     ah, 09h
        lea     dx, newstr
        int     21h
        mov     ah, 09h
        lea     dx, mess_r
        int     21h
        mov     ax, r       ;содержимое из памяти r поместить в ax
        call    outint      ;вывод числа из ax на экран


Саму процедуру inint с добавлением фильтра я переписал так
Код

inint   proc    near
        push    cx
        push    dx
        push    bx
        push    si
; В SI будет признак знака, в BX - число, CX тоже пригодится.
        xor     si, si
        xor     bx, bx
        xor     cx, cx
; Введём первый символ.
        mov     ah, 08h ;ввод без отображения на экран
        int     21h
; Здесь и только здесь может попасться минус. Если это не так,
; перейдём к обычной обработке символа.
        cmp     al, '-'
        jne     short @ii1
; Иначе установим признак знака и
        inc     si
        mov     ah,02h  ;вывод символа на экран
        mov     dl, al  ;
        int  21h        ;
; введём следующий символ.
@ii0:
        mov     ah, 08h ;ввод без отображения на экран 
        int     21h
@ii1:
        cmp     al, 0dh     ;если нажат Enter то конец ввода
        je      @ii2
        cmp     al, '0'
        jb      @ii0
        cmp     al, '9'
        ja      @ii0
;да это символ из ['0'..'9']
        mov ah,02h  ;вывод символа на экран
        mov  dl, al
        int  21h

; Переводим символ в число.
        sub     al, '0'
; Итак, в AL цифра, которую нужно приписать справа к уже имеющемуся
; в BX числу. Поместим цифру из AL в CX. Именно для этого он обнулялся.
        mov     cl, al
; Умножим текущий результат на 10.
        shl     bx, 1   ; BX = 2 * bx
        mov     ax, bx  ; AX = 2 * bx
        shl     ax, 2   ; AX = 8 * bx
        add     bx, ax  ; BX = 10 * bx
        add     bx, cx  ; BX = 10 * bx + al
; И так, пока вводят цифры.
        jmp     short @ii0
; Когда ввели нецифру - Enter, то посмотрим, надо ли менять знак,
@ii2:
        test    si, si
        jz      short @ii3
        neg     bx
; перейдём на новую строку
@ii3:   mov     ah, 02h
        mov     dl, 0Dh
        int     21h
        mov     dl, 0Ah
        int     21h
; и запишем результат в AX.
        mov     ax, bx
        pop     si
        pop     bx
        pop     dx
        pop     cx
        ret
inint   endp

PM   Вверх
Sanek123
Дата 30.5.2009, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 22.10.2008

Репутация: нет
Всего: нет



Я так понимаю резултат-число сохранен в ах, можно ли применить
Код

 @inttostr:
mov dl, сhislo[si]
add dl, 30h
int 21h
inc si
add bx, dl
exit:
mov ah,02h
mov dx, bx
int 21h
 для перевода обратно в строку и вывода?

--------------------
Вас разыскивают бойцы 139-го порта...
PM MAIL   Вверх
ФедосеевПавел
Дата 30.5.2009, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Прости, я не сразу увидел, что у тебя в двух темах обсуждается один вопрос.

И всё равно не пойму твой вопрос. Причём в твоём коде AX - его там просто нет... Нет и объяснения, что за массив chislo.

Я привёл два куска кода: первый - фрагмент рабочей программы с вызовом процедур ввода и вывода целых чисел, а второй - процедура ввода (с фильтром) целого числа. Процедуру вывода (outint) - для вывода результата на экран - я не стал копировать из FAQ'а.

От тебя требуется разобраться как они работают, вставить в текст программы и вызывать по мере необходимости.

Посмотри пример - ввод трёх чисел (x,y,z), вычисление r (r=x+y-z) и вывод результата.

Присоединённый файл ( Кол-во скачиваний: 21 )
Присоединённый файл  ASM.ZIP 1,74 Kb
PM   Вверх
octopus
Дата 4.10.2010, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



Ребята, спасибо Вам за содержательные тексты! Просто спасли...Но у меня вопрос, сколько ни билась, понять не могу самостоятельно: 
что происходит в этом фрагтенте кода?

; Умножим текущий результат на 10.
        shl     bx, 1   ; BX = 2 * bx
        mov     ax, bx  ; AX = 2 * bx
        shl     ax, 2   ; AX = 8 * bx
        add     bx, ax  ; BX = 10 * bx
        add     bx, cx  ; BX = 10 * bx + al

Кусок из процедуры inint.
Заранее спасибо.
PM MAIL   Вверх
ФедосеевПавел
Дата 4.10.2010, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Оп-па... А я, когда переделывал процедуру, даже и не заметил этого...

Тут всё правильно вычисляется, но несколько непривычно.
Код
; В SI будет признак знака, в BX - число, CX тоже пригодится.
        xor     si, si
        xor     bx, bx
        xor     cx, cx
............................................
много пропущенных строчек
............................................
; Итак, в AL цифра, которую нужно приписать справа к уже имеющемуся
; в BX числу. Поместим цифру из AL в CX. Именно для этого он обнулялся.
        mov     cl, al
; Умножим текущий результат на 10.
        shl     bx, 1   ; BX = 2 * bx
        mov     ax, bx  ; AX = 2 * bx
        shl     ax, 2   ; AX = 8 * bx
        add     bx, ax  ; BX = 10 * bx
        add     bx, cx  ; BX = 10 * bx + al

Здесь показано умножение BX на 10, а потом, сложение со значением в AL. Только вместо операции умножения используются две операции сдвига (замена умножения BX на 2 и на 8) и несколько операций сложения.
BX:=10*BX+AL=8*BX+2*BX+AL
Можно, в принципе, заменить на MUL, но там нужно будет следить за регистром DX (см. описание MUL).
PM   Вверх
octopus
Дата 4.10.2010, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 17.9.2010

Репутация: нет
Всего: нет



)) Cпасибо, дошло теперь))) smile Надеюсь, защищусь!)))
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для Windows/DOS"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для Windows/Dos | Следующая тема »


 




[ Время генерации скрипта: 0.0914 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.