IPB
ЛогинПароль:

> ПРАВИЛА РАЗДЕЛА!!!

1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!

> Ошибка в программе вычисления интеграла, метод трапеций
Hey
сообщение 7.09.2012 20:32
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


Приветствую,

пишу программу вычисления интеграла функции 1/ln x методом трапеций, для начала взял n=20 (затем буду увеличивать). Файл .exe создан, но выдает ошибку и вылетает. При просмотре в дебаггере вижу, что еще на этапе вычисления шага в регистре ST0 оказывается отрицательная величина, еще через пару шагов вылетает. В чем тут дело?

Заранее спасибо.


.486p
.model small
.stack 100h
.data
a dw 2
b dw 5
x dq 2
n dw 20
h dq ?
y dq ?

.code
main proc
mov ax, @data
mov ds, ax
finit
fild b
fisub a
fidiv n
fst h ;вычисляем шаг h


fld1
fild b
fyl2x
fldln2
fmul
fld1
fdiv
fADD y
fild b
fdivr st(1), st ;вычисляем (ln a + ln b)/2

cycl:
fadd y
fst y

fild x
fadd h
fst x ;производим приращение х и каждый раз сохраняем
ficom b
je mult_ ;пока не равно b(=5),продолжаем

fld x
fyl2x
fldln2
fmul
fld1
fdiv ;
loop cycl ;

mult_:
fld y ;
fld h ;
fmul ;когда х достиг значения 5, перемножаем на h

exit:
mov ax, 4c00h ;
int 21h ;
main endp
end main

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Hey
сообщение 5.10.2012 22:47
Сообщение #2


Новичок
*

Группа: Пользователи
Сообщений: 15
Пол: Мужской

Репутация: -  0  +


IUnknown, опять вынужден обратиться. Та же многострадальная программа, но для другой функции: требуется вычислить интеграл от функции sin (3x+3) / 7x+6. Беда в том, что я привязан к средствам процессора 286 и команду fsin использовать не могу. Иду окольным путем, через процедуру вычисления частичного тангенса fptan. Пока возникли две проблемы:
1. Решительно не хочет правильно разделить pi на 4. Это переменная four в формате слова. Эксперименты с присвоением ей другого формата (dq) или обозначения (например, 4.0. вместо 4) дают еще более неправильный результат.
2. После завершения энтой процедуры вычисления синуса возврат идет не к месту ее вызова, а к началу кода.

Что за напасть?

.286p
.model small
.stack 100h
.data
mes db 'Operands not comparable', 13, 10, '$'
a dw 1
b dw 5
x dd 1
n dw 0
d dw 20
eps dd 0.0001
two dw 2
three dw 3
seven dw 7
six dw 6
h dq ?
y dq ?
z dq ?
NL db 0Dh, 0Ah, "$"
STATUS DW ?
FOUR dw 4
C3 EQU 40H
C2 EQU 04H
C1 EQU 02H
C0 EQU 01H


.code

CalcF macro; На вершине стека д.б. "x"

fimul three
fiadd three
call sin

fstp y
fld x
fimul seven
fiadd six
fld y
fdivr

endm

iCalcF macro param

fild param
fimul three
fiadd three

call sin
fstp y
fild param
fimul seven
fiadd six
fld y
fdivr

endm

Сalc_h macro
mov cx, n
add cx, d
mov n, cx
dec cx

; вычисляем шаг
finit
fild b
fisub a
fidiv n
fst h ; Сохраняем шаг
endm

main proc

mov ax, @data
mov ds, ax

outer_:
fld y
fstp z
Сalc_h
iCalcF b
fstp y
iCalcF a
fadd y ; Складываем
fidiv two ; Делим сумму на 2
fstp y ; Сохр. начальное приближение

; внутренний цикл - вычисляем ФУНКЦИЮ
fld x ; X в стек сопроцессора
inner_loop:
fadd h ; X <- X + h
CalcF
fadd y
fstp y ; Сохраняем новое значение
loop inner_loop

fld y
fmul h
fst y

call outfloat
call OutInt ;выводим актуальное n
finit

fld y
fsub z
fabs
fcomp eps
fstsw ax
sahf

jp m2
jz m1
jc exit
jmp outer_

m1: jmp outer_

m2:
MOV DX, offset mes
mov Ah,09
int 21h

exit:
mov ax, 4c00h ;
int 21h ;
main endp

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, '-'
int 21h
; и оставляем модуль числа.
fchs

@of1: fld1
fld st(1)
fprem
fsub st(2), st
fxch st(2)

xor cx, cx

@of2: fidiv word ptr [bp - 2]
fxch st(1)
fld st(1)
fprem
fsub st(2), st
fimul word ptr [bp - 2]
fistp word ptr [bp - 4]
inc cx
push word ptr [bp - 4]
fxch st(1)
ftst
fstsw ax
sahf
jnz short @of2
; Теперь выведем её.
mov ah, 02h
@of3: pop dx
add dl, 30h
int 21h
; И так, пока не выведем все цифры.
loop @of3
; Теперь за дробную часть, для начала проверив её существование.
fstp st(0)
fxch st(1)
ftst
fstsw ax
sahf
jz short @of5
; Если она ненулевая, выведем точку
mov ah, 02h
mov dl, '.'
int 21h
; и не более четырех цифр дробной части.
mov cx, 4
; Помножим дробную часть на десять,
@of4: fimul word ptr [bp - 2]
fxch st(1)
fld st(1)
; отделим целую часть
fprem
; оставим от произведения лишь дробную

часть,
fsub st(2), st
fxch st(2)
; сохраним полученную цифру во временной ячейке
fistp word ptr [bp - 4]
; и сразу выведем.
mov ah, 02h
mov dl, [bp - 4]
add dl, 30h
int 21h
; Теперь, если остаток дробной части ненулевой
fxch st(1)
ftst
fstsw ax
sahf
; и мы вывели менее четырех цифр, продолжим.
loopnz @of4
; Осталось убрать мусор из стэка.
@of5: fstp st(0)
fstp st(0)

leave

mov AH,9
mov dx, offset NL
int 21h

pop dx
pop cx
pop ax
ret
outfloat endp

OutInt proc near
push cx
push dx
push bx
push ax

mov ax,n
xor cx, cx
mov bx, 10
l1:
xor dx,dx
div bx
push dx
inc cx
test ax, ax
jnz l1
mov ah, 02h
l2:
pop dx
add dl, 30h
int 21h
loop l2

mov AH,9
mov dx, offset NL
int 21h

pop ax
pop bx
pop dx
pop cx
ret
outint endp

SIN PROC near
PUSH DS
SUB AX, AX
PUSH AX
MOV AX, CS
MOV DS, AX
MOV ES, AX

DO_AGAIN:

FLDPI ; PI ; X
FIDIV FOUR ; PI/4 ; X
FXCH ; X ; PI/4
FPREM ; R ; PI/4
FSTSW STATUS
FWAIT
MOV AH, BYTE PTR STATUS+1
TEST AH, C1 ; Определяется, необходимо ли вычитание PI/4
JZ DO_R ; Если 0, то не нужно
FSUBRP ST(1), ST(0) ; A = PI/4-R ; ?
JMP SHORT DO_FPTAN

DO_R:
FXCH ; PI/4 ; R
FCOMP ; R ; ?

DO_FPTAN:

FPTAN ; OPP ; ADJ Где

OPP/ADJ=Tan(A)

;----- Определение того, что нужно - синус или косинус

TEST AH, C3 or C1

JPE DO_SINE

FXCH ; ADJ ; OPP
DO_SINE: ; D ; N


; Вычисление N/SQR(N**2 + D**2)
FMUL ST(0),ST(0) ; D**2 ; N
FXCH ST(1) ; N ; D**2
FLD ST(0) ; N ; N ; D**2
FMUL ST(0),ST(0) ; N**2 ; N ; D**2
FADD ST(0), ST(2) ; N**2 + D**2 ; N ; D**2
FSQRT ; SQR(N2 + D2) ; N ; D**2
FDIVRP ST(1) ; SIN(X) ; D**2
FXCH ST(1) ; D**2 ; SIN(X)
FCOMP ; SIN(X) ; ?
Test ah, C0
jz return_inst
fchs
return_inst:
RET

SIN ENDP

end main























 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
Hey   Ошибка в программе вычисления интеграла   7.09.2012 20:32
IUnknown   А ты в дебаггере посмотрел, что именно грузится в ...   8.09.2012 12:00
Hey   Спасибо, с тем фрагментом действительно пошло. Гд...   9.09.2012 12:30
TarasBer   А почему всё-таки fild пятёрки загрузил 8397?   9.09.2012 14:31
Hey   Снова загвоздка: не принимает директиву loop, попр...   9.09.2012 17:30
IUnknown   Это особенности цикла LOOP. Чтобы он работал, надо...   9.09.2012 18:14
Hey   P.S. ТОчно, забыл на счетчик СХ поставить. Правда,...   9.09.2012 18:31
IUnknown   С описанием x dd 2.0 все итерации проходят (прове...   9.09.2012 19:04
Hey   С описанием x dd 2.0 все итерации проходят (пров...   9.09.2012 21:08
Hey   Опять вынужден обратиться: программу продолжил, но...   10.09.2012 16:48
IUnknown   Во-первых, с чего ты решил, что вот это: сработает...   10.09.2012 20:12
IUnknown   Вот первоначальный вариант (можно еще дорабатывать...   11.09.2012 16:14
Hey   Однако серьезно! Буду пробовать. Признателен) ...   11.09.2012 21:54
Hey   Цикл ему кажется слишком длинным: на инструкции lo...   12.09.2012 18:11
IUnknown   Ты б за структурой следил, и вторую процедуру запи...   12.09.2012 23:10
Hey   Да, фрагмент с exit'ом я не туда вставил. Дейс...   13.09.2012 14:32
IUnknown   Это для перевода строки: NewLine, символ CR = 13, ...   13.09.2012 15:09
Hey   Решительно не хватает знаний, чтобы успешно заверш...   14.09.2012 20:22
IUnknown   Hey, я опять не понял, зачем тебе 2 цикла, в каждо...   15.09.2012 11:30
Hey   IUnknown, ты прав: уперся я в свое решение как лун...   15.09.2012 17:36
IUnknown   Еще вопрос: в какой программе ты набираешь листинг...   15.09.2012 18:24
Hey   Отлично, спасибо))   15.09.2012 19:12
Hey   IUnknown, опять вынужден обратиться. Та же многост...   5.10.2012 22:47
Hey   Порядок, нашел ошибки. Из процедуры SIN надо было ...   8.10.2012 15:55


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 20.04.2024 18:44
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"