IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   Вопрос по ассемблеру!Помогите новичку! (http://www.imho.ws/showthread.php?t=57248)

7en 24.04.2004 16:08

Вопрос по ассемблеру!Помогите новичку!
 
Подскажите пожалуйста как конвертировать данные введенные с клавы, в числа с которыми я далее мог бы оперировать (+,-,*,/ и т.д.). Как я понял это конвертация (String to DB,DW). Если кто знает помогите, это очень срочно. Заранее спасибо.

Ghost 24.04.2004 17:05

Встроенной процедуры, как ты понимаешь, для этого нет. Последний раз писал на асме очень давно, поэтому написать код не могу (может попозже), но алгоритм таков:

1. узнаешь адрес и длину строки, в регистр dx (например) записываешь "адрес - длина + 1" (это адрес последней цифры)
2. в регистр bl (например) записываешь 1 (это коэффициент, на который будем множить)
3. в регистр si (например) записываешь "длина строки" (это номер обрабатываемой цифры)
4. заводишь переменную "результат" и записываешь в нее 0 (без комментариев)
5. проверяешь, если si = 0, то переходишь на пункт (9)
6. считываешь байт по адресу dx, уменьшаешь его на 48 (код "0"), умножаешь на bl, результат прибавляешь к переменной "результат"
7. уменьшаешь dx и si на 1; умножаешь bl на 10
8. возвращаешься к пункту 5
9. готово

Попохже может выложу код.

Ghost 26.04.2004 12:19

Гыхм... Вот пример простенькой проги на асме для преобразования строки в число:
Код:

stak segment stack
  db 128 dup (?)
stak ends

data segment
 sc db '123' ; string content
 sl dw 3    ; string  length
 dc dw ?    ; convert result
data ends

code segment
assume ds:data,cs:code
start:
  mov ax,data
  mov ds,ax
; detect adress of last symbol in string
  lea di, sc
  add di, sl
  dec di
; initialize si and bl
  mov si, sl
  mov bx, 1
; initialize variable 'dc'
  mov ax, 0
  mov dc, ax
; start convert circle
convert:
; verify: si > 0; else goto to end circle
  cmp si, 0
  je  cnv_end
; read and covert digit
  mov ah, 0
  mov al, [di]
  sub al, 48
  mul bx
; summ with 'dc'
  add ax, dc
  mov dc, ax
; decrease si and di
  dec si
  dec di
; mul bl 10x
  mov ax, bx
  mov bx, 10
  mul bx
  mov bx, ax
; goto circle start
  jmp convert
cnv_end:
; cotvert complit, see variable 'dc'
  mov ah,4ch
  int 21h
code ends
end start

Проверял у себя - вроде все работает.

helldomain 26.04.2004 16:18

Algoritm wsegda odin i tot-je. Wopros - implementaciya ;-).

Ya delal nemnogo po-drugomu. Chital key s klawi, pinal w stek (esli ne 13 i ne 10), uwelichiwal kaunter kol-wa schitannih simwolow. Nu i dalee - 10 w stepeni nomer cifri esli schitat sprawa na lewo pomnojit na wwedenuju cifru i w akkumulyator (tipa Ax). Wwod simwolow mojno i po-drugomu sbacat. Smotri doku po int 21h dlya DOS'a, nomer funkcii pozowlyajushei schitiwat stroki s stdin. A dalshe - algoritm tot-je ;-).

Ghost 26.04.2004 16:49

helldomain
Насчет ввода: я писал прогу только для конвертации, т.е. здесь нет ни процедуры ввода, ни определения длины строки, ни вывода результата. Только исходные данные и преобразование. Насчет преобразования на лету (т.е. при вводе): можно и так, тогда отпадает необходимость в постоянном преобразовании из строки в число и обратно (для вывода на экран и произведения арифметических действий), но увеличивается объем памяти под переменные, поскольку приходится хранить и само введенное число, и его строковое представление.

7en 26.04.2004 18:28

2 Ghost, Helldomain
Nu rebyat, spasibo vam ogromnoe, vyruchili! A to vremya podjimaet...

helldomain 27.04.2004 03:10

Ghost, preobrazowanie w realtaime ne wozmojno pri pobukwennom wwode - ti ne znaesh, skolko budet cifr.

Ghost 27.04.2004 12:45

helldomain
Очень даже возможно:
- вводим первый символ, преобразуем его в цифру и записываем в 'res';
- вводим второй, преобразуем, и добавлям его к 'res', предварительно умножив 'res' на 10;
- и т.д.
Такой способ вполне пойдет, если ввод не будет использовать никаких управляющих клавиш кроме "ENTER" (и "BACKSPACE"). Но если добавить еще и управление курсором (влево, вправо, вначало, вконец) и удаление текущего символа (delete), вот тогда действительно невозможно. Точнее, можно, на выигрыша от этого никакого не будет, поскольку алгоритм чересчур усложниться.

n0n 27.04.2004 13:27

Еще разрешите вопросик: где найти документацию по WinAPI на асме?
Заранее бдлагодарен.

/7y3uK 27.04.2004 14:18

2 n0n
если ты пользуешь что-нить из Visual C++, Borland C++ Builder, Borland Delphi, то там обычно в комплекте идет хелп с заголовком что-то типа Win32 Programming reference, от туда можно взять описание функций с числом и типом параметров, а вот значения констант можно выцепить из заголовочных фалов в случае с С++, а в случае с делфи львиная доля находится в Windows.pas

helldomain 27.04.2004 18:56

Doka po API: http://msdn.microsoft.com/
Ghost: xmm. Ti ne rulish ;-). Tebe nado digit umnojat na 10 w stepeni n, gde n - poryadkowij nomer digita sprawo na lewo.

Ghost 27.04.2004 19:15

helldomain
Хи-хи. ;) Ты мой пост внимательно читал? Алгоритм посимвольного ввода с одновременным преобразованием строки в число я предложил такой:
  1. В переменную 'res' записываем 0.
  2. Считываем символ с клавиатуры в 'sym'.
  3. Если 'sym' = #13 (Enter), то идем к пункту (7).
  4. Если 'sym' = #9 (Backspace, кажись такой у него код), то стираем на экране последний выведенный символ, а в 'res' записываем 'res' div 10, после чего переходим к пукту (2).
  5. Если 'sym' = '0'||'1'||..||'9', то выводим симол на экран, преобразуем 'sym' в цифру 'dig' ('dig' = ord('sym') - 48), а в 'res' записываем 10 * 'res' + 'dig', после чего переходим к пункту (2).
  6. Введен другой символ -> переход к пункту (2).
  7. Конец: на экране отображается число в виде строки, а в переменной 'res' оно же записано в числовом виде.
В принципе, можно запоминать и саму строку. Проверь - всё работает. ;)

Ghost 28.04.2004 07:38

Вот. Наколбасил прогу. Прогнал в TurboDebugger'е - усё пашет:
Код:

stak segment stack
  db 128 dup (?)
stak ends

data segment
  rs dw 0        ; результат преобразования
  dg dw 0        ; введенная цифра
  sm dw 0        ; введенный символ
data ends

code segment
assume ds:data,cs:code
start:
  mov ax, data
  mov ds, ax
; ----------------------------------------------
ent_beg:        ; начало ввода и преобразования
  mov ah, 07h        ; вводим с
  int 21h        ; клавиатуры
  mov ah, 00h        ; символ в
  mov sm, ax        ; переменную 'sm'
  cmp ax, 0Dh        ; если 'sm' = #13 (ENTER)
  je  ent_end        ; то конец ввода => ent_end
  cmp ax, 08h        ; если 'sm' = #8 (BACKSPACE)
  je  ent_bsp        ; то => ent_bsp
  cmp ax, 30h        ; если 'sm' < #48 ('0')
  jb  ent_beg        ; или
  cmp ax, 39h        ; если 'sm' > #57 ('9')
  ja  ent_beg        ; то повторяем ввод => ent_beg
  sub ax, 30h        ; преобразуем символ 'sm'
  mov dg, ax        ; в цифру 'dg' = ord('sm') - 48
  mov ax, rs        ; вычисляем значение
  mov bx, 10        ; выражения 10*'rs'+'dg'
  mul bx        ; и если результат вызывает
  jo  ent_beg        ; переполнение при умножении
  add ax, dg        ; или перенос при сложении
  jc  ent_beg        ; то повторяем ввод => ent_beg
  mov rs, ax        ; сохраняем результат
  mov dx, sm        ; выводим на экран
  mov ah, 02h        ; введенный с клавиатуры
  int 21h        ; символ 'sm' и
  jmp ent_beg        ; возврат на начало => ent_beg
ent_bsp:        ; обработка нажатия 'backspace'
  mov ax, rs        ; если 'rs' = 0, т.е.
  cmp ax, 0        ; строка ввода пуста, то
  je  ent_beg        ; возврат на начало => ent_beg
  mov dl, 08h        ; возвращаем указатель
  mov ah, 02h        ; курсора на предыдущую
  int 21h        ; позицию
  mov dl, 20h        ; стираем предыдущий
  mov ah, 02h        ; введенный символ, выведя
  int 21h        ; на его место пробел
  mov dl, 08h        ; возвращаем указатель
  mov ah, 02h        ; курсора на предыдущую
  int 21h        ; позицию
  mov dx, 0        ; делим нацело текущий
  mov ax, rs        ; результат преобразования
  mov bx, 10        ; на 10 и запоминаем
  div bx        ; частное как новый
  mov rs, ax        ; результат преобразования
  jmp ent_beg        ; возврат на начало => ent_beg
ent_end:        ; конец ввода и преобразования
; ----------------------------------------------
  mov ah, 4ch
  int 21h
code ends
end start


helldomain 02.05.2004 19:07

Ghost poluchaet karmu ;-).


Часовой пояс GMT +4, время: 17:01.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.