Форум программистов, компьютерный форум, киберфорум
Assembler: математика, вычисления
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 1
Регистрация: 15.07.2022
Сообщений: 70

Вывод числа с плавающей запятой

15.11.2022, 16:53. Показов 1958. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, не дружу с выводом в ассемблере и скорее всего с динамической памятью, как сделать полноценный вывод ответа?
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
include Rad2.asm
Title    UMN (EXE)       ; основная программа
Extrn SubUmn:Far        ; объявление внешней процедуры
 
StackSg     Segment PARA STACK 'Stack'
    DW      512 DUP(?)
StackSg     ENDS
 
DataSg  Segment PARA 'Data'
DataSg  ENDS
CodeSg  Segment PARA 'Code'
Begin       Proc    FAR
Assume CS:CodeSg, DS:DataSg, SS:StackSg
Push    DS
Sub AX, AX
Push    AX
Mov AX, DataSg
Mov DS, AX
 
Call    SubUmn  ; вызов процедуры
 
Ret
Begin       ENDP
CodeSg  ENDS
END Begin
Сам модуль
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Title   SubUmn      ; внешняя подпрограмма
CodeSg  Segment PARA 'Code'
    ms db 'Press enter Diametr:$',0
    ms1 db 'Result:$',0
    Pi dw 3,14
SubUmn  Proc FAR
Assume CS:CodeSg
Public SubUmn   ; открытие доступа к подпрограмме
lea dx,ms
mov ah,09h
int 21h
mov ah,01h
int 21h
sub al,30h
mov bl,2
div bl ;al = Введнный диаметр/2
mul al ; ax = al*al
mov cx,ax ; ax в cx
mov ax,Pi ;Pi  в ах
mul cx ;Получили площадь  
lea dx,ms1
mov ah,09h
int 21h  
add al,30h
mov ah,2h
mov dl,al
int 21h
Ret         ; результат заносится в DX:AX
SubUmn  ENDP
CodeSg  ENDS
END SubUmn
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.11.2022, 16:53
Ответы с готовыми решениями:

Запись числа с плавающей запятой в регистр
Здравствуйте уважаемые эксперты! Подскажите как записать число с плавающей запятой в регист ax например..

Объявление и вывод на экран числа с запятой - Пи(3,14)
Здраствуйте. Вопрос вот какой: как объявить в сегменте даных число с запятой так, чтобы потом нормально проводить с ним расчеты и выводить...

Вывод чисел с плавающей запятой
Доброго времени суток, в программе при выводе значений остаются незначимые нули, можно ли как нибудь избавиться от них? #include...

4
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8659 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,907
Записей в блоге: 12
15.11.2022, 17:07
То, что вы привели - целочисленные вычисления.
Для работы с числами в формате "плавающая запятая" нужно использовать инструкции сопроцессора FPU, или более поздние добавления инструкций SIMD (SSE, AVX и проч.).

Немного об этих инструкциях есть в главе 11
Электронный учебник
и поищите ещё в интернете.

О вводе таких чисел писали в отдельных темах, но в закреплённые они не попали, хотя найти можно.
Вывод тоже неоднократно рассматривался, и кое-что попало в тему
Ввод и вывод чисел в различных системах счисления
0
Модератор
1245 / 676 / 292
Регистрация: 10.11.2019
Сообщений: 1,406
16.11.2022, 11:06
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
; Печать числа с плавающей запятой
; Тестировалась на Tasm 4.0 и Masm 5.10 в DosBox
    .286
    .model small
    .code
start:  fldpi ; заносим PI в регистр сопроцессора
    call outfloat ; печатаем
    mov ax,4C00h
    int 21h
 
putchar:int 21h
    ret
 
; Требуется директива .286C или выше.
outfloat proc   near
        push    ax
        push    cx
        push    dx
; Формируем кадр стэка, чтобы хранить в нём десятку
; и ещё какую-нибудь цифру.
        push    bp
        mov     bp, sp
        push    10
        push    0
; Проверяем число на знак, и если оно отрицательное,
        ftst
        fstsw   ax
        sahf
        jnc     @of1
; то выводим минус
        mov     ah, 02h
        mov     dl, '-'
        call putchar; int     21h
; и оставляем модуль числа.
        fchs
; Пояснение далее пойдёт на примере.   ; ST(0) ST(1) ST(2) ST(3) ...
; Отделим целую часть от дробной.      ; 73.25 ... что-то не наше
@of1:   fld1                           ;  1    73.25 ...
        fld     st(1)                  ; 73.25  1    73.25 ...
; Остаток от деления на единицу даст дробную часть.
        fprem                          ;  0.25  1    73.25 ...
; Если вычесть её из исходного числа, получится целая часть.
        fsub    st(2), st              ;  0.25  1    73    ...
        fxch    st(2)                  ; 73     1     0.25 ...
; Сначала поработаем с целой частью. Считать количество цифр будем в CX.
        xor     cx, cx
; Поделим целую часть на десять,
@of2:   fidiv   word ptr [bp - 2]      ;  7.3   1     0.25 ...
        fxch    st(1)                  ;  1     7.3   0.25 ...
        fld     st(1)                  ;  7.3   1     7.3   0.25 ...
; отделим дробную часть - очередную справа цифру целой части исходного числа,-
        fprem                          ;  0.3   1     7.3   0.25 ...
; от чатсного оставим только целую часть
        fsub    st(2), st              ;  0.3   1     7     0.25 ...
; и сохраним цифру
        fimul   word ptr [bp - 2]      ;  3     1     7     0.25 ...
        fistp   word ptr [bp - 4]      ;  1     7     0.25 ...
        inc     cx
; в стэке.
        push    word ptr [bp - 4]
        fxch    st(1)                  ;  7     1     0.25 ...
; Так будем повторять, пока от целой части не останется ноль.
        ftst
        fstsw   ax
        sahf
        jnz     short @of2
; Теперь выведем её.
        mov     ah, 02h
@of3:   pop     dx
; Вытаскиваем очередную цифру, переводим её в символ и выводим.
        add     dl, 30h
        call putchar; int     21h
; И так, пока не выведем все цифры.
        loop    @of3                   ;  0     1     0.25 ...
; Итак, теперь возьмёмся за дробную часть, для начала проверив её существование.
        fstp    st(0)                  ;  1     0.25 ...
        fxch    st(1)                  ;  0.25  1    ...
        ftst
        fstsw   ax
        sahf
        jz      short @of5
; Если она всё-таки ненулевая, выведем точку
        mov     ah, 02h
        mov     dl, '.'
        call putchar; int     21h
; и не более шести цифр дробной части.
        mov     cx, 6
; Помножим дрообную часть на десять,
@of4:   fimul   word ptr [bp - 2]      ;  2.5   1    ...
        fxch    st(1)                  ;  1     2.5  ...
        fld     st(1)                  ;  2.5   1     2.5  ...
; отделим целую часть - очередную слева цифру дробной части исходного числа,-
        fprem                          ;  0.5   1     2.5  ...
; оставим от произведения лишь дробную часть,
        fsub    st(2), st              ;  0.5   1     2    ...
        fxch    st(2)                  ;  2     1     0.5  ...
; сохраним полученную цифру во временной ячейке
        fistp   word ptr [bp - 4]      ;  1     0.5  ...
; и сразу выведем.
        mov     ah, 02h
        mov     dl, [bp - 4]
        add     dl, 30h
        call putchar; int     21h
; Теперь, если остаток дробной части ненулевой
        fxch    st(1)                  ;  0.5   1    ...
        ftst
        fstsw   ax
        sahf
; и мы вывели менее шести цифр, продолжим.
        loopnz  @of4                   ;  0     1    ...
; Итак, число выведено. Осталось убрать мусор из стэка.
@of5:   fstp    st(0)                  ;  1     ...
        fstp    st(0)                  ;  ...
; Точнее, стэков.
        leave
        pop     dx
        pop     cx
        pop     ax
        ret
outfloat endp
    end start
0
0 / 0 / 1
Регистрация: 15.07.2022
Сообщений: 70
16.11.2022, 14:57  [ТС]
ФедосеевПавел, Добрый день по мск, помогите .пожалуйста,разобраться с вводом числа с руки , с выводом все понятно
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
Title   SubUmn      ; внешняя подпрограмма
.286c
CodeSg  Segment PARA 'Code'
    ms db 'Press enter Diametr:$',0
    ms1 db 'Result:$',0
    X dd 5.0 ; допустим ввели это число
    two dd 2.0
    res dd ?; место под результат
    ten     equ word ptr [bp-2]
    temp    equ word ptr [bp-4]
    length_frac     equ     [bp+4]
    string  db  20, ?, 20 dup (0)  ;максимальное число состоит из 20 цифр (22 - с учетом 0d0ah)
    ten1 dd  10.0    ;вещественное 10
u_n dw  0
rez dd ?
count dw 0
 
SubUmn  Proc FAR
Assume CS:CodeSg
Public SubUmn   ; открытие доступа к подпрограмме
;---------вводим вещественное число с клавиатуры---------------------------------------------
mov ah, 10
    mov dx, offset string
    int 21h
 
m2:
;преобразуем целую часть
    dec cx
    mov si, offset string
    add si, 2
    fldz
m3:
    mov al, [si]
    and al, 0Fh
    fmul st(0), st(2)
    mov u_n, ax
    fiadd u_n
    inc si
    loop m3
    fadd 
    
    mov cx, count
ml: 
    fmul st(0), st(1)
    loop ml
    fstp rez
    fld rez
    mov cx, count
 
     ;загрузили в FPU полученный диаметр
fdiv two     ;получили радиус st(0)=X/2
fld st         ;st(1)=st(0)
fmulp st(1),st    ;получили квадрат радиуса st(0)=st(0)*st(1)
fldpi           ;загрузили число Пи
fmulp st(1),st   ;перемножили Пи на квадрат радиуса
;=====Вывод ответа=====
enter 4,0
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)
    fld st(1)
    fprem
    fsub st(2),st
    fimul ten
    fistp temp
    push temp
    inc cx
    fxch st(1)
    ftst
    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    res
        leave                   ; эпилог
 
Ret         ; результат заносится в DX:AX
SubUmn  ENDP
CodeSg  ENDS
END SubUmn
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8659 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,907
Записей в блоге: 12
16.11.2022, 21:09
С выводом у Вас бардак. Нельзя смешивать логику работы программы (вычисление длины окружности) и ввод/вывод.

Ввод
https://www.cyberforum.ru/post2085862.html
тот же код Ввод и вывод чисел в различных системах счисления
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.11.2022, 21:09
Помогаю со студенческими работами здесь

Ввод/Вывод чисел с плавающей запятой
Почему GCC выводит в результате выполнения такого кода #include <stdio.h> #define test(n, type, flg) { \ int a##n; type...

Числа с плавающей запятой
Задание: Записать число 0.625 в ячейку ST(0) сопроцессора, ввести в строке CS:0000 команду fstp dword ptr - запись числа, представленного...

Числа с плавающей запятой
Всем привет! как сравнивать числа с плавающей запятой? var c : real; begin c := 0; if c = 0 then Result := c; end; ...

Числа с плавающей запятой
Доброго времени суток форуманчане! Сижу над книгой Хорстмана и непонятен момент с дробными числами . Когда double с>1 считает...

Числа с плавающей запятой
struct float_as_struct { unsigned int fraction : 23; //мантисса unsigned int exponent : 8; //экспонента + 0x3FF unsigned int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия SDL 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual. . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru