![]() |
1. Заголовок или название темы должно быть информативным
2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE]
3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора.
5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM!
6. Проверяйте программы перед тем, как выложить их на форум!!
![]() ![]() |
![]() |
Hey |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Приветствую,
пишу программу вычисления интеграла функции 1/ln x методом трапеций, для начала взял n=20 (затем буду увеличивать). Файл .exe создан, но выдает ошибку и вылетает. При просмотре в дебаггере вижу, что еще на этапе вычисления шага в регистре ST0 оказывается отрицательная величина, еще через пару шагов вылетает. В чем тут дело? Заранее спасибо.
|
IUnknown |
![]()
Сообщение
#2
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
А ты в дебаггере посмотрел, что именно грузится в ST0 при выполнении
finit? Там явно не 5-ка, а 8397: ![]() Измени режим процессора на .286p, тогда значения станут подгружаться нормально, и по крайней мере h вычисляется правильно, дальше не проверял. |
Hey |
![]()
Сообщение
#3
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Спасибо, с тем фрагментом действительно пошло. Где-то дальше еще есть ошибки, сейчас буду смотреть.
|
TarasBer |
![]()
Сообщение
#4
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
А почему всё-таки fild пятёрки загрузил 8397?
-------------------- |
Hey |
![]()
Сообщение
#5
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Снова загвоздка: не принимает директиву loop, попросту ее пропускает. Это свойство моей версии ассемблера или режима 286р?
P.S. Виноват: забыл на счетчик СХ поставить. Правда, он почему-то считает только два цикла, затем обнуляется. Притом во втором цикле в x грузит сразу 4,8 вместо 2,15. ... прилагаю новый листинг.
Сообщение отредактировано: Hey - 9.09.2012 18:29 |
IUnknown |
![]()
Сообщение
#6
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Это свойство моей версии ассемблера или режима 286р? Это особенности цикла LOOP. Чтобы он работал, надо занести число повторений в CX. У тебя CX - нулевой. Похоже, тебе нужен не LOOP, а простой JMP, если ты из цикла уходишь по "je mult_"Цитата А почему всё-таки fild пятёрки загрузил 8397? А кто его знает... В 286-ом режиме грузит нормально, выше - начинает придумывать что-то своё. |
Hey |
![]()
Сообщение
#7
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
P.S. ТОчно, забыл на счетчик СХ поставить. Правда, он почему-то считает только два цикла, затем обнуляется. Притом во втором цикле в x грузит сразу 4,8 вместо 2,15. ... прилагаю новый листинг.
.286p .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 mov CX, [n] dec CX finit fild b fisub a fidiv n fst h ;вычисляем шаг h finit fld1 fild b fyl2x fldln2 fmul ; вычиcляем ln 5 fld1 fdivr ;вычиcляем 1/ln 5 fstp y fldln2 fld1 fdivr ; вычисляем 1/ln2 fadd y fstp y fild a fld y fdivr ;вычисляем (1/ln a + 1/ln b)/2 fstp y cycl: finit fld x fadd h fst x ;производим приращение х и каждый раз сохраняем fld1 fld x fyl2x fldln2 fmul fld1 ; fdivr ; fadd y fstp y loop cycl ; mult_: fld y fld h fmul |
IUnknown |
![]()
Сообщение
#8
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
С описанием
x dd 2.0все итерации проходят (проверял 4 первых, дальше не хватило терпения, на выходе, после того как цикл завершился) имеем: Эскизы прикрепленных изображений ![]() |
Hey |
![]()
Сообщение
#9
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
|
Hey |
![]()
Сообщение
#10
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Опять вынужден обратиться: программу продолжил, но новый фрагмент он не видит и сразу переходит к выводу на экран прежнего значения для n=20. Привожу листинг без процедуры вывода на экран:
|
IUnknown |
![]()
Сообщение
#11
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Во-первых, с чего ты решил, что вот это:
Цитата fild n fcomp x ; сравниваем верхушку стека с числом XА во-вторых - зачем тебе все эти пляски с прыжками из одной части кода в другую? Сделай 2 нормальных вложенных цикла, изначально N присвой 0, и тут же его увеличивай на D, это будет внешний цикл. А внутренний - вычисление самого интеграла. Программа упростится донельзя (а если еще воспользоваться макросредствами ассемблера - у тебя же TASM, я правильно понимаю?) то все будет еще проще. |
IUnknown |
![]()
Сообщение
#12
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Вот первоначальный вариант (можно еще дорабатывать)
.286p |
Hey |
![]()
Сообщение
#13
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Однако серьезно! Буду пробовать. Признателен)
Кстати, почему я организовал дополнительные циклы, и ввел переменную у2: необходимо найти решение с определенной точностью (0,0001). Для этого придется сравнивать значения F для каждых "соседних" n. Соответственно, если для каждого последующего n я записываю значения f в одну и ту же переменную у, то значения при меньшем n теряются. Попробую что-нибудь придумать. Сообщение отредактировано: Hey - 11.09.2012 22:54 |
Hey |
![]()
Сообщение
#14
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цикл ему кажется слишком длинным: на инструкции loop outer_loop выдает "Relative jump out of range by 22h bytes". И почему-то стал ругаться на невинную команду fstsw ax: "Illegal immediate".
P.S. Я решил оформить макросом приращение n и вычисление h, прилагаю код целиком.
|
IUnknown |
![]()
Сообщение
#15
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Цикл ему кажется слишком длинным: на инструкции loop outer_loop выдает "Relative jump out of range by 22h bytes". И почему-то стал ругаться на невинную команду fstsw ax: "Illegal immediate". Ты б за структурой следил, и вторую процедуру записывал бы после того, как первая закончится - было бы меньше неожиданностей. Насчет цикла - не подтверждается, код прекрасно собирается (помнят еще руки-то ![]() .286p Сообщение отредактировано: IUnknown - 12.09.2012 23:11 Эскизы прикрепленных изображений ![]() |
Hey |
![]()
Сообщение
#16
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Да, фрагмент с exit'ом я не туда вставил. Действительно работает, спасибо)). Вопрос: что означает строка NL db 0Dh, 0Ah, "$" ?
|
IUnknown |
![]()
Сообщение
#17
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Это для перевода строки: NewLine, символ CR = 13, символ LF = 10, и завершение строки - знак доллара
![]() |
Hey |
![]()
Сообщение
#18
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
Решительно не хватает знаний, чтобы успешно завершить программу. Я ее расширил, чтобы n возрастало до тех пор, пока не будет достигнута требуемая точность (0.0001). Вместо вывода значения функции при каждом из n (20, 40, 60 ....) прога выводит окончательное значение, причем не один раз((. Вывод n также не работает. Прилагаю.
|
IUnknown |
![]()
Сообщение
#19
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Hey, я опять не понял, зачем тебе 2 цикла, в каждом из которых ты вычисляешь значения интегралов? Давай запишем алгоритм который тебе нужен, в псевдокоде. Итак, чтобы определить, при каком N значение интеграла найдено с точностью Eps, тебе достаточно:
n <- 0 Всё, никаких двойных циклов, все прекрасно делается одним. А теперь смотри, как это записывается на ассемблере (я заменил переменную z на prev): main procПроще, правда, чем делать дважды одно и то же? Теперь насчет Цитата Вывод n также не работает. Процедуру OutInt проверять не пробовал? ![]() Вообще-то, она должна выглядеть так (вообще-то, жестко задавать в программе, что процедура выводит именно N - это бред, лучше перед ее вызовом занести ax <- N): outint proc nearС этими изменениями программа прекрасно отрабатывает: F:\Asm30>trapece |
Hey |
![]()
Сообщение
#20
|
Новичок ![]() Группа: Пользователи Сообщений: 15 Пол: Мужской Репутация: ![]() ![]() ![]() |
IUnknown, ты прав: уперся я в свое решение как лунатик и увидеть больше ничего не мог). С одним циклом все внятно. Спасибо за терпение
![]() |
![]() ![]() |
![]() |
Текстовая версия | 12.09.2024 9:17 |