Программирование на Ассемблере

           

Ввод/вывод числовых данных


Для ввода числовых данных необходимо:

1. Ввести соответствующую строку.

2. Преобразовать ее в числовой вид.

Для вывода необходимо выполнить действия в обратном порядке.

Преобразование строки в число.

Пусть задана строка вида:

[<Пробелы>] [<>][<Пробелы>] Цифра [Цифра Цифра...]

Преобразовать ее в соответствующее ей число.

Для преобразования последовательности цифр в число можно использовать схему Горнера. Например, пусть необходимо строку символов  «375»

преобразовать в число. Представим число в виде:

(3 * 10 + 7) * 10 + 5. Здесь 3, 7, 5 -цифры числа, а 10

- основание системы счисления для исходного числа. Таким образом, алгоритм преобразования:

r=0;



for (i=n-1; i>=0; i--)

   r = r*10 +d[i];

Так как в общем виде числа могут быть пробелы, которые надо игнорировать, напишем макрос для игнорирования этих символов. На вход макроса подается адрес символа строки, на выходе получаем адрес ненулевого символа

macro skip address

local    l1, l2

ifidn <di>, <address>

reg       equ      esi

else

reg       equ      edi

endif

push     reg

mov     reg, address

l2:

cmp     [byte ptr reg], ‘ ’

jne       l1

inc       reg

jmp      l2

l1:

mov     address, reg

pop      reg

endm

Данный макрос подключим к файлу win.inc

Функции для преобразования строки в число и обратного преобразования представлены ниже.

Преобразование чисел при выводе

До вывода числа оно должно быть преобразовано из внутреннего представления в строковое. Для преобразования можно использовать следующие способы.

1. Число делится на 10 и остаток от деления рассматривается как очередная цифра. Деление продолжается до тех пор, пока не получим нулевое значение. Недостаток способа: цифры числа получаем, начиная с младших, перед выводом необходимо инвертирование строки или формирование строки заданной длины.

2. Число делится на 10000, 1000,... и получаем цифры числа, начиная со старших цифр. Недостаток. Требуется хранение массива или его программное формирование.


Рассмотрим реализацию первого способа. Для хранения 32-битного десятичного числа требуется 10 цифр + знак + нулевой завершитель, т.е. 12 символов. Так как строка может занимать не все 12 символов, оставшиеся символы слева должны быть пробелами.
Функция для преобразования числа в строку. Входное данное-32-битное число. Выходное - строка с нулевым завершителем
Функции для преобразования числа при вводе и выводе и соответствующая главная программа представлены ниже:
Ideal
p586
model              flat
extrn ExitProcess:proc
include "win.inc"
dataseg
my       db        '    25', 0
val       dd        ?
codeseg
proc     atoi
public  atoi
arg       value:dword, mystr:dword = p
push     ebp
mov     ebp, esp
push     ebx ecx edx esi
mov     esi, [mystr]
skip      esi
mov     ebx, 1
cmp     [byte ptr esi], '-'
je         short    minus
cmp     [byte ptr esi], '+'
je         short plus
jmp      prod
minus:
inc       esi
neg      ebx
jmp      prod
plus:
inc       esi
prod:
skip      esi
xor       eax, eax;          r=0
mov     ecx, 10
for:
cmp     [byte ptr esi], 0
je         exit
mul      ecx
test       edx, edx
jne       error
mov     dl, [esi]
sub       dl, '0'
add      eax, edx
inc       esi
jmp      for
exit:
mul      ebx
mov     esi, [value]
mov     [esi], eax
xor       eax, eax
jmp      lend
error:
mov     eax, 1
lend:
pop      esi edx ecx ebx
pop      ebp
ret        p
endp atoi
begin:
push     offset my offset val
call      atoi
call      ExitProcess
end     begin
Задание для самостоятельной работы. Составить программу для второго алгоритма и сравнить их по вычислительной сложности.

Содержание раздела