Вывод вещественного числа
Категория: Assembler
2012-02-12 14:56:35
Число для вывода должно находиться на вершине стека сопроцессора, функции должен передаваться через стек параметр - число цифр после запятой (из-за ошибок округления его обычно нельзя посчитать заранее)
code: #assembler
; Вывод вещественного числа ; аргумент - количество цифр дробной части length_frac equ [bp+4] ; локальные переменные ten equ word ptr [bp-2] temp equ word ptr [bp-4] OutFloat proc near enter 4, 0 ; пролог - выделим в кадре стека 4 байта под локальные переменные mov ten, 10 ftst ; определяем знак числа fstsw ax sahf jnc @positiv mov al, '-' ; если число отрицательное - выводим минус int 29h fchs ; и получаем модуль числа @positiv: fld1 ; загружаем единицу fld st(1) ; копируем число на вершину стека fprem ; выделим дробную часть fsub st(2), st ; отнимем ее от числа - получим целую часть fxch st(2) ; меняем местами целую и дробную части xor cx, cx ; обнуляем счетчик ; далее идет стандартный алгоритм вывода целого числа на экран @1: fidiv ten ; делим целую часть на десять fxch st(1) ; обменяем местами st и st(1) для команды fprem fld st(1) ; копируем результат на вершину стека fprem ; выделим дробную часть (цифру справа от целой части) fsub st(2), st ; получим целую часть fimul ten ; *10 fistp temp ; получаем очередную цифру push temp ; заталкиваем ее глубже в стек inc cx ; и увеличим счетчик fxch st(1) ; подготовим стек к следующему шагу цикла (полученное частное на вершину, в st(1) - 1) ftst ; проверим не получили ли в частном 0? fstsw ax sahf jnz @1 ; нет - продолжим цикл @2: ; извлекаем очередную цифру, переводим её в символ и выводим. pop ax add al, '0' int 29h loop @2 ; далее то же самое, только для дробной части. Алгоритм похож на вывод целого числа, только вместо деления умножение и проход по числу слева fstp st ; сначала проверим, есть ли дробная часть fxch st(1) ftst fstsw ax sahf jz @quit ; дробная часть отсутствует mov al, '.' int 29h ; если присутствует - выведем точку mov cx, length_frac ; помещаем в счетчик длину дробной части @3: fimul ten ; умножим на 10 fxch st(1) ; подготовка для fprem - меняем st и st(1) местами и fld st(1) ; копируем число на вершину fprem ; отделим дробную часть от целой fsub st(2), st ; и оставляем дробную fxch st(2) fistp temp ; выталкиваем полученное число из стека в temp mov ax, temp ; по дробной части идем слева, значит число выводим сразу, без предварительного сохранения в стек or al, 30h ; перевод в ascii int 29h ; на экран fxch st(1) ; подготовим стек к следующему шагу цикла (полученное частное на вершину, в st(1) - 1) ftst fstsw ax sahf ; проверим на 0 остаток дробной части loopne @3 @quit: fstp ; готово. Чистим стек сопроцессора fstp st leave ; эпилог ret 2 OutFloat endp end start
автор: vital792
Поделиться: