Ввод/вывод числовых данных
Для ввода числовых данных необходимо:
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
Задание для самостоятельной работы. Составить программу для второго алгоритма и сравнить их по вычислительной сложности.