Консультация № 177751
08.04.2010, 20:56
45.00 руб.
0 6 1
Уважаемые эксперты.
Помогите пожалуйста написать программу.
Требуется вычислить значения заданных функций с помощью TASM, используя стандартные директивы сегментации. Все переменные описать в разных сегментах данных, каждую функцию — в виде отдельной подпрограммы, используя разные способы передачи параметров. Вычисления, которые встречаются несколько раз, оформить в виде макрокоманд.

a=(ln3(1+cos|z-1|)+0,71y)/(2x-3+0,005zy)

b=ln3(1+cos|z-1|)+5

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

Обсуждение

давно
Посетитель
7438
7205
09.04.2010, 17:28
общий
это ответ
Здравствуйте, Comtessa D.
Программа в приложении

Приложение:
;Требуется написать программу для вычисления двух выражений
;с использованием макросов и процедур.
;Каждую переменную(x,y,z) описывать в отдельных сегментах данных
;a=(ln^3(1+cos|z-1|)+0,71y)/(2x^(-3)+0,005zy)
;b=ln^3(1+cos|z-1|)+5

.386 ;необходимо для команды fcos
sseg segment stack "stack"
db 1024 dup (0)
sseg ends

dsegX segment use16 para public 'data'
x dq 1.5
dsegX ends

dsegY segment use16 para public 'data'
y dq 5.6
dsegY ends

dsegZ segment use16 para public 'data'
z dq 1.1
dsegZ ends

dseg segment use16 para public 'data'
a dq ?
b dq ?
;константы
c71 dq 0.71
c2 dq 2.
c3 dq 3.
cm3 dq -3.
c5 dq 5.
c005 dq 0.005
dseg ends

;в st должно находиться xlog[2]y
POWER MACRO
fld st ;x*log[2]e->st(1)
frndint ;округляем st до целого
fsub st(1),st ;st(1)-=st
fxch ;st(1)<->st
f2xm1 ;st=(2 в степени st) - 1
fld1 ;1->st
fadd ;st+=1
fscale ;exp = st * (2 в степени st(1))
fstp st(1) ;чтобы убрать значение из st(1)
ENDM

;(ln^3(1+cos|z-1|)
LN3Z MACRO zoff
fld c3 ;3 (для fyl2x)

les bx, dword ptr zoff ;address z
fld qword ptr es:[bx] ;z->st
fld1 ;1
fsubp ;z-1
fabs ;|z-1|
fcos ;cos(|z-1|)
fld1 ;1
faddp ;1+cos(|z-1|)
fld1 ;1
fxch ;st(1)<->st
fyl2x ;st=1*log[2]st=log[2](1+cos(|z-1|))
fldl2e ;log[2]e
fdivp ;st=ln(1+cos(|z-1|))

fyl2x ;st=st(1)*log[2]st=3*log[2]st
POWER ;находим (ln()^3)
ENDM

cseg segment para use16 public 'code'
assume cs:cseg, ss:sseg, ds:dseg
start:
mov ax,sseg
mov ss,ax
mov ax,dseg
mov ds,ax

push dsegX ;в стек длинные адреса x
push offset x
push dsegY ;y
push offset y
push dsegZ ;z
push offset z
call calc_a ;получаем в st ответ
fstp a ; и сохраняем его в переменной

push dsegZ ;z
push offset z
call calc_b ;получаем в st ответ
fstp b ; и сохраняем его в переменной

mov ax,3c00h
int 21h

par_z equ [bp+4] ;для адресации в стеке
par_y equ [bp+8]
par_x equ [bp+12]

calc_a proc
push bp
mov bp,sp

LN3Z par_z ;st = ln^3(1+cos|z-1|)
les bx, dword ptr par_y ;длинный указатель на y
fld qword ptr es:[bx] ;st = y
fmul c71 ;st = 0.71*y
faddp ;st = ln^3(1+cos|z-1|)+0.71y

fld cm3 ;st = -3
les bx, dword ptr par_x ;длинный указатель на x
fld qword ptr es:[bx] ;st = x
fyl2x ;st=st(1)*log[2]st=(-3)*log[2]x
POWER ;находим x^(-3)
fmul c2 ;2*x^(-3)
les bx, dword ptr par_z ;длинный указатель на z
fld qword ptr es:[bx] ;st = z
les bx, dword ptr par_y ;длинный указатель на y
fmul qword ptr es:[bx] ;st = z*y
fmul c005 ;st = 0.005*z*y
faddp ;st = 2*x^(-3)+0.005*z*y

fdivp ;st=ln^3(1+cos|z-1|)+0.71y / 2*x^(-3)+0.005*z*y

pop bp
ret 12
calc_a endp

calc_b proc
push bp
mov bp,sp

LN3Z par_z ;st = ln^3(1+cos|z-1|)
fadd c5 ;st = ln^3(1+cos|z-1|) + 5

pop bp
ret 4
calc_b endp

cseg ends
end start
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
09.04.2010, 17:34
общий
Comtessa D:
Вам случайно не знакомы авторы вот этого и этого вопросов?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
09.04.2010, 21:28
общий
Лысков Игорь Витальевич:
при вызове calc_b вы пушите только один параметр:

...
push dsegZ ;z
push offset z
call calc_b ;получаем в st ответ
...

а при выходе из подпрограммы выравниваете стек как будто бы для трех параметров:

...
pop bp
ret 12
calc_b endp
давно
Посетитель
7438
7205
11.04.2010, 02:08
общий
Alex_S:
Подправил, спасибо.
Подобных вопросов уже три, за основу взял один из предыдущих, это место, увы, не подправил...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
11.04.2010, 22:38
общий
Лысков Игорь Витальевич:
Знакомы)
Неизвестный
11.04.2010, 22:39
общий
Alex_S:
Спасибо, буду разбираться
Форма ответа