СПРОСИ ПРОФИ
👍
0
👎 08

Ассемблер, вывод данных

совсем не понимаю как выводить на консоль значения с плавающей точкой внутри цикла. Работаю в турбо ассемблере (16 бит). Программа запускается без ошибок и просто открывает консоль
.386
.model flat

DATA_SEG SEGMENT
buf db 20 dup('$')
two dd 2.0
three dd 3.0
x dd 0.0
y dd ?
b dd 0.1
sinh dd ?
cosh dd ?
DATA_SEG ENDS

STACk_seg SEGMENT PARA STACK
DB 128 DUP(?)
STACk_seg ENDS

CODE_SEG SEGMENT
ASSUME CS:CODE_SEG, DS:DATA_SEG, SS:STACk_seg

START:
MOV AX, DATA_SEG
MOV DS, AX

FINIT
MOV CX, 15

OTR:
FLD x
FSIN
FLD two
FMUL
FST sinh
FLD x
FMUL ST(0), ST(0)
FCOS
FLD three
FMUL
FST cosh

FLD sinh
FLD cosh
FSUB
FST y
lea dx, buf
mov ah, 09h
;int 21h

FLD x
FLD b
FADD
FST x

LOOP OTR

MOV AH, 4CH
MOV AL, 0
INT 21H

CODE_SEG ENDS
END START

👍
0
👎 0

а для чего semicolon поставили перед int 21h ?!
естественно, с ним не будет ничего выводиться.

👍
0
👎 0

С ним вообще дичь выводится, а именно множество «w» в разных частях консоли. Проблема в том, что я не понимаю как преобразовать число в строку и вывести её

  #3   09 янв 2025 02:42   Ответить
👍
0
👎 0

Удивительно ... в вашем буфере одни доллары, значит ничего и не должно выводиться. Впишите в него спереди другие символы типа buf db ';', 20 dup('$') и проверьте, выводит ли их функция №09 на консоль.
А для чего модель распределения памяти .model flat – не взять ли какую попроще? тут вот – https://prog-cpp.ru/asm-memory – написано, что она не годится для 16-разрядных систем.
Для вывода числа его придётся разбить на цифры, каждую преобразовать в символ и скопировать их коды последовательно в buf – хотя проще посимвольно выводить без буфера (если после вывода не планируются с ними иные действия).

👍
0
👎 0

Если написать buf db ';', 20 dup('$'), то просто ненадолго открывается консоль и сама закрывается
А как можно посимвольно выводить и можно ли это реализовать с числами с плавающей точкой?

  #5   09 янв 2025 06:22   Ответить
👍
0
👎 0

Надеюсь, это с int 21h так, да?
А с закоментированным тоже закрывается сразу? Если так, то перед завершением надо задержку или ожидание ввода поставить, чтобы успеть увидеть содержимое консоли.
Если эффекта нет, то следующим действием либо уберите строку mov ds, либо поменяйте .model на другую кроме flat, после этого снова проверьте.
Насчёт посимвольного вывода прочитайте статью про функции DOS и выберите самую простую, их там несколько. Вообще любую информацию можно выводить, но разбивать число на цифры придётся через арифметические операции (хотя может быть в современных сопроцессорах есть и функции, не знаю), а для преобразования цифры в печатный символ есть инструкции процессора, читайте описание системы команд.

👍
0
👎 0

Да, это с int 21h. Без него то же самое
Изменение модели тоже результата не даёт. Я в целом сам не уверен, что мне нужен именно flat. Просто вроде как мне нужно именно с 32битами работать, т.к. я использую плавающую точку и стек, но работает почему-то только в турбо 16-бит.
Там не в задержке дело, как я понимаю. Она не моментально закрывается, а через несколько секунд.

  #7   09 янв 2025 07:20   Ответить
👍
0
👎 0

Ну так в описании к flat сказано, что в ней значения 32-разрядных сегментных регистров устанавливаются операционной системой непосредственно перед передачей управления пользовательской программе, т.е. не надо без особой нужды их править, а вы копируете в ds из ax и возможно этим его портите.
Я бы для начала оттестировал простой код в .model small без команд сопроцессора:
lea dx, buf
mov ah, 09h
int 21h
и убедился, что на консоль выводится содержимое buf.
Потому что есть подозрение, поддерживается ли в этой системе int 21h как функция вывода.
Кстати, под какой операционной системой запускаете программу? В виртуальной машине с эмулятором DOS или другим каким образом?

👍
0
👎 0

Чтобы выводить числа с плавающей точкой в Turbo Assembler (16-бит), нужно преобразовать их в строку. Вот исправленный код с комментариями:

asm
.386
.model small

.data
buf db 20 dup('$')       ; Буфер для строки
two dd 2.0
three dd 3.0
x dd 0.0
y dd ?
b dd 0.1
sinh dd ?
cosh dd ?

.code
start:
    mov ax, @data
    mov ds, ax
    finit                ; Инициализация FPU

    mov cx, 15           ; Количество итераций

loop_start:
    ; Вычисление sinh = 2 * sin(x)
    fld x
    fsin
    fld two
    fmul
    fstp sinh

    ; Вычисление cosh = 3 * cos(x^2)
    fld x
    fmul st(0), st(0)
    fcos
    fld three
    fmul
    fstp cosh

    ; y = sinh - cosh
    fld sinh
    fsub cosh
    fstp y

    ; Преобразование y в строку
    fld y                ; Загружаем y в FPU
    call float_to_str    ; Преобразуем в строку в buf

    ; Вывод строки
    mov ah, 09h
    lea dx, buf
    int 21h

    ; Переход на новую строку
    mov ah, 02h
    mov dl, 0Dh
    int 21h
    mov dl, 0Ah
    int 21h

    ; x += b
    fld x
    fadd b
    fstp x

    loop loop_start

    ; Завершение программы
    mov ax, 4C00h
    int 21h

; Процедура преобразования float в строку
float_to_str proc near
    pusha
    fstcw [buf]          ; Сохраняем управляющее слово
    or word ptr [buf], 0C00h ; Устанавливаем округление к нулю
    fldcw [buf]

    ; Целая часть
    fistp word ptr [buf+2]
    mov ax, [buf+2]
    add ax, '0'
    mov [buf], al

    ; Дробная часть (1 знак)
    fimul word ptr [ten]
    fistp word ptr [buf+2]
    mov ax, [buf+2]
    add ax, '0'
    mov [buf+1], al

    mov byte ptr [buf+2], '$'
    popa
    ret
float_to_str endp

ten dw 10
end start


Ключевые изменения:
1. Добавлена процедура float_to_str для преобразования числа в строку.
2. После вычисления y вызывается преобразование в строку.
3. Добавлен вывод символов перевода строки.
4. Исправлена модель памяти на small.

Как это работает:

  • Число с плавающей точкой преобразуется в формат «X.Y» (1 десятичный знак).
  • Для вывода используется функция DOS 09h.
  • Перед выводом добавляются символы возврата каретки и перевода строки.


Ограничения:

  • Процедура float_to_str упрощена и работает только для чисел от 0.0 до 9.9.
  • Для более сложных случаев потребуется полноценный алгоритм преобразования.
  #9   29 янв 2025 08:57   Ответить

Задайте свой вопрос программистам –
профессионалам

Сейчас онлайн 75 программистов
Получите ответ профи быстро и бесплатно
ASK.PROFI.RU © 2020-2025