Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.12.2018, 13:53   #1
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию Задача вычисления уравнения с использованием сопроцессора. Помогите решить..

Добрый день!
Помогите, пожалуйста, решить задачу.. или может у вас исходники есть подобные.. Очень надо, программа должна содержать операции сопроцессора. Много информации искал, но подобного не увидел((
Нужно разработать программу:

а) Вычисляет выражение в соответствии с задан-ным вариантом математическое выражение (табл. 1) и для значений X от 0 до 10 и сохраняет в массив.
б) Распечатывает на экране полученный в пункте а) массив в формате в соответствии с вариантом (таблица 2)
в) Осуществляет операцию по обработке массива, полученного в п.а) в соответствии с вариантом (таблица 3) и распечатывает результат выполнения на экране.
г) Осуществляет вывод данных о разработчике в соответствии с вариантом

Таблица 1.
Выражение
Y=3X^3+2X-EXP(1-X)

Таблица 2. Формат вывода массива результатов
Расположение на экране
*
*

*

Таблица 3. Операция по обработке массива результатов
Операция
поиск значения минимального элемента
----------------------------
snapsik вне форума Ответить с цитированием
Старый 04.12.2018, 14:02   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от snapsik Посмотреть сообщение
Много информации искал, но подобного не увидел((
Вот прям никакой инфы о сопроцессоре. Никаких примеров и задач. Может все-таки стоит поискать и почитать?
p51x вне форума Ответить с цитированием
Старый 04.12.2018, 14:43   #3
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Вот прям никакой инфы о сопроцессоре. Никаких примеров и задач. Может все-таки стоит поискать и почитать?
Можете посоветовать литературу с практическими примерами?
snapsik вне форума Ответить с цитированием
Старый 04.12.2018, 14:52   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Любая нормальная книга по асму. Можете в гугл вбить asm сопроцессор и переходить по ссылкам.
p51x вне форума Ответить с цитированием
Старый 04.12.2018, 22:08   #5
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Отличный совет, спасибо!
snapsik вне форума Ответить с цитированием
Старый 11.12.2018, 20:28   #6
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Добрый вечер! Значение регистра cx храню в стеке временно в подпрограмме. В основном блоке программы значение cx = 10. То есть, программа должна вывести 10 чисел в столбик при разных значениях x. Но на экран выводится только одно число первое, рассчитанное при x = 0. Почему не выводятся остальные числа? В td.exe смотрю cpu пошаговой отладкой, но там сегмент кода сильно искажен машинными командами, отладить не получается до конца, будто что-то циклит((
Компилирую в .com файл, так как в .exe не рассчитываются вещественные числа. Может компилировать нужно какими-то другими командами?


Код:
.286
.model tiny
; .model small
.data
 
 .code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        CrLf            db      0Dh, 0Ah, '$'
        X               dw      0
        Y               dw      ?
		i 				dw      0
		press    		db 'Press any key',13,10,'$'
		;int i = 10; 
start:
        ;программа
 ;temp    equ word ptr [bp-4]
 
        fninit
		
		mov i,0
		
		mov cx,10
		
label1:
		mov ax,[i] 
		fild    [i]				;загрузить целое число со знаком в стек
        ;fild    [X]				;загрузить целое число со знаком в стек
        fld1					;поместить в стек 1.0 (вещественное число)
        fld     st(1)
        fsubp   st(1),  st(0)       ; st(0)=1-x, st(1)=x - верно??
        ;exp(1-x)
        fldl2e                  ;st(0)=1/ln(2)=log2(e)
        fmulp   st(1),  st(0)   ;st(0)=x/ln(2)=x*log2(e)
        fld     st(0)
        frndint
        fsub    st(1), st(0)
        fxch    st(1)
        f2xm1                   ;st(0)=2^(mantissa)-1
        fld1                    ;st(0)=2^(mantissa)-1+1=2^(mantissa)
        faddp   st(1), st(0)
        fscale
        fstp    st(1)
       	;2*x-epx(1-x)
        fxch    st(1)
        fld     st(0)
        fadd    st(0),  st(0)
        fxch    st(2)
        fsubp   st(2),  st(0)
        ;3*x^3+2*x+epx(1-x)
        fld     st(0)
        fmul    st(0),  st(0)
        fmulp   st(1),  st(0)
        fld     st(0)
        fadd    st(0),  st(0)
        faddp   st(1),  st(0)
 
        faddp   st(1),  st(0)
 
        ;fistp  word ptr  [Y]
		;fistp temp
		
		;push 10
		;fld1
		call outfloat
		
		mov dx,offset press
		mov ah,09h
		int 21h
		
		
		
		;mov dh,dl         ;Сохраняем значение DL в DH
		;mov dl,13         ;
		;int 21h           ; 
		;mov dl,10         ;  Переход на следующую строку
		;int 21h           ;
		;mov dl,dh         ;Восстанавливаем значение DL
		
		
		;mov dl,10 ;10 или 0ah - символ перевода строки
		;mov ah, 2h  
		;int 21h 

		;mov dl,13 ;13 или 0dh - символ возврата каретки
		;mov ah, 2h  
		;int 21h
		
		
		; и сразу выведем.
        ;mov     ah, 02h
		;mov     dl, [Y]
        ;add     dl, 30h
        ;int     21h
		
		;mov     ax, temp        ; по дробной части идем слева, значит число выводим сразу, без предварительного сохранения в стек
        ;or      al, 30h         ; перевод в ascii
        ;int     29h             ; на экран
		inc i
		;cmp ax,10     ;Сравнение AL и 10
		; jb label1        ;Переход, если AL < 10 (числа без знака)

		loop label1
		
		
		mov ah,10h;ждём нажатия клавиши...
		int 16h
		
		
        ;завершение программы
        int     20h
		RET                             ;Возврат из процедуры
		
main    endp		
;-----------------------------------------------------------------------------------------------------------------------------------
;ВЫВОД ВЕЩЕСТВЕННОГО ЧИСЛА
;-----------------------------------------------------------------------------------------------------------------------------------
; .exit
 
; Вывод вещественного числа
; аргумент - количество цифр дробной части
length_frac     equ     [bp+4]
; локальные переменные
ten     equ word ptr [bp-2]
temp    equ word ptr [bp-4]
 
 OutFloat proc   near
        push cx
		
		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 ; помещаем в счетчик длину дробной части
		mov     cx, 2 ; помещаем в счетчик длину дробной части
		
@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
        
		
		;mov dl,10 ;10 или 0ah - символ перевода строки
		;mov ah, 2h  
		;int 21h 

		;mov dl,13 ;13 или 0dh - символ возврата каретки
		;mov ah, 2h  
		;int 21h
		
		
		
		pop cx
				
		leave                   ; эпилог
        ret 2    
OutFloat endp

end     main
 
                
 ;       BEGIN   ENDP
;	   CODESG  ENDS
 ;       END     BEGIN
snapsik вне форума Ответить с цитированием
Старый 11.12.2018, 22:06   #7
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от snapsik Посмотреть сообщение
Значение регистра cx храню в стеке временно в подпрограмме.
Если Вы cx кладёте в стек перед enter, то вынимать надо после leave.
И наоборот.
Black Fregat вне форума Ответить с цитированием
Старый 12.12.2018, 19:09   #8
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Точно, заработало! Спасибо большое!
snapsik вне форума Ответить с цитированием
Старый 12.12.2018, 22:37   #9
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

А Вы не знали, что enter / leave работают со стеком?
Black Fregat вне форума Ответить с цитированием
Старый 12.12.2018, 23:02   #10
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

не знал, я только разбираюсь с ассемблером
snapsik вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
С использованием цикла для вычисления суммы ряда решить уравнение ben74 Помощь студентам 0 15.03.2012 10:00
Решить уравнение с использованием цикла для вычисления суммы ряда ben74 Помощь студентам 1 05.02.2012 12:48
пробл с использованием сопроцессора Aneli Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 12 25.11.2009 21:44
решить с использованием процедуры!помогите сделать. st1m Паскаль, Turbo Pascal, PascalABC.NET 1 01.04.2009 19:26
Помогите разработать программу для вычисления корней алгебраического уравнения вида f(x)=0 BIS88 Помощь студентам 2 16.11.2008 08:11