Консультация № 193846
08.11.2018, 11:14
0.00 руб.
0 0 0
Здравствуйте! У меня возникли сложности с таким вопросом:

Добавил я на арифмометр точку. Изменилась арифметика:
Код:

...
finit
fld dig1 ;dig1 dd 0,0
fld dig2 ;dig2 dd 0,0
;тип операции
fstp result ;result dd 0,0 (короткое вещественное)
...

Добавилась процедура str2leng - определение к-ва символов целой и дробной части набранного числа:
Код:

...
strleng proc
pushad
lea eax,stroka ;адрес начала stroka db 16 dup (0)
mov point,0 ;инициируем... (point db ?)
mov sfull,0 ;sfull dd ?
mov sdrob,0 ;sdrob dd ?
xor edx,edx ;очищаем
s1:
mov bl,[eax] ;берём байт
or bl,bl ;есть что-нибуть?
jz s4 ;нет->s4
cmp point,0 ;была точка?
jne s3 ;да->s3
cmp bl,"." ;это точка?
je s2 ;да->s2
inc edx ;фиксируем символ целой части
inc eax ;смещаемся вправо, к следующему символу
jmp s1 ;повторяем
s2:
mov sfull,edx ;sfull=>к-во символов целой части stroka
xor edx,edx ;очищаем
inc eax ;пропускаем точку
mov point,1 ;фиксируем её наличие
jmp s1
s3:
inc edx ;фиксируем символ дробной части
inc eax ;смещаемся вправо, к следующему символу
cmp eax,0 ;закончились символы?
jne s1
mov sdrob,edx ;к-во символов дробной части stroka
s4:
popad
ret
strleng endp
...

Изменились процедуры преобразования:
Код:

...
asc2float proc
pushad
lea esi,stroka-1 ;правый байт
add esi,sfull ;целой части
mov ecx,sfull ;счётчик
mov bufer,0 ;инициируем... (bufer dd ?)
mov bfull,0 ;bfull dd ?
mov bdrob,0 ;bdrob dd ?
xor eax,eax ;очищаем
f1: ;преобразуем целую часть:
mov al,[esi] ;берём байт
or al,al ;есть что?
jz d1 ;нет->d1
and al,0Fh ;да->убираем 3-ку
mul mult ;учитываем coмножитель (mult dd 1.0)
add bfull,eax ;сохраняем
mov eax,mult ;обновляем
mul ten ;множитель и (ten dd 10.0)
mov mult,eax ;сохраняем его
dec esi ;смещаемся влево
loop f1 ;повторяем
d1: ;преобразуем дробную часть:
lea esi,stroka+1 ;левый байт
add esi,sfull ;дробной части
mov ecx,sdrob ;счётчик
xor eax,eax ;очищаем
d2:
mov al,[esi] ;берём байт
or al,al ;есть что?
jz itog ;нет->itog
and al,0Fh ;да->убираем 3-ку
mul aten ;учитываем множитель (aten dd 0.1)
add bdrob,eax ;сохраняем
mov eax,aten ;обновляем
mul aten ;множитель и
mov aten,eax ;сохраняем его
inc esi ;смещаемся вправо
loop d2 ;повторяем
itog: ;здесь я не совсем уверен:
xor edi,edi ;очищаем
lea edi,bufer ;адрес начала bufer
mov ebx,bfull ;добавляем
mov [edi],ebx ;целую часть
lea edi,bufer-1 ;адрес
add edi,sfull ;точки
mov byte ptr [edi],"." ;добавляем точку
inc edi ;смещаемся вправо
mov ebx,bdrob ;добавляем
mov [edi],ebx ;дробную часть
fin:
popad
ret
asc2float endp
...

Создание процедуры преобразования итога в ASCII-символы я решил разбить на этапы. Это первый этап,
когда на дисплей выводится итог без учёта знака и порядка, например: 3.3+2.2=55
Код:

...
float2asc proc
pushad
xor eax,eax
xor ecx,ecx
finit
fstcw cwr ;слово управления
or cwr,1111000011111111b ;точность 8-9->00(11), округление 10-11->00
fldcw cwr ;мантисса 24 бита (короткое вещ.)
fld result ;st=result
fxtract ;st=мантиса, st(1)=порядок
fstp mant ;mant->мантисса со знаком числа
fistp pord ;pord->порядок со знаком, без расширения
mov eax,mant ;обработка мантиссы:
lea esi,stroka+1 ;знак пропускаем
m1:
xor edx,edx
div ten
add dl,"0" ;cформируем из остатка ASCII-символ
push edx ;сохраним для разворота
inc ecx ;ECX+1->m2
test eax,eax ;преобразование закончено?
jnz m1
m2:
pop edx
mov [esi],dl ;занесём ASCII-символ в stroka
inc esi ;смещаемся
loop m2 ;повторяем
;аналогично - с порядком: учитываем знак, преобразуем, добавляем в адрес для точки
fin:
popad
ret
float2asc endp
...

По идее, на дисплее должен появляться "без порядочный" ответ (3.3+2.2=55). В реальности - каждый
раз появляется новый итог (иногда - даже с точкой). Одно радует - если на дисплее появляются
символы (итога), значит преобразование работает. Помогите разобратся - что не так?

Обсуждение

Форма ответа