Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

гос / sp-lect (1)

.pdf
Скачиваний:
18
Добавлен:
16.02.2016
Размер:
2.59 Mб
Скачать

від значення <операнд2> і зберігають результат в <операнд1>: <операнд1><операнд2>–< операнд1>. Команди з пост суфіксом «P» після цього ще виштовхують значення із верхівки стеку ST(0), звільняючи таким чином стек. Команда без операндів FSUB еквівалентна команді FSUBP ST(1),ST(0), а команда без операндів FSUBR еквівалентна команді FSUBRP

ST(1),ST(0).

Команди множення з одним операндом

F[I ]MUL < операнд >= FMUL операнд

= FMUL mem32 fp / mem64 fp

FIMUL операнд

FIMUL mem16int/ mem32 int

множать значення <операнд> на значення на верхівці стеку ST(0) і зберігають результат в ST(0): ST (0) ← ST (0) i < операнд > .

Команди множення з двома операндами

FMUL ST (0), ST (i)

FMUL[P] [ < операнд1 >, < операнд2 >] = FMUL ST (i), ST (0)

FMULP ST (i), ST (0)

множать значення <операнд2> на значення <операнд1> і зберігають результат в <операнд1>: <операнд1><операнд1> · <операнд2>. Команди з пост суфіксом «P» після цього ще виштовхують значення із верхівки стеку ST(0), звільняючи таким чином стек. Команда без операндів еквівалентна команді FMULP ST(1),ST(0).

Команди ділення з одним операндом

FDIV операнд

FDIV mem32 fp / mem64 fp

F[I ]DIV [R] < операнд >= FIDIV операнд

= FIDIV mem16int/ mem32 int

FDIVR операнд

FDIVR mem32 fp / mem64 fp

FIDIVR операнд

FIDIVR mem16int/ mem32 int

без пост суфікса «R» ділять значення на верхівці стеку ST(0) на значення

ST (0)

<операнд> і зберігають результат в ST(0): ST (0) < операнд > . Пост суфікс

«R» змінює порядок операндів, тобто команди ділять значення <операнд> на

значення

на верхівці стеку ST(0) на і зберігають результат в ST(0):

< операнд >

ST (0)

ST (0)

Команди ділення з двома операндами

 

 

FDIV ST (0), ST (i)

 

 

FDIV ST (i), ST (0)

FDIV [R][P] [ < операнд1 >,< операнд2 >] = FDIVP ST (i), ST (0)

 

 

FDIVR ST (0), ST (i)

 

 

FDIVR ST (i), ST (0)

 

 

FDIVRP ST (i), ST (0)

без пост суфікса «R» ділять

значення <операнд1> на значення

<операнд2> і зберігають результат в <операнд1>:

< операнд1 >

< операнд1 >

 

< операнд2 >

 

 

Команди з пост суфіксом «R» ділять значення <операнд2> на значення <операнд1> і зберігають результат в <операнд1>:

< > ← < операнд2 > операнд1

< операнд1 >

Команди з пост суфіксом «P» після цього ще виштовхують значення із верхівки стеку ST(0), звільняючи таким чином стек. Команда без операндів FDIV еквівалентна команді FDIVP ST(1),ST(0), а команда без операндів FDIVR еквівалентна команді FDIVRP ST(1),ST(0).

Серед допоміжних арифметичних команд тут варто відзначити тільки чотири – FABS, FCHS, FSQRT і FRNDINT. Призначення інших допоміжних арифметичних команд поки що може виявитися не зрозумілим, і ми повернемося до їх розгляду в контексті інших задач, в яких вони виявляються корисними.

Команда FABS замінює число на верхівці стеку ST(0) його абсолютним значенням (модулем): ST (0) ← ST (0) . Команда FCHS змінює знак числа на верхівці стеку ST(0) на протилежний. Команда FSQRT обчислює квадратний

корінь числа на

верхівці стеку ST(0) і розміщує результат

в ST(0):

ST (0) ←

 

.

 

 

ST (0)

Команда FRNDINT округлює значення числа в

ST(0) до

цілого числа у відповідності з режимом округлення (заданим бітами RC CWR). Команд пересилання і обміну та базових арифметичних команд вже виявляється достатньо для реалізації деяких чисельних алгоритмів, що і демонструють наведені далі приклади. Приклади обмежуються використанням тільки тих функцій, обчислення яких можна виконати на основі основних арифметичних команд. Це обмеження ніяк не впливає на реалізацію алгоритму, і в подальшому, приклади можуть бути легко пристосовані для вирішення інших задач, заміною коду відповідної процедури для обчислення значення

функції з використанням трансцендентних функцій.

 

 

 

 

 

 

 

Приклад 8.1 Чисельне

інтегрування

10 x2dx =

x3

 

 

10

=

1000

= 333,3(3)

 

3

 

 

 

 

 

 

0

 

 

 

0

3

 

 

b

 

b - a

n−1

 

b - a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

методом прямокутників f ( x)dx =

f ( x +

×i)

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

a

 

i=0

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

; Файл integral.inc

 

 

 

 

 

 

 

 

 

 

 

 

 

include windows.inc

 

 

 

 

 

 

 

 

 

 

 

 

 

include user32.inc

 

 

 

 

 

 

 

 

 

 

 

 

 

include kernel32.inc

 

 

 

 

 

 

 

 

 

 

 

 

 

include masm32.inc

 

 

 

 

 

 

 

 

 

 

 

 

 

include C:\MASM32\MACROS\strings.mac

 

 

 

 

 

 

 

 

 

 

includelib

user32.lib

 

 

 

 

 

 

 

 

 

 

 

 

 

includelib

kernel32.lib

 

 

 

 

 

 

 

 

 

 

 

 

 

includelib

masm32.lib

 

 

 

 

 

 

 

 

 

 

 

 

 

Main PROTO

 

 

 

 

 

 

 

 

 

 

 

 

 

.data

 

 

 

 

 

 

 

 

 

 

 

 

 

 

szResult

db "Iнтеграл дорiвнює I = ",0

 

 

 

 

 

 

 

integral

dq 0.0

 

 

 

 

 

 

 

 

 

 

 

 

 

a

dq 0.0

 

 

 

 

 

 

 

 

 

 

 

 

 

b

dq 10.0

 

 

 

 

 

 

 

 

 

 

 

 

 

n

dd 10000

; Файл integral.asm

.386

.model flat, stdcall option casemap:none include integral.inc

.code

start: invoke Main

invoke ExitProcess,0

Main proc

LOCAL Buffer[128]:BYTE

invoke AllocConsole lea esi,Buffer

invoke CharToOem, $CTA0("Чисельне iнтегрування"), esi invoke SetConsoleTitle,esi

invoke ClearScreen

finit

 

fld b

; b

fsub a

; b-a

fidiv n

; h=(b-a)/n

fld a

; a, h

fld st(0)

; a, a, h

call function

; s=f(a), a, h

fxch

; a, s, h

mov ebx,n

 

dec ebx

 

@@: fadd st(0),st(2)

; x=a+h, s, h

fld st(0)

; x, x, s, h

call function

; f(x), x, s, h

faddp st(2),st(0)

; x, s=s+f(a+h), h

dec ebx

 

or ebx,ebx

 

jnz @B

 

fxch st(2)

; h, s=s+f(a+h), x

fmul

; I=s*h, x

fstp integral

; x

fstp st(0)

;

invoke CharToOem,ADDR szResult, esi invoke StdOut,esi

invoke FloatToStr,integral,esi invoke StdOut,esi

invoke CharToOem,\

$CTA0("\n\nНатиснiть Enter для завершення..."), esi invoke StdOut,esi

invoke StdIn,esi, 4

ret

Main endp function proc

; Вхід - число в st(0)

; Вихід - квадрат числа в st(0)

fld st(0) fmul

ret

function endp end start

10

 

x3

 

 

10

 

 

Приклад 8.2 Чисельне інтегрування

3x2dx = 3×

 

 

 

 

 

 

 

0

3

 

 

0

 

 

 

 

= x3 10 = 1000

0

 

b

 

 

 

a

+ b

 

b - a

1

b - a

n

 

 

 

 

 

 

методом Гауса f ( x)dx = x =

 

 

+

 

t

= f (t)dt =

 

Ai f (ti ) + D ,

 

2

 

2

 

a

 

 

 

 

 

2

1

i=1

 

 

 

 

 

 

 

 

 

 

де D =

(b - a)2n+1

(n!)4 M

2n

, M2n

максимальне значення 2n-ї похідної на [a,b]

[(2n)!]3 (2n +1)

 

 

 

 

 

 

 

 

 

 

 

 

Ai, ti для n=8 наведені в наступній таблиці

i

ti

Ai

i

ti

Ai

1

-0.96028996

0.10122854

5

+0.18343464

0.36268378

 

 

 

 

 

 

2

-0.79666648

0.22238104

6

+0.52553142

0.31370664

 

 

 

 

 

 

3

-0.52553142

0.31370664

7

+0.79666648

0.22238104

 

 

 

 

 

 

4

-0.18343464

0.36268378

8

+0.96028996

0.10122854

 

 

 

 

 

 

; Файл IntegralGauss.inc

include kernel32.inc include masm32.inc include user32.inc

include C:\MASM32\MACROS\strings.mac includelib kernel32.lib

includelib masm32.lib includelib user32.lib Main PROTO

.const

tdq -0.96028996, -0.79666648, -0.52553142, -0.18343464

dq 0.18343464, 0.52553142, 0.79666648, 0.96028986

Kdq 0.10122854, 0.22238104, 0.31370664, 0.36268378 dq 0.36268378, 0.31370664, 0.22238104, 0.10122854

.data

 

szResult

db "Iнтеграл дорiвнює I = ",0

integral

dq 0.0

adq 0.0

bdq 10.0

; Файл IntegralGauss.asm

.386

.model flat, stdcall

option casemap:none

include IntegralGauss.inc

.code

start: invoke Main

invoke ExitProcess,0

Main proc

LOCAL Buffer[128]:BYTE

invoke AllocConsole lea esi,Buffer

invoke CharToOem, $CTA0("Чисельне iнтегрування"), esi invoke SetConsoleTitle,esi

invoke ClearScreen

mov ecx,8

 

xor edi,edi

 

finit

 

fldz

; s=0

fld1

; 1, s

fld1

; 1, 1, s

fadd

; 2, s

fld b

; b, 2, s

fadd a

; b+a, 2, s

fdiv st(0),st(1)

; (b+a)/2, 2, s

fld b

; b, (b+a)/2, 2, s

fsub a

; b-a , (b+a)/2, 2, s

fdiv st(0),st(2)

; (b-a)/2 , (b+a)/2, 2, s

@@: fld st(0)

; (b-a)/2, (b-a)/2 , (b+a)/2, 2, s

fld t[edi]

; t, (b-a)/2 , (b-a)/2 ,(b+a)/2, 2, s

fmul

; t*(b-a)/2 , (b-a)/2 ,(b+a)/2, 2, s

fadd st(0),st(2)

; x=t*(b-a)/2 + (b+a)/2, (b-a)/2 ,(b+a)/2, 2, s

call function

; f(x), (b-a)/2 ,(b+a)/2, 2, s

fmul K[edi]

; K*f(x), (b-a)/2 ,(b+a)/2, 2, s

faddp st(4),st(0)

; (b-a)/2 ,(b+a)/2, 2, s=s+K*f(x)

add edi,8

 

loop @B

 

fmul st(0),st(3)

; I=s*(b-a)/2, (b+a)/2, 2, s

fstp integral

; (b+a)/2, 2, s

invoke CharToOem,ADDR szResult, esi

invoke StdOut,esi

invoke FloatToStr,integral,esi invoke StdOut,esi

invoke CharToOem,\

$CTA0("\n\nНатиснiть Enter для завершення..."), esi invoke StdOut,esi

invoke StdIn,esi, 4

ret

Main endp function proc near

; Вхід - число в st(0), Вихід - 3*квадрат числа в st(0) fld st(0)

fmul fld1 fld1 fld1 fadd fadd fmul

ret

function endp end start

Приклад 8.3 Розвязок задачі Коші dy = 2( x2 + y), y(0) = 1 методом Рунге dx

 

Кутта

4-го порядку. Значення невідомої функції y

в точці xn+1 відносно

значення

в

 

попередній

 

 

точці xn

для

 

задачі Коші

y′ = f ( x, y), y( x0 ) = y0

обчислюється методом Рунге

 

Кутта 4-го порядку за формулою

y

n+1

= y

 

 

+

h

(k + 2k

 

+ 2k

 

 

+ k

 

 

) , x

n+1

= x

 

+ h , де

 

n

 

 

2

3

4

n

 

 

 

 

6

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

k = f ( x

 

, y

 

 

), k

 

= f ( x

 

+

h

, y

 

 

+

h

k ),

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

n

 

n

 

 

2

 

 

 

 

n

 

2

 

 

n

2

 

 

1

 

 

 

 

k3 = f ( xn

+

h

, yn

+

h

k2 ), k4 = f ( xn + h, yn + hk3 )

 

 

 

 

 

 

 

 

 

 

 

2

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

; Файл RungeKutt4.inc

include windows.inc include user32.inc include kernel32.inc include masm32.inc

include C:\MASM32\MACROS\strings.mac

includelib

user32.lib

includelib

kernel32.lib

includelib

masm32.lib

Main PROTO

k=10

 

.data

 

xn

dq 0.0

yn

dq 1.0

xk

dq 1.0

n

dd k

.data?

 

h

dq ?

h2

dq ?

h6

dq ?

k1

dq ?

k2

dq ?

k3

dq ?

k4

dq ?

x

dq k dup(?)

y

dq k dup(?)

; Файл RungeKutt4.asm

.686

.model flat, stdcall

option casemap:none

include RungeKutt4.inc

.code

start: invoke Main

invoke ExitProcess,0

Main proc

LOCAL Buffer[128]:BYTE

invoke AllocConsole lea esi,Buffer

invoke CharToOem, $CTA0("Метод Рунге-Кутта 4-го порядку"), esi invoke SetConsoleTitle,esi

invoke ClearScreen

mov ebx,n

 

xor edi,edi

 

finit

 

fld yn

; yn

fld xn

; xn, yn

fld xk

; xk, xn, yn

fsub st(0),st(1)

; xk-xn, xn, yn

fild n

; n, xn-xk, xn, yn

fdivp st(1),st(0)

; h=(xn-xk)/n, xn, yn

fld st(0)

; h, h, xn, yn

fld st(0)

; h, h, h, xn, yn

fld1

; 1, h, h, h, xn, yn

fld1

; 1, 1, h, h, h, xn, yn

fadd

; 2, h, h, h, xn, yn

fld st(0)

; 2, 2, h, h, h, xn, yn

fadd st(1),st(0)

; 2, 4, h, h, h, xn, yn

fadd st(1),st(0)

; 2, 6, h, h, h, xn, yn

fdivp st(2),st(0)

; 6, h/2, h, h, xn, yn

fdivp st(2),st(0)

; h/2, h/6, h, xn, yn

fstp h2

; h/6, h, xn, yn

fstp h6

; h, xn, yn

fstp h

; xn, yn

@@: fld st(0)

; xn, xn, yn

fxch st(2)

; yn, xn, xn

fld st(0)

; yn, yn, xn, xn

Соседние файлы в папке гос