Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.05.2008, 10:52   #1
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию Ввод чисел с клавиатуры

Ниже приведенная программа принимает с клавиатуры ASCII коды нажатых клавиш цифр и переводит их в шестнадцатеричный формат, одна беда: максимальное число которое переводится 999, а кто подскажет как переделать чтобы и большие числа можно было таким же образом переводить.

Код:
stdin=0
stdout=1
stderr=2

data segment

msg db 'Введите',10,13
msglen=$-msg
buf db 80 dup(0)
actlen db 0
str1 db 10,13,'$'
str3 db ' = ','$'
k dw 0
tab1 db '0123456789ABCDEF'
data ends

code segment
assume cs:code, ds:data

start: 
mov ax, data
mov ds,ax
mov ah,40h
mov bx,stdout
mov cx,msglen
mov dx,offset msg
int 21h
mov ah, 3fh
mov bx, stdin
mov cx,80
mov dx,offset buf
int 21h
mov actlen,al
mov ah,40h
mov bx,stdout
mov cl,actlen
mov dx,offset buf
int 21h
mov cl,actlen
sub cl,2
mov si,0
f1:
mov bl,buf[si]
mov dl,bl
mov ah, 02h
int 21h
lea dx,str3
mov ah,09h
int 21h
call conv
lea dx,str1
mov ah,09h
int 21h
mov bl,buf[si]
sub bl,30h
mov al,1
mov bh,10
push cx
sub cl,1
jz f3
f2:
mul bh
loop f2
f3:
pop cx
mul bl
add di,ax
inc si
loop f1
mov bx,di
xchg bh,bl
call conv
xchg bh,bl
call conv
mov ah,4ch
int 21h
conv:
LOCALS
push dx
push cx
push ax
mov ch,2
a:
mov al,bl
and al,0f0h
mov cl,4
shr al,cl
push bx
lea bx,tab1
xlat
pop bx
mov dl,al
mov ah,02h
int 21h
shl bl,cl
dec ch
jnz a
pop ax
pop cx
pop dx
ret
NOLOCALS
code ends
end start

Последний раз редактировалось B_N; 22.05.2008 в 11:18.
SAVIK вне форума Ответить с цитированием
Старый 22.05.2008, 12:46   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Если бы ты не поленился скачать MASM и заглянуть к нему в генофонд, то увидел бы следующее:
Код:
; ########################################################################
;
;               This original module was written by f0dder.
;
;      Part of the code has been optimised by Alexander Yackubtchik
;
; ########################################################################

    .386
    .model flat, stdcall
    option casemap :none   ; case sensitive

    .code

; ########################################################################

dw2hex proc source:DWORD, lpBuffer:DWORD

    push esi

    mov edx, lpBuffer
    mov esi, source

    xor eax, eax
    xor ecx, ecx

    mov [edx+8], al         ; put terminator at correct length
    mov cl, 7               ; length of hexstring - 1

  @@:
    mov eax, esi            ; we're going to work on AL
    and al, 00001111b       ; mask out high nibble

    cmp al,10
    sbb al,69h
    das

    mov [edx + ecx], al     ; store the asciihex(AL) in the string
    shr esi, 4              ; next nibble
    dec ecx                 ; decrease counter (one byte less than dec cl :-)
    jns @B                  ; eat them if there's any more

    pop esi

    ret

dw2hex endp

; #########################################################################

end
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.05.2008, 16:41   #3
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию

Да мне в принципе и не лень, но преподавтель требует работы в TASM, сейчас попробую разобраться, честно говоря пока и не пойму что это все значит, нам такого ничего не давали, но в любом случае спасибо что не остались равнодушны.
SAVIK вне форума Ответить с цитированием
Старый 22.05.2008, 16:51   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Дык кишки процедуры этой то не зависят от компилятора, тем паче с комментариями...
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.05.2008, 20:06   #5
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию

Из приведенной вами программы я понял что нужно применить 32 битовые регистры, но пож. ответьте на мой вопрос, а зачем?
Ведь если я допустим набираю число 1000, то оно и так помещается в 16 битовом, или я что-то не так понимаю?
Разбирая свою программу в отладчике заметил что до строки
67.mul bl
все идет нормально, в регистре ах накапливается 3e8h (1000), в bl у нас 1, умножаем на нее, и тут старший байт регистра ах обнуляется. Вот это мне и не понятно, и здесь я так понимаю и кроется ответ на мой вопрос. В той литературе которая у меня есть, ответа я на него не нашел, а может просто не так искал.
Попробовал заменить ах на еах результат тот же.
Подскажите пожалуйста в чем здесь дело, или подскажите где это прочитать.
SAVIK вне форума Ответить с цитированием
Старый 25.05.2008, 09:24   #6
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию

Ау люди откликнитесь, ответьте пожалуйста на мои вопросы, а то во вторник сдавать а я никак разобраться не могу.
SAVIK вне форума Ответить с цитированием
Старый 25.05.2008, 09:40   #7
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от SAVIK Посмотреть сообщение
Разбирая свою программу в отладчике заметил что до строки
67.mul bl
все идет нормально, в регистре ах накапливается 3e8h (1000), в bl у нас 1, умножаем на нее, и тут старший байт регистра ах обнуляется. Вот это мне и не понятно, и здесь я так понимаю и кроется ответ на мой вопрос. В той литературе которая у меня есть, ответа я на него не нашел, а может просто не так искал.
Попробовал заменить ах на еах результат тот же.
Подскажите пожалуйста в чем здесь дело, или подскажите где это прочитать.
Почитать в описаниях команд процессора.
Цитата:
MUL
...
- Операнд размером в байт умножается на значение AL; результат помещается в регистр AX.
Для приведенного примера AL(e8h)*BL(1) = AX(e8h)
Чтобы умножить AX нужно писать mul bx
alexBlack вне форума Ответить с цитированием
Старый 25.05.2008, 10:48   #8
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию

Вот переделал как смог, вроде переводит правильно, если что-то можно к этому добавить, буду рад узнать об этом от вас

Код:
.386
stdin=0
stdout=1
stderr=2

data segment USE16
msg db '‚ўҐ¤ЁвҐ',10,13
msglen=$-msg
buf dw 80 dup(0)
actlen db 0
str1 db 10,13,'$'
str3 db ' = ','$'
k dw 0
tab1 db '0123456789ABCDEF'
ten dw 10
data ends

code segment USE16
assume cs:code, ds:data
start: 
mov ax, data
mov ds,ax
mov ah,40h
mov bx,stdout
mov cx,msglen
mov dx,offset msg
int 21h
mov ah, 3fh
mov bx, stdin
mov cx,80
mov dx,offset buf
int 21h
mov actlen,al
mov ah,40h
mov bx,stdout
mov cl,actlen
mov dx,offset buf
int 21h

mov cl,actlen
sub cl,2
mov si,0
mov di,0
f1:
mov bx,buf[si]
sub bx,30h
xor bh,bh
mov ax,1
push cx
sub cl,1
jz f3
f2:
mul ten
loop f2
f3:
pop cx
mul bx
add edi,eax
inc si
loop f1
mov ebx,edi
xchg bh,bl
call conv
xchg bh,bl
call conv
mov ah,4ch
int 21h
conv:
LOCALS
push dx
push cx
push ax
mov ch,2
a:
mov al,bl
and al,0f0h
mov cl,4
shr al,cl
push bx
lea bx,tab1
xlat
pop bx
mov dl,al
mov ah,02h
int 21h
shl bl,cl
dec ch
jnz a
pop ax
pop cx
pop dx
ret
NOLOCALS
code ends
end start
SAVIK вне форума Ответить с цитированием
Старый 25.05.2008, 15:20   #9
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от SAVIK Посмотреть сообщение
Вот переделал как смог, вроде переводит правильно, если что-то можно к этому добавить, буду рад узнать об этом от вас
Добавить вряд-ли, если только немного убавить. Если проходить введенную строку с конца, можно проще формировать множитель (степень 10-ки). Посмотрите для сравнения вот этот код:

Код:
.386  
stdin=0  
stdout=1  
stderr=2  
  
data segment USE16   
   msg    db 'vvvvvvv',10,13  
   msglen = $-msg   
   buf    dw 80 dup(0)   
   actlen db 0  
   res    dw 0
   str1   db 10,13,'$'  
   str3   db ' = ','$'  
   k      dw 0  
data ends   
  
code segment USE16   
assume cs:code, ds:data   
start:    

   mov ax, data   
   mov ds, ax   

   mov ah, 40h   
   mov bx, stdout   
   mov cx, msglen   
   mov dx, offset msg   
   int 21h   

   mov ah, 3fh   
   mov bx, stdin   
   mov cx,80  
   mov dx,offset buf   
   int 21h   
   mov actlen,al   

   mov ah,40h   
   mov bx,stdout   
   mov cl,actlen   
   mov dx,offset buf   
   int 21h   

   xor cx, cx
   mov cl, actlen   
   sub cl, 2  
   mov si, offset buf
   add si, cx
   dec si       ; строку проходим с конца, так проще формировать множитель 10
   cmp cx, 5    ; Есть смысл ограничить введенную строку 
   jbe @@1      ; Это не гарантирует, что не будет переполнения
   mov cx, 5    ; например для 99999. Нужно делать более строгие проверки
 @@1:
 
   xor dx, dx
   mov [res], 0
   mov ax, 1   ; множитель 
   std
 @@Loop:   
   xchg ax, bx
   lodsb
   sub  ax, '0'
   xor  dx, dx
   mul  bx
   add  [res], ax
   ; меняем множитель
   xchg ax, bx
   mov  bx, 10
   mul  bx
   loop @@loop
   cld

   mov  ax, [res]
   xchg ah, al
   call convByte2Hex
   xchg ah, al
   call convByte2Hex

   mov ah,4ch   
   int 21h   

convByte2Hex:   
LOCALS   
   push  ax   
   and   al, 0f0h   
   mov   cl, 4  
   shr   al, cl   
   call  writeHexChar
   pop   ax
   push  ax   
   and   al, 0Fh   
   call  writeHexChar
   pop   ax
   ret   
NOLOCALS   

writeHexChar:
   cmp   al, 9
   jbe   @@b9_1 
   add   al, 'A'-'0'-10
 @@b9_1 :
   add   al, '0'
   mov   dl, al   
   mov   ah, 02h   
   int   21h   
   ret

code ends   
end start
alexBlack вне форума Ответить с цитированием
Старый 25.05.2008, 15:46   #10
SAVIK
Пользователь
 
Регистрация: 22.05.2008
Сообщений: 10
По умолчанию

Спасибо за помощь.
Еще такой вопрос, как проверить четное было число введено или нечетное.
допустим вот я ввел число и сейчас проверяю его вот так:
Код:
          ........
           mov ah, 0h
           int 16h
           cmp al, '1'
           je goto1
           cmp al '2'
           je goto2
           ........
если 1 иди туда, 2 иди туда, а мне нужно через раз то в 1 метку то во вторую.

Последний раз редактировалось rpy3uH; 25.05.2008 в 15:50.
SAVIK вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как запретить/разрешить ввод от клавиатуры любых символов (в том числе и юникодных)? SkAndrew Общие вопросы Delphi 8 15.08.2008 15:30
ввод чисел со знаком... maLoy*508 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 21.05.2008 19:32
ввод данных с клавиатуры juden Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 07.05.2008 18:05
Ввод последовательности чисел POPOV Общие вопросы Delphi 5 16.02.2008 22:13
ввод чисел bruce Microsoft Office Excel 1 08.02.2007 17:58