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

Вещественное деление двух чисел с помощью сопроцессора, затем вывод результата на экран

28.12.2023, 14:27. Показов 1161. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Уже несколько дней хочу научится орудовать вещественными числами, нужно для лабораторной. Даже нашёл алгоритм вывода на экран, понял его, и думал, что всё заработает. Программа принимает 2 числа, для примера x = 125, y = 4. z = x/y = 31.25. Но нет, выводит только 31.00. Другие числа, конечно, проверил. Помогите, пожалуйста, 2 дня потратил , сил нет. Уже думал реализовать деление в столбик)
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
DosSeg
include D:\tasm.2_0\tasm\io.asm
.model small
.stack 100
.data
    inpX db "Enter X: ",'$'
    inpY db "Enter Y: ",'$'
    outZ db "Z = ",'$'
    x   dd  ?
    y   dd  ?
.code
.startup
.286C
    mov ah, 9
    lea dx, inpX
    int 21h
    inint ax                ; макрокоманда inint осуществляет ввод числа с клавиатуры
    mov word ptr x, ax      
    
    mov ah, 9
    lea dx, inpY
    int 21h
    inint ax
    mov word ptr y, ax      ; ввод y
    
    mov ah, 9
    lea dx, outZ
    int 21h
    
    push    bp              
    mov     bp, sp
    push    10              ; на 10 будем делить у умножать
    push    0               ; ещё одно место под число
    
    finit
    fld y
    fld x
    fdiv st(0), st(1)       ; s(0) = s(0) / s(1) (
    
    ftst                    ; сравнение s(0) с нулём
    fstsw ax
    sahf
    jnc DROB                ; если > 0, то пропускаем вывод минуса
    mov ah, 02h
    mov dl, '-'
    int 21h
    fchs                    ; модуль числа
    DROB:   ; пусть x = 125, y = 4, тогда:        31.25   8  ...
    fld1    ; 1     31.25   
    fld     st(1) ; 31.25   1   31.25   8   ...
    fprem   ;остаток от деления на 1 в st(0) ; 0.25      1   31.25   8   ...
    fsub    st(2), st(0)    ; целая часть в st(2)    0.25    1   31  8   ...
    fxch    st(2)   ;теперь st - целая часть    ;    31     1   0.25    8   ...
    xor cx, cx
    CEL:
    fidiv   word ptr [bp - 2]      ; делим целую часть на 10   3.1     1    0.25   ...
    fxch    st(1)                  ;  1     3.1   0.25  ...
    fld     st(1)                  ;  3.1   1     3.1   0.25 ...
    fprem                          ;  0.1   1     3.1   0.25 ...
    fsub    st(2), st              ;  0.1   1     3     0.25 ...
    fimul   word ptr [bp - 2]      ;  1     1     3     0.25 ...
    fistp   word ptr [bp - 4]      ;  1     3     0.25 ...
    inc     cx
    push    word ptr [bp - 4]      ; сохраним полученную цифру в стек
    fxch    st(1)                  ; 3      1   0.25    ...
    ftst                
    fstsw   ax
    sahf
    jnz     short CEL              ; повторяем, пока st(0) != 0
    mov ah, 02h
    OUT1:
    pop dx                          ; dx = 3,  dx = 1
    add dl, 30h                     ; перевод в ASCII
    int 21h
    loop OUT1                       ; CX = количеству цифр в целой части
    fstp    st(0)                  ;  1     0.25 ...
    fxch    st(1)                  ;  0.25  1    ...
    ftst        
    fstsw   ax
    sahf
    jz      short CLEAR             ; если нет дробной части, то точку не ставить
    mov ah, 02h
    mov dl, '.'
    int 21h
    mov cx, 6                       ; максимум 6 знаков после запятой
    DROB1:
    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    ...
    fstp    [bp - 4]            ; 1     0.5     ...
    mov     ah, 02h
    mov     dl, [bp - 4]        ; [bp-4] = 2,       [bp-4] = 5
    add     dl, 30h
    int     21h
    fxch    st(1)               ; 0.5 1
    ftst
    fstsw   ax
    sahf
    loopnz      short DROB1     ; повторять пока s(0) != 0 и cx != 0
    CLEAR:
    fstp st(0)                  
    fstp st(0)
    add sp, 4
    pop bp
    
.exit   0
end
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.12.2023, 14:27
Ответы с готовыми решениями:

Программа ввода двух чисел, их деление и вывод на экран
Ввод символьных 5- разрядных целых шестнадцатиричных чисел, преобразование их в числа с фиксированной точкой, их деление, преобразование...

Умножение двух чисел введенных с консоли и вывод результата на экран
Народ помогите. Может у кого есть программки умножения чисел и вывод результата на экран.

Деление числа и вывод результата на экран
Здравствуйте, есть программа для сложения двух чисел: 56 и 8. Необходимо её преобразовать для деления. Вот код:title obrazec2(exe) stsg...

3
Модератор
1245 / 676 / 292
Регистрация: 10.11.2019
Сообщений: 1,406
28.12.2023, 16:36
Лучший ответ Сообщение было отмечено nordslomin как решение

Решение

У Вас x и y описаны как dd, а при вводе в них записывается dw, и далее при делении они снова
загружаются как дробные. Я нашёл у себя работающую процедуру вывода - считает правильно.

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
128
129
130
131
    .286C
    .8087
    .model small
    .code
 
; x dd 125.0
; y dd 4.0
x   dw 125
y   dw 4
 
; Требуется директива .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
 
putchar:int 21h
    ret
 
start:  mov ax,cs
    mov ds,ax
    mov es,ax
    finit
    fild y ; грузим целые значения
    fild x
    fdiv st(0), st(1)       ; s(0) = s(0) / s(1)
    call outfloat
    int 20h
    end start
1
0 / 0 / 0
Регистрация: 08.05.2020
Сообщений: 9
29.12.2023, 00:31  [ТС]
Заработало, спасибо Вам! Я пытался использовать переменные dw, но они не передавались в сопроцессор. Оказывается нужна команда fild, а не fld. Я всё равно не понял, почему при переменных dd деление не происходит, ведь 2 старших байта просто заполняются нулями. Но главное, что всё работает
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8659 / 4494 / 1669
Регистрация: 01.02.2015
Сообщений: 13,905
Записей в блоге: 12
29.12.2023, 06:00
Цитата Сообщение от nordslomin Посмотреть сообщение
ведь 2 старших байта просто заполняются нулями
Скорее всего это не так.
Вот здесь конвертер и формируется отчёт о решении
https://numeral-systems.com/ieee-754-converter/
Так для числа 125 перевод в формат single (4 байта) даёт результат 0x42FA0000.

Да и в отладчике можно увидеть содержимое регистров FPU.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.12.2023, 06:00
Помогаю со студенческими работами здесь

PHP функция деление двух значений - вывод результата
Есть вывод цены в интернет-магазине, нужно реализовать рядом ЦЕНУ товара в рассрочку. Например разделить цену на 6 (платежей) и вывод...

В чем ошибка при выводе двух целых чисел,нахождения результата их деления и выводом результата на экран?
решил вывести с клавиатуры два целых числа,написал программу как написано в учебнике Фаронова В.В. нажимаю ctrl+f9 и в итоге получаю...

Вывод результата после выполнения функций для сопроцессора
Задание: Посчитать 6 значений функции Yn = 25х3 – 2,1 (x изменяется с шагом 0.2) Подскажите, каким образом вывести результаты на...

Сравнение чисел с помощью сопроцессора
дано задание создать программу разбиения массива вещественных чисел в формате двойного слова на два массива. В первый массив помещаем все...

Деление двух чисел и вывод результатов в квадраты
Необходимо написать программу для деления двух чисел и вывод результатов в квадраты на экране. В первый квадрат поместить частное, во...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
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
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru