🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.asm
Article #1937

Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja

#1937
From: MrokU
Date: Tue, 02 Jun 2009 23:13
518 lines
14947 bytes
No nic, programik działa, interpoluje (zapewne nieoptymalnie, ale
cóż...). Kod w ASMie wrzucę, tak dla potomności, oraz może ktoś
skomentuje i poprawi moje wypociny :)

.586
.387

.MODEL FLAT, STDCALL

OPTION CASEMAP:NONE

INCLUDE c:\masm32\include\windows.inc;

.DATA
.CODE

DllEntry PROC ;hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD
	mov eax, TRUE
	ret
DllEntry ENDP

;******************************************************************
;****** Procedura obliczajaca wspolczynnik beta dla j-ego elementu
;****** Wg wzoru:
;****** double beta (int j) //obliczanie wspólczynnika beta - wzór 26
;****** {
;******		return ((j* 2 * pi) / (n + 1));
;****** }

Beta PROC n:DWORD, j:DWORD, wynik:PTR
	pushad
	mov ebx, wynik		; adres wyniku

	finit
	fldpi				; PI -> st0
	fadd st(0), st(0)	; 2*PI -> st0
	fild j				; 2*PI -> st1, j -> st0
	fmulp st(1), st(0)	; 2*PI*j -> st0
	fld1				; 1 -> st0
	fild n				; n -> st0
	faddp st(1), st(0)	; n+1 -> st0
	fdivp st(1), st(0)	; 2*PI*j / n+1 -> st0

	fstp QWORD PTR [ebx]; zapisanie wyniku pod adres przekazanego
wskaznika

	popad
	ret					;koniec funkcji
Beta ENDP

;******************************************************************
;****** Procedura obliczajaca pierwsze 2 wyrazy ciagu Un
;****** Wg wzoru:
;****** double U (int k, double beta, Element *tab)  //obliczanie
wspólczynnika U - wzór 28
;****** {
;******		if ( k > n )
;******			return (0.0);
;******		else
;******			return (tab[k].f_x + (2.0) * ( U(k+1, beta, tab) * cosf
(beta) ) - U(k+2, beta, tab));
;****** }

;****** definicja elementu tablicy

;****** struct Element
;****** {
;****** 	double x;
;******		double f_x;
;****** 	double g_x;
;****** 	double blad;
;****** };

wspU PROC n:DWORD, k:DWORD, beta:PTR, tab:PTR, wynik:PTR
LOCAL t1:QWORD, t2:QWORD, t3:QWORD, t4:QWORD, temp:DWORD, tabptr:PTR,
twynik:QWORD
	pushad
	finit

	mov eax, k
	cmp eax, n				; if (k > n)

	ja Zwroc0				; return 0;

	mov ebx, tab			; zaladowanie adresu tablicy
	fld QWORD PTR [ebx+8]	; zaladowanie wartosci f(x)
	fstp t1					; zachowanie wartosci do zmiennej lokalnej, zwolnienie
stosu

	mov ebx, beta			; zaladowanie adresu zmiennej beta (liczonej przez
funkcje "Beta(j, n)"
	fld QWORD PTR [ebx]		; zaladowanie wartosci spod wskaznika beta
	fcos					; cosinus (beta)
	fadd st(0), st(0)		; 2 * cos (beta)
	fstp t2					; zachowanie powyzszej wartosci do lokalnej zmiennej

	mov eax, k				; zachowanie zmiennej k
	mov temp, eax
	inc temp				; temp = k+1
	mov esi, tab			; zachowanie adresu tablicy
	mov tabptr, esi
	add tabptr, 32			; przesuniecie sie do nastepnego elementu tablicy

	lea edi, twynik			; wyluskanie adresu zmiennej twynik

	INVOKE wspU, n, temp, beta, tabptr, edi				; wywolanie funkcji wspU
(n, k+1, beta, tab[k+1])

	lea edi, twynik			; zaladowanie adresu wyniku
	fld QWORD PTR [edi]		; odczytanie wyniku zwroconego przez wspU
	fstp t3					; zapisanie wyniku

	mov eax, k				; zachowanie zmiennej k
	mov temp, eax
	inc temp				; temp = k+1
	inc temp				; temp = k+2
	mov esi, tab			; zachowanie adresu tablicy
	mov tabptr, esi
	add tabptr, 64			; przesuniecie sie w tablicy o 2 elementy

	lea edi, twynik			; wyluskanie adresu zmiennej twynik

	INVOKE wspU, n, temp, beta, tabptr, edi				; wywolanie funkcji wspU
(n, k+2, beta, tab[k+2])

	lea edi, twynik			; zaladowanie adresu wyniku
	fld QWORD PTR [edi]		; odczytanie wyniku zwroconego przez wspU
	fstp t4					; zapisanie wyniku

	fld t3					; st1 = U(k+1)
	fld t2					; st0 = 2 * cos(beta)

	fmulp st(1), st(0)		; st0 = 2 * cos(beta) * U(k+1)
	fld t4					; st0 = U(k+2)
	fsubp st(1), st(0)		; st0 = 2 * cos(beta) * U(k+1) - U(k+1)

	mov ebx, tab
	fld QWORD PTR [ebx+8]	; st0 = f(x)
	faddp st(1), st(0)		; st0 = f(x) + 2 * cos(beta) * U(k+1)

	mov esi, wynik			; wczytanie adresu zmiennej wynikowej
	fstp QWORD PTR [esi]	; zapisanie wyniku

	jmp Koniec

Zwroc0:
	fldz					; ladujemy 0 do st0

	mov esi, wynik			; wczytanie adresu zmiennej wynikowej
	fstp QWORD PTR [esi]	; zapisanie zera pod adres wynikowy

Koniec:
	popad
	ret ;koniec funkcji

wspU ENDP


;******************************************************************
;****** Procedura obliczajaca pierwsze 2 wyrazy ciagu Un
;****** Wg wzoru:
;****** double U (int k, double beta, Element *tab)  //obliczanie
wspólczynnika U - wzór 28
;****** {
;******		if ( k > n )
;******			return (0.0);
;******		else
;******			return (tab[k].f_x + (2.0) * ( U(k+1, beta, tab) * cosf
(beta) ) - U(k+2, beta, tab));
;****** }

;****** definicja elementu tablicy

;****** struct Element
;****** {
;****** 	double x;
;******		double f_x;
;****** 	double g_x;
;****** 	double blad;
;****** };

wspU_2 PROC n:DWORD, k:DWORD, beta:QWORD, tab:PTR, wynik:PTR
LOCAL Uk1:QWORD, Uk2:QWORD, tabT:PTR
	pushad
	finit

	mov eax, k
	cmp eax, n				; if (k > n)

	ja Zwroc0				; return 0

	mov ebx, k
	inc ebx					; ebx = k+1
	mov ecx, tab
	add ecx, 32
	mov tabT, ecx			; tabT = tab + 32 (przejscie do kolejnego elementu
tablicy)

	INVOKE wspU_2, n, ebx, beta, tabT, wynik

	mov ebx, wynik
	fld QWORD PTR [ebx]
	fstp Uk1				; zapisanie wyniku do zmiennej lokalnej

	mov ebx, k
	add ebx, 2				; ebx = k+2
	mov ecx, tab
	add ecx, 64
	mov tabT, ecx			; tabT = tab + 64 (przejscie o 2 elementy tablicy)

	INVOKE wspU_2, n, ebx, beta, tabT, wynik

	mov ebx, wynik
	fld QWORD PTR [ebx]
	fstp Uk2				; zapisanie wyniku do zmiennej lokalnej

	fld beta
	fcos					; cosinus (beta)
	fadd st(0), st(0)		; 2 * cos (beta)

	fld Uk1					; zaladowanie wartosci U(k+1)
	fmulp st(1), st(0)		; 2 * cos (beta) * U(k+1) -> st0

	fld Uk2
	fsubp st(1), st(0)		; 2 * cos (beta) * U(k+1) - U(k+2) -> st0

	mov esi, tab
	fld QWORD PTR [esi+8]
	faddp st(1), st(0)		; f(xk) + 2 * cos (beta) * U(k+1) - U(k+2) -> st0

	mov esi, wynik
	fstp QWORD PTR [esi]	; zapisanie wyniku

	jmp Koniec

Zwroc0:
	mov esi, wynik
	fldz
	fstp QWORD PTR [esi]	; zwrocenie zera

Koniec:
	popad
	ret;

wspU_2 ENDP


;******************************************************************
;****** Procedura liczaca wspolczynnik A
;****** double wspA (int j, Element *tab) //obliczanie wspolczynnika A
- wzór 27
;****** {
;****** 	double beta_j = beta (j);
;****** 	return ( (2.0/(n+1)) * (tab[0].f_x + U(1, beta_j, tab) * cosf
(beta_j) - U(2, beta_j, tab)) );
;****** }
wspA PROC n:DWORD, j:DWORD, tab:PTR, wynik:PTR
LOCAL Tbeta:QWORD, U2:QWORD, temp:DWORD
	pushad
	finit

	lea ebx, Tbeta			; wyluskanie adresu zmiennej Tbeta (bedzie w niej
przechowywany wynik funkcji Beta())
	INVOKE Beta, n, j, ebx

	mov esi, tab
	add esi, 64

	INVOKE wspU_2, n, 2, Tbeta, esi, wynik

	mov esi, wynik
	fld QWORD PTR [esi]		; zapamietanie wyniku
	fstp U2

	mov esi, tab
	add esi, 32

	INVOKE wspU_2, n, 1, Tbeta, esi, wynik

	mov esi, wynik
	fld QWORD PTR [esi]		; U(1) -> st0

	fld Tbeta
	fcos					; cos(beta) -> st0

	fmulp st(1), st(0)		; cos(beta) * U1 -> st0
	fld U2					; U(2) -> st0
	fsubp st(1), st(0)		; cos(beta) * U1 - U2 -> st0

	mov esi, tab
	fld QWORD PTR [esi+8]	; f(x0) -> st0
	faddp st(1), st(0)		; f(x0) + cos(beta) * U1 - U2 -> st(0)
	fadd st(0), st(0)		; 2 * st0

	mov ebx, n
	inc ebx					; n+1 -> ebx
	mov temp, ebx

	fild temp				; n+1 -> st0

	fdivp st(1), st(0)		; [2 * (x0) + cos(beta) * U1 - U2 -> st(0)] / (n
+1) -> st0

	mov esi, wynik
	fstp QWORD PTR [esi]	; zwrocenie wyniku

	popad

	ret
wspA ENDP

;******************************************************************
;****** Procedura liczaca wspolczynnik B
;****** double B (int j, Element* tab) //obliczanie współczynnika B -
wzór 27
;****** {
;****** 	double beta_j = beta (j);
;****** 	return (2 * ( U(n, 1, beta_j, tab) * sinf(beta_j) ) ) / (n +
1) ;
;****** }
wspB PROC n:DWORD, j:DWORD, tab:PTR, wynik:PTR
LOCAL Tbeta:QWORD, temp:DWORD
	pushad
	finit

	lea esi, Tbeta			; wyluskanie adresu zmiennej Tbeta (bedzie w niej
przechowywany wynik funkcji Beta())
	INVOKE Beta, n, j, esi

	mov esi, tab
	add esi, 32

	INVOKE wspU_2, n, 1, Tbeta, esi, wynik

	mov esi, wynik
	fld QWORD PTR [esi]		; U(1) -> st0

	fld Tbeta
	fsin					; sin(beta) -> st0

	fmulp st(1), st(0)		; U(1) * sin(beta) -> st0
	fadd st(0), st(0)		; 2 * U(1) * sin(beta) -> st0

	mov ebx, n
	inc ebx					; n+1 -> ebx
	mov temp, ebx

	fild temp				; n+1 -> st0

	fdivp st(1), st(0)		; [2 * sin(beta) * U1] / (n+1) -> st0

	mov esi, wynik
	fstp QWORD PTR [esi]	; zwrocenie wyniku

	popad
	ret
wspB ENDP

;******************************************************************
;****** Procedura obliczajaca wartosc funkcji interpolujacej w danym
punkcie.
;****** wg wzoru:
;****** t(x) =	A(0)/2 +													// lokalnie jako wA02
;******			[ delta * A(m+1) * cos ((m+1)*x) ] / 2 +					// lokalnie
jako wA
;******			SUMA (od j=1 do m) [ A(j) * cos (j*x) + B(j) * sin (j*x) ]
;****** gdzie:
;******			dla n parzystych:		delta = 0, m =	n	/ 2
;******			dla n nieparzystych:	delta = 1, m =(n-1)	/ 2
;******
;****** funkcja bedzie wywolywana osobno dla kazdego punktu
;****** interpolacji, stad 2 wskazniki na tablice tab[]
;****** jeden wskaznik na poczatek tablicy oraz jeden wskaznik
;****** na aktualnie liczony element

Interpoluj PROC n:DWORD, tab:PTR, AKT_tab:PTR
LOCAL m:DWORD, j:DWORD, wA:QWORD, wA02:QWORD, wAsuma:QWORD,
wBsuma:QWORD, SUMA:QWORD
	pushad
	finit

	mov eax, n				; zaladowanie n
	shl eax, 31				; wyluskanie najmlodszego bitu (1 - nieparzysta)

	cmp eax, 0				; sprawdzenie parzystosci liczby
	je Parzysta

Nieparzysta:				; tutaj bedziemy liczyc: [ A(m+1) * cos ((m+1)*x) ] /
2
	mov ebx, n
	dec ebx					; n - 1
	shr ebx, 1				; (n - 1) / 2
	mov m, ebx				; m = (n - 1) / 2

	lea esi, wA
	mov ebx, m
	inc ebx
	mov j, ebx				; j = m+1

	INVOKE wspA, n, j, tab, esi		; obliczamy A(m+1), wynik -> wA

	fld wA					; A(m+1) -> st0
	fild j					; m+1 -> st0
	fld QWORD PTR AKT_tab	; zaladowanie wartosci x dla aktualnie
liczonego wezla
	fmulp st(1), st(0)		; [ A(m+1) * x ] -> st0
	fcos					; cos ((m+1)*x) -> st0
	fmulp st(1), st(0)		; [ A(m+1) * cos ((m+1)*x) ] -> st0
	mov j, 2
	fild j					; zaladowanie 2 do st0
	fdivp st(1), st(0)		; [ A(m+1) * cos ((m+1)*x) ] / 2 -> st0
	fstp wA					; zapisanie powyzszego wyniku do wA

	jmp M_obliczone

Parzysta:					; ustawienie odpowiedniego m oraz wA = 0
	mov ebx, n
	shr ebx, 1				; n / 2
	mov m, ebx				; m = n / 2
	fldz
	fstp wA

M_obliczone:				; obliczenie A(0) / 2 i petla liczaca sume

	lea esi, wA02			; zaladowanie adresu zmiennej do esi

	INVOKE wspA, n, 0, tab, esi		; obliczamy A(0), wynik -> wA02

	fld wA02				; A(0) -> st0
	mov j, 2
	fild j					; zaladowanie 2 do st0
	fdivp st(1), st(0)		; A(0) / 2 -> st0
	fstp wA02				; zaladowanie st0 do zmiennej wA02

;* petla obliczajaca sume
;** SUMA (od j=1 do m) [ A(j) * cos (j*x) + B(j) * sin (j*x) ]

	mov ecx, 1								; for (j = 1...)
	fldz
	fstp SUMA								; SUMA = 0
Petla:
		mov j, ecx
		cmp ecx, m
		ja Endfor							; for (j = 1; j < m...)

		lea esi, wAsuma
		INVOKE wspA, n, j, tab, esi		; wAsuma = A(j)

		lea esi, wBsuma
		INVOKE wspB, n, j, tab, esi		; wBsuma = B(j)

		mov esi, AKT_tab
		fld QWORD PTR [esi]					; tab[j].x -> st0
		fild j								; j -> st0
		fmulp st(1), st(0)					; j * x -> st0
		fcos								; cos (j * x) -> st0
		fld wAsuma
		fmulp st(1), st(0)					; A(j) * cos (j * x) -> st0

		mov esi, AKT_tab
		fld QWORD PTR [esi]					; tab[j].x -> st0
		fild j								; j -> st0
		fmulp st(1), st(0)					; j * x -> st0
		fsin								; sin (j * x) -> st0
		fld wBsuma
		fmulp st(1), st(0)					; B(j) * cos (j * x) -> st0

		faddp st(1), st(0)					; [ A(j) * cos (j*x) + B(j) * sin (j*x) ] ->
st0

		fld SUMA
		faddp st(1), st(0)
		fstp SUMA							; SUMA += [ A(j) * cos (j*x) + B(j) * sin (j*x) ]

		inc ecx								; for (j = 1, j < m, j++)
		jmp Petla
Endfor:

	fld SUMA
	fld wA02
	fld wA
	faddp st(1), st(0)
	faddp st(1), st(0)						; SUMA += A(0)/2 + [ delta * A(m+1) * cos ((m
+1)*x) ] / 2

	mov esi, AKT_tab						; zaladowanie wskaznika na aktualny element
tablicy
	add esi, 16								; przesuniecie sie na element g_x struktury
	fstp QWORD PTR [esi]					; zapisanie wartosci funkcji interpolacyjnej
dla danego elementu

Liczenie_bledu:
	mov esi, AKT_tab
	fld QWORD PTR [esi+8]					; f(x) -> st0 __zaladowanie wartosci
oryginalnej funkcji
	fld QWORD PTR [esi+16]					; g(x) -> st0 __zaladowanie wartosci
funkcji interpolacyjnej

	fsubp st(1), st(0)						; f(x) - g(x) -> st(0)

	fldz
	fcomip st(0), st(1)						; porownanie st0 i st1
	jbe bladdodatni

bladujemny:
	fldz
	fld1
	fsubp st(1), st(0)						; -1 -> st0
	fmulp st(1), st(0)						; zmiana znaku bledu

bladdodatni:
	fstp QWORD PTR [esi+24]					; zapisanie wartosci bledu
Koniec:
	popad
	ret
Interpoluj ENDP

END DllEntry
Technical Details
Message-ID: <16742a2d-f987-46f6-91ef-572f952e5fd7@n19g2000vba.googlegroups.com>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!wsisiz.edu.pl!plix.pl!newsfeed1.plix.pl!news-out1.kabelfoon.nl!newsfeed.kabelfoon.nl!bandi.nntp.kabelfoon.nl!eweka.nl!lightspeed.eweka.nl!postnews.google.com!n19g2000vba.googlegroups.com!not-for-mail
References: <29a4a4e4-9913-4afa-ba78-63b3168b1c91@r34g2000vbi.googlegroups.com> <1800926.ER7XFjMh0G@meehow.homeip.net> <6a3c09a9-6a40-491a-8d0b-aebe884ddeb9@k38g2000yqh.googlegroups.com> <gvh3mf$a3r$1@inews.gazeta.pl> <0350c547-38dd-4ffd-9348-994f087be99e@21g2000vbk.googlegroups.com> <gvhacl$b4v$1@inews.gazeta.pl> <4cd17bbe-78cb-4b0c-8dcf-d71287d4f307@x3g2000yqa.googlegroups.com> <f5c0cab0-caff-4858-bfad-4106556e0597@r13g2000vbr.googlegroups.com> <gvrei4$l9v$1@inews.gazeta.pl> <168f208a-9218-484f-82cd-2c3dc452d48f@v4g2000vba.googlegroups.com> <gvriog$c4n$1@inews.gazeta.pl> <fff60de0-8de1-4f54-bae0-960e47e1bfd3@o14g2000vbo.googlegroups.com> <b5d08268-4d2e-4e43-a816-196a0781602a@z9g2000yqi.googlegroups.com>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!newsfeed.gazeta.pl!wsisiz.edu.pl!plix.pl!newsfeed1.plix.pl!news-out1.kabelfoon.nl!newsfeed.kabelfoon.nl!bandi.nntp.kabelfoon.nl!eweka.nl!lightspeed.eweka.nl!postnews.google.com!n19g2000vba.googlegroups.com!not-for-mail
From: MrokU <arkosmc@gmail.com>
Newsgroups: pl.comp.lang.asm
Subject: Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
Date: Tue, 2 Jun 2009 16:13:59 -0700 (PDT)
Organization: http://groups.google.com
Lines: 518
Message-ID: <16742a2d-f987-46f6-91ef-572f952e5fd7@n19g2000vba.googlegroups.com>
References: <29a4a4e4-9913-4afa-ba78-63b3168b1c91@r34g2000vbi.googlegroups.com>  <1800926.ER7XFjMh0G@meehow.homeip.net> <6a3c09a9-6a40-491a-8d0b-aebe884ddeb9@k38g2000yqh.googlegroups.com>  <gvh3mf$a3r$1@inews.gazeta.pl> <0350c547-38dd-4ffd-9348-994f087be99e@21g2000vbk.googlegroups.com>  <gvhacl$b4v$1@inews.gazeta.pl> <4cd17bbe-78cb-4b0c-8dcf-d71287d4f307@x3g2000yqa.googlegroups.com>  <f5c0cab0-caff-4858-bfad-4106556e0597@r13g2000vbr.googlegroups.com>  <gvrei4$l9v$1@inews.gazeta.pl> <168f208a-9218-484f-82cd-2c3dc452d48f@v4g2000vba.googlegroups.com>  <gvriog$c4n$1@inews.gazeta.pl> <fff60de0-8de1-4f54-bae0-960e47e1bfd3@o14g2000vbo.googlegroups.com>  <b5d08268-4d2e-4e43-a816-196a0781602a@z9g2000yqi.googlegroups.com>
NNTP-Posting-Host: 83.4.160.167
Mime-Version: 1.0
X-Trace: posting.google.com 1243984439 30157 127.0.0.1 (2 Jun 2009 23:13:59 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Tue, 2 Jun 2009 23:13:59 +0000 (UTC)
Complaints-To: groups-abuse@google.com
Injection-Info: n19g2000vba.googlegroups.com; posting-host=83.4.160.167;  posting-account=M89B8goAAADtNGu6YLcVvvVDLG2z3LY8
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.0.10)  Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729),gzip(gfe),gzip(gfe)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit