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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.12.2018, 23:04   #11
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

подскажите, как лучше организовать занесение вещественных чисел в массив и найти в нем минимальное значение?
snapsik вне форума Ответить с цитированием
Старый 18.12.2018, 22:12   #12
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Добрый день!
У меня в цикле выводятся на экран рассчитанные значения выражения. Помимо этого, я каждое значение добавляю в массив. В идеале потребуется найти минимальный элемент массива. На данный момент, у меня ошибка при компиляции. В ax планирую писать рассчитанный минимальный элемент массива, а потом вывести на экран.
Ругается, когда пытаюсь в сопроцессор поместить число из ax, потом должна сработать функция вывода вещественного числа:
mov max,ax
fld ax
call outfloat
Подскажите, что тут не так?

Код:
.286
.model tiny
.data
 
 .code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        CrLf            db      0Dh, 0Ah, '$'
        X               dw      0
        Y               dw      ?
		i 				dw      0
		press    		db 13,10,'$'
		
        mas dw 11 dup (?)
		max dw ?
		;int i = 10; 
start:
        ;программа
  
        fninit
		
		mov i,0
		
		mov cx,11
		lea bx, mas
		
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)
 
   	
		add ax,[bx]
		
		call outfloat
				
		
		mov dx,offset press		;перевод курсора
		mov ah,09h
		int 21h
		
		
	

		inc i
		inc bx 	 ;переход к следующему элементу (размер элемента=1 байту)
	
		loop label1
		
		mov max,ax
		fld ax
		call outfloat
		
				
		mov ax,4C00h      
		int 21h           ;/ Завершение программы
		
        ;завершение программы
        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
		push ax
		
		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
        
					
		leave                   ; эпилог
		
		pop ax
		pop cx
		
        ret 2    
OutFloat endp

end     main
Изображения
Тип файла: png 1.png (4.9 Кб, 73 просмотров)
snapsik вне форума Ответить с цитированием
Старый 19.12.2018, 03:27   #13
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от snapsik Посмотреть сообщение
пытаюсь в сопроцессор поместить число из ax
Это что-то странное
Black Fregat вне форума Ответить с цитированием
Старый 19.12.2018, 22:08   #14
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

добавил новую строку 67 fst dword ptr[bx]....это помогает заполнять массив значениями?
Код:
.286
.model tiny
.data
 
 .code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        CrLf            db      0Dh, 0Ah, '$'
        X               dw      0
        Y               dw      ?
        i               dw      0
        press           db 13,10,'$'
        
        mas dw 11 dup (?)
        min dw ?
        ;int i = 10; 
start:
        ;программа
  
        fninit
        
        mov i,0
        
        mov cx,11
        lea bx, mas
        
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)
 
        fst dword ptr[bx]
    
        add ax,[bx]
        
        call outfloat
                
        
        mov dx,offset press     ;перевод курсора
        mov ah,09h
        int 21h
        
        
    
 
        inc i
        inc bx   ;переход к следующему элементу (размер элемента=1 байту)
    
        loop label1
        
        mov min,1
        ;fld 1
        call outfloat
        
                
        mov ax,4C00h      
        int 21h           ;/ Завершение программы
        
        ;завершение программы
        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
        push ax
        
        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
        
                    
        leave                   ; эпилог
        
        pop ax
        pop cx
        
        ret 2    
OutFloat endp
 
end     main
snapsik вне форума Ответить с цитированием
Старый 28.12.2018, 21:06   #15
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Ребят, где можно найти информацию по поиску минимального элемента в стеке сопроцессора fpu ? Элементы - вещественные числа, могут быть знаковые..
snapsik вне форума Ответить с цитированием
Старый 28.12.2018, 21:15   #16
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

А чем это будет отличаться от поиска максимума в массиве, кроме доступа к элементам? Вам для этого нужна отдельная инструкция?
p51x вне форума Ответить с цитированием
Старый 28.12.2018, 21:46   #17
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Да, можно и поиск максимума для примера, там думаю и для минимума переделать будет не трудно. У вас есть пример подобный?
snapsik вне форума Ответить с цитированием
Старый 28.12.2018, 21:56   #18
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Добрый день. У меня получилась вот такая программа.. но поиск минимального не корректный( Никто толком не может понять как правильно прописать.. Может вы сможете понять в чем проблема?

Код:
; -------------------------------------------------------------------------------
.286
.model tiny
.data
 
 .code
 
        org     100h
main    proc
 
        jmp     start
 
        ;Данные
        CrLf            db      0Dh, 0Ah, '$'
        X               dw      0
        Y               dw      ?
		i 				dw      0
		press    		db 13,10,'$'
		msgPressAnyKey  db      0Dh, 0Ah, 'Press any key to exit...', '$'
		msgResult       db      'Result array:', 0Dh, 0Ah, '$'
		minElem  		db 13,10,'Минимальный  элемент массива: $'
        mas dd 11 dup (?)
		min dw ?
		;int i = 10; 
start:
        ;программа
  
        fninit
		
		mov i,0
		
		mov cx,11
		lea si, mas
		
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)
 
		fst dword ptr [si]
	
	
		;add ax,[bx]
		
		call outfloat
				
		
		mov dx,offset press		;перевод курсора
		mov ah,09h
		int 21h
		
		
	

		inc i
		add si, 4 	 ;переход к следующему элементу массива
	
		loop label1
		
		
		
		;вывод результата
        mov     ah,     09h
        lea     dx,     [msgResult]
        int     21h
		
		 ;вывод массива
        fninit
        mov     cx,     11
        lea     si,     mas
        @@ForShow:
                ;push    cx
                fld     dword ptr [si]
                add     si,     4
                push    word ptr 2
                ;call    OutFloat
 
                ;mov     ah,     09h
                ;lea     dx,     [CrLf]
                ;int     21h
                ;pop     cx
        loop    @@ForShow
		
		;поиск минимального значения
		mov     cx,     11
		poiskmin:
		;push    cx
		fcom st(1)	;Сравнить ST(0) и ST(i) и установить флаги ZF, PF, CF согласно результата
		JGE next1			;больше либо равно
		fxch st(1)  ;меняем местами, чтобы min оказался в st(1)
		next1:
			fstp st(0)        ;удаляем ненужное значение st(0)
			;pop     cx
			loop poiskmin
		
		call outfloat
		
			
		 ;ожидание нажатия любой клавиши
        mov     ah,     09h
        lea     dx,     [msgPressAnyKey]
        int     21h
 
        mov     ah,     00h
        int     16h
		
		
				
		mov ax,4C00h      
		int 21h           ;/ Завершение программы
		
        ;завершение программы
        ;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
		push ax
		
		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
        
					
		leave                   ; эпилог
		
		pop ax
		pop cx
		
        ret 2    
OutFloat endp

end     main
snapsik вне форума Ответить с цитированием
Старый 02.01.2019, 21:42   #19
snapsik
Пользователь
 
Регистрация: 06.02.2012
Сообщений: 13
По умолчанию

Добрый вечер. Есть у кого-нибудь пример с поиском минимального значения в стеке fpu? Или может кто знает как это организовать? Должны учитываться знаковые вещественнык числа.. не могу отыскать подобной информации((
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