🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.asm
27 messages
27 total messages Started by MrokU Sat, 23 May 2009 18:14
Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1912
Author: MrokU
Date: Sat, 23 May 2009 18:14
17 lines
1805 bytes
Witam,
zupełnie nie znam asemblera, a muszę napisać bibliotekę dll, służącą
do interpolacji algorytmem Goertzel`a.

Wymyśliłem sobie, żeby do biblioteki przekazywać listę / tablicę
węzłów interpolacji (czyli punktów, w których funkcja wyjściowa i
wejściowa muszą się zgadzać) i dla nich wyliczać wartość funkcji
interpolującej.

Czy ktoś może mi podpowiedzieć od czego w ogóle zacząć, podrzucić
jakieś tutoriale do tworzenia bibliotek dll, wymiany danych między C/C+
+ i biblioteką dll w asmie?

Ewentualnie, czy ktoś, kto się na tym zna byłby skory coś takiego
napisać?

pozdrawiam
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1913
Author: Bogdan (bogdro)
Date: Sun, 24 May 2009 09:17
21 lines
1796 bytes
MrokU pisze:
> Witam,
> zupełnie nie znam asemblera, a muszę napisać bibliotekę dll, służącą
> do interpolacji algorytmem Goertzel`a.
> 
> Wymyśliłem sobie, żeby do biblioteki przekazywać listę / tablicę
> węzłów interpolacji (czyli punktów, w których funkcja wyjściowa i
> wejściowa muszą się zgadzać) i dla nich wyliczać wartość funkcji
> interpolującej.
> 
> Czy ktoś może mi podpowiedzieć od czego w ogóle zacząć, podrzucić
> jakieś tutoriale do tworzenia bibliotek dll, wymiany danych między C/C+
> + i biblioteką dll w asmie?

 Odpowiedziano na forum.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1914
Author: MrokU
Date: Sun, 24 May 2009 10:07
6 lines
1516 bytes
Wiem, widziałem już.

Pozostaje jeszcze pytanie, czy ktoś osobiście (lub znajomi) robi tego
typu projekty, że tak powiem odpłatnie?

pozdrawiam
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1915
Author: Bogdan
Date: Mon, 25 May 2009 01:42
12 lines
1242 bytes
Użytkownik "Bogdan (bogdro)" napisał:

> Odpowiedziano na forum.

Na jakim forum? Można prosić o oświecenie mnie?

Do MrokU:

Parę DLL-ek pod Windows w asemblerze napisałem. Mogę co nieco podpowiedzieć.
Mój e-mail z nagłówka jest fałszywy. To tak na wszelki.

Remek
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1916
Author: MrokU
Date: Mon, 25 May 2009 15:23
121 lines
4235 bytes
To może tak:
wkleję tutaj kod, który mi działa, ale zapewne wiele rzeczy jest
nieoptymalnie, niefajnie, etc.
Czy ktoś może rzucić na to okiem i powiedzieć co i jak robić lepiej?
pozdrawiam.


-----------------------------------------------------------------------------------------------------------------
KOD DLL:
.586
.387

.MODEL FLAT, STDCALL

OPTION CASEMAP:NONE

INCLUDE    .\masm32\include\windows.inc;
INCLUDE    .\masm32\include\user32.inc
INCLUDE    .\masm32\include\kernel32.inc
INCLUDELIB .\masm32\lib\user32.lib
INCLUDELIB .\masm32\lib\kernel32.lib

.DATA
.CODE

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

;***************************************************************
;******	Procedura testowa ***** dodawanie

sumuj PROC a: DWORD , b: DWORD
	pushad
	mov eax, a
	add b, eax
	popad
	mov eax, b
	ret            ;koniec funkcji
sumuj ENDP

;***************************************************************
;******	Procedura testowa ***** odejmowanie

odejmuj PROC a: DWORD , b: DWORD
	pushad
	mov eax, a
	sub b, eax
	popad
	mov eax, b
	ret            ;koniec funkcji
odejmuj ENDP

;***************************************************************
;******	Procedura testowa ***** HARDCORE - sinus()

sinus PROC kat:DQ;, wynik:PTR
	pushad
	finit
	fld	kat			; wczytanie zmiennej do rejestru st0
	fsin
	fst kat
	popad
	mov eax, kat
	ret            ;koniec funkcji
sinus ENDP

END DllEntry


-----------------------------------------------------------------------------------------------------------------
KOD C++:

#include <windows.h>
#include <stdio.h>
#include <iostream>

#define PI
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
//---------------------------------------------------------------------------

typedef int (__stdcall *MYPROC)(int, int);
typedef float (__stdcall *MYPROC2)(float);

MYPROC ProcAdd, ProcSub;
MYPROC2 ProcSin;
HINSTANCE hinstLib;
int a, b;
float d;

int main(int argc, char* argv[])
{
	hinstLib = LoadLibrary ("DLLint.dll");							//ladowanie biblioteki
	if (hinstLib == NULL)												//sprawdzenie, czy moduł faktycznie
został załadowany
		return 1;

	ProcAdd = (MYPROC) GetProcAddress(hinstLib, "sumuj");
	if (NULL != ProcAdd)
		a = (ProcAdd)(9,2);

	ProcSub = (MYPROC) GetProcAddress(hinstLib, "odejmuj");
	if (NULL != ProcAdd)
		b = (ProcSub)(2,9);

	ProcSin = (MYPROC2) GetProcAddress(hinstLib, "sinus");
	if (NULL != ProcAdd)
		d = (ProcSin)(PI / 6);	// sinus 30 stopni

	FreeLibrary(hinstLib);
	std::cout << a << std::endl;
	std::cout << b << std::endl;
	std::cout << d << std::endl;

	system("PAUSE");
	return 0;
}

-----------------------------------------------------------------------------------------------------------------
pozdrawiam.
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1917
Author: MrokU
Date: Mon, 25 May 2009 15:30
2 lines
1524 bytes
No a to forum, to
http://profesor.niesfornazyta.pl/viewtopic.php?f=84&t=151&sid=19e22332db7f7e7749ca37199d4d60f2
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1921
Author: Bogdan (bogdro)
Date: Mon, 25 May 2009 15:35
19 lines
1476 bytes
Bogdan pisze:
> Użytkownik "Bogdan (bogdro)" napisał:
> 
>> Odpowiedziano na forum.
> 
> Na jakim forum? Można prosić o oświecenie mnie?

 Oczywiście: http://profesor.niesfornazyta.pl/
 [...]

> Remek

 Podpisujesz się na raz "Remek" i "Bogdan"?

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1918
Author: Bogdan (bogdro)
Date: Mon, 25 May 2009 16:05
110 lines
4415 bytes
MrokU pisze:
> To może tak:
> wkleję tutaj kod, który mi działa, ale zapewne wiele rzeczy jest
> nieoptymalnie, niefajnie, etc.
> Czy ktoś może rzucić na to okiem i powiedzieć co i jak robić lepiej?
> pozdrawiam.

[...]

> ;******	Procedura testowa ***** dodawanie
> 
> sumuj PROC a: DWORD , b: DWORD
> 	pushad
> 	mov eax, a
> 	add b, eax
> 	popad
> 	mov eax, b
> 	ret            ;koniec funkcji
> sumuj ENDP

 Możesz nie pisać PUSHAD i POPAD, bo używasz tylko rejestru EAX, który
nie tylko można dowolnie zmieniać, ale przy wyjściu zawiera wynik.
Podobnie w kilku innych procedurach.

> ;******	Procedura testowa ***** HARDCORE - sinus()
> 
> sinus PROC kat:DQ;, wynik:PTR
> 	pushad
> 	finit
> 	fld	kat			; wczytanie zmiennej do rejestru st0
> 	fsin
> 	fst kat
> 	popad
> 	mov eax, kat
> 	ret            ;koniec funkcji
> sinus ENDP

 Oj, tu niedobrze. Pomijając PUSHAD/POPAD, wykonywanie FINIT może być
dość kosztowne czasowo i raczej powinno się to robić tylko raz, przy
starcie programu (chyba że naprawdę potrzebny jest reset). Większy
problem jest w tym, że wkładasz coś na stos i nie zdejmujesz - po 8
uruchomieniach się przepełni (pewnie dlatego robiłeś FINIT). Zamiast
FST użyj FSTP. Nawet jeśli nigdzie indziej nie używasz koprocesora,
rób tak dla zasady.
 Swoją drogą, chyba "wynik" jest od tego, by otrzymać wynik, a nie "kat"?


> #include <windows.h>
> #include <stdio.h>
> #include <iostream>
> #define PI
> 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

 Czemu nie użyjesz stałych "firmowych" (jeśli są dostępne, oczywiście)?

#include <math.h>
#ifndef M_PI
#define M_PI 3.141592653589793238462643383279502884197 blablabla...
#endif


> //---------------------------------------------------------------------------
> 
> typedef int (__stdcall *MYPROC)(int, int);
> typedef float (__stdcall *MYPROC2)(float);
> 
> MYPROC ProcAdd, ProcSub;
> MYPROC2 ProcSin;
> HINSTANCE hinstLib;
> int a, b;
> float d;
> 
> int main(int argc, char* argv[])
> {
> 	hinstLib = LoadLibrary ("DLLint.dll");	//ladowanie biblioteki
> 	if (hinstLib == NULL)			//sprawdzenie, czy moduł faktycznie
> został załadowany
> 		return 1;
> 
> 	ProcAdd = (MYPROC) GetProcAddress(hinstLib, "sumuj");
> 	if (NULL != ProcAdd)
> 		a = (ProcAdd)(9,2);

 Formalnie to pewnie powinno być

		a = (*ProcAdd)(9,2);

 jako że "ProcAdd" jest wskaźnikiem. Ale jak działa, to dobrze.

[...]

> 		d = (ProcSin)(PI / 6);	// sinus 30 stopni

 W tym błędu nie ma, ale jak będziesz potrzebował szybkiego działania,
używaj stałych, bez obliczeń, np.

#define M_PI_6 0.5235987755982988527 /* M_PI / 6 */
		d = (*ProcSin)(M_PI_6);

 aby od razu przekazywać parametr do funkcji, bez zbędnych obliczeń na
stałych (a na przykład dzielenie jest akurat kosztowne).
 Pewnie mądry kompilator i tak by tu wstawił stałą, ale co jeśli nie?

 Tyle ja zauważyłem na pierwszy rzut oka. Może ktoś jeszcze coś dołoży.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1919
Author: MrokU
Date: Mon, 25 May 2009 20:34
45 lines
3693 bytes
>  Możesz nie pisać PUSHAD i POPAD, bo używasz tylko rejestru EAX, który
> nie tylko można dowolnie zmieniać, ale przy wyjściu zawiera wynik.

No właśnie muszę używać, bo Visual mi się pluje, że coś robię nie tak
z rejestrem ESI. Nie wiem o co chodzi, ale jak te instrukcje dodam, to
żadnych błędów mi nie wyrzuca...

>  Oj, tu niedobrze. Pomijając PUSHAD/POPAD, wykonywanie FINIT może być
> dość kosztowne czasowo i raczej powinno się to robić tylko raz, przy
> starcie programu (chyba że naprawdę potrzebny jest reset). Większy
> problem jest w tym, że wkładasz coś na stos i nie zdejmujesz - po 8
> uruchomieniach się przepełni (pewnie dlatego robiłeś FINIT). Zamiast
> FST użyj FSTP. Nawet jeśli nigdzie indziej nie używasz koprocesora,
> rób tak dla zasady.
>  Swoją drogą, chyba "wynik" jest od tego, by otrzymać wynik, a nie "kat"?

o FINIT nie wiedziałem. Jak na razie to jedyna funkcja, która używa
liczb zmiennoprzecinkowych, ale domyślnie będzie to działało tak, że
jedna duża funkcja będzie liczyła interpolację dla danego punktu, w
związku z tym FINIT będzie tylko raz (aczkolwiek to na razie plany).
Wynik jest do tego, żeby sobie spróbować zwrócić wynik w inny sposób
niż przez eax, ale jak na razie tego nie robiłem, bo nie do końca wiem
jak :P chociaż pewnie trzeba przekazać wskaźnik i modyfikować adres.
Tylko nie zastanawiałem się jeszcze jak to robić.

> > #include <windows.h>
> > #include <stdio.h>
> > #include <iostream>
> > #define PI
> > 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
>
>  Czemu nie użyjesz stałych "firmowych" (jeśli są dostępne, oczywiście)?
>
> #include <math.h>
> #ifndef M_PI
> #define M_PI 3.141592653589793238462643383279502884197 blablabla...
> #endif

nie widziałem sensu dołączania całej biblioteki, skoro potrzebuję
tylko PI (chociaż jak już mówiłem, to są dopiero próby i przymierzanie
się do pisania programu).

No a z liczeniem sinusa 30 stopni, to nie ma sensu robić to z #define,
bo nie będę liczył stałych wartości kątów. Wszystko leci na wzorach i
będzie wyliczane na bieżąco.
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1922
Author: Remek
Date: Mon, 25 May 2009 21:13
9 lines
1302 bytes
Użytkownik "Bogdan (bogdro)" napisał:

> Podpisujesz się na raz "Remek" i "Bogdan"?

Nie do końca. Podpis był mój, ale gościnnie skorzystałem z innego komputera
i konta, zapominając o skutkach. Przepraszam za zamieszanie. Nie powinno się
powtórzyć.

Pozdrawiam  Remek
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1923
Author: MrokU
Date: Tue, 26 May 2009 00:45
201 lines
8305 bytes
A czy wiecie może, co może być skutkiem nagłej zmiany w Windowsach i
wysypu błędów?

Bo w pewnym momencie coś się VS odwidziało i kod, który się normalnie
kompilował, nagle wyrzuca coś takiego (dla pewności kompilowany kod):


-----------------------------------------------------------------------------------------------------------------
C++
#include <windows.h>
#include <stdio.h>
#include <iostream>

#define PI 3.1415926535897932


typedef int (__stdcall *MYPROC)(int, int);
typedef float (__stdcall *MYPROC2)(float);

MYPROC ProcAdd, ProcSub;
MYPROC2 ProcSin;
HINSTANCE hinstLib;
int a, b;
float d;

int main(int argc, char* argv[])
{
        hinstLib = LoadLibrary ("DLLint.dll");//ladowanie biblioteki
        if (hinstLib == NULL)//sprawdzenie, czy moduł faktycznie
został załadowany
                return 1;

        ProcAdd = (MYPROC) GetProcAddress(hinstLib, "sumuj");
        if (NULL != ProcAdd)
                a = (ProcAdd)(9,2);

        ProcSub = (MYPROC) GetProcAddress(hinstLib, "odejmuj");
        if (NULL != ProcAdd)
                b = (ProcSub)(2,9);

        ProcSin = (MYPROC2) GetProcAddress(hinstLib, "sinus");
        if (NULL != ProcAdd)
                d = (ProcSin)(PI / 6);  // sinus 30 stopni

        FreeLibrary(hinstLib);
        std::cout << a << std::endl;
        std::cout << b << std::endl;
        std::cout << d << std::endl;

        system("PAUSE");
        return 0;
}
-----------------------------------------------------------------------------------------------------------------
ASM
.586
.387

.MODEL FLAT, STDCALL

OPTION CASEMAP:NONE

INCLUDE    .\masm32\include\windows.inc;
INCLUDE    .\masm32\include\user32.inc
INCLUDE    .\masm32\include\kernel32.inc
INCLUDELIB .\masm32\lib\user32.lib
INCLUDELIB .\masm32\lib\kernel32.lib

.DATA
.CODE

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

;***************************************************************
;****** Procedura testowa ***** dodawanie

sumuj PROC a: DWORD , b: DWORD
        pushad
        mov eax, a
        add b, eax
        popad
        mov eax, b
        ret            ;koniec funkcji
sumuj ENDP

;***************************************************************
;****** Procedura testowa ***** odejmowanie

odejmuj PROC a: DWORD , b: DWORD
        pushad
        mov eax, a
        sub b, eax
        popad
        mov eax, b
        ret            ;koniec funkcji
odejmuj ENDP

;***************************************************************
;****** Procedura testowa ***** HARDCORE - sinus()

sinus PROC kat:DQ
        pushad
        finit
        fld     kat                     ; wczytanie zmiennej do
rejestru st0
        fsin
        fst kat
        popad
        mov eax, kat
        ret            ;koniec funkcji
sinus ENDP

END DllEntry
-----------------------------------------------------------------------------------------------------------------
DEF
LIBRARY DLLint
EXPORTS sumuj
EXPORTS odejmuj
EXPORTS sinus
-----------------------------------------------------------------------------------------------------------------
KOMPILACJA:
1>------ Rebuild All started: Project: interJA, Configuration: Debug
Win32 ------
1>Deleting intermediate and output files for project 'interJA',
configuration 'Debug|Win32'
2>------ Rebuild All started: Project: DLLint, Configuration: Debug
Win32 ------
2>Deleting intermediate and output files for project 'DLLint',
configuration 'Debug|Win32'
2>Assembling...
1>Compiling...
1>main.cpp
2> Assembling: .\DLLint.asm
2>.\DLLint.asm(1) : error A2044: invalid character in file
2>.\DLLint.asm(2) : error A2008: syntax error : .
2>.\DLLint.asm(4) : error A2008: syntax error : .
2>.\DLLint.asm(6) : error A2008: syntax error : P
2>.\DLLint.asm(8) : error A2109: only white space or comment can
follow backslash
2>.\DLLint.asm(10) : error A2109: only white space or comment can
follow backslash
2>.\DLLint.asm(12) : error A2109: only white space or comment can
follow backslash
2>.\DLLint.asm(14) : error A2109: only white space or comment can
follow backslash
2>.\DLLint.asm(16) : error A2109: only white space or comment can
follow backslash
2>.\DLLint.asm(19) : error A2008: syntax error : .
2>.\DLLint.asm(20) : error A2008: syntax error : .
2>.\DLLint.asm(22) : error A2008: syntax error : l
2>.\DLLint.asm(23) : error A2008: syntax error : m
2>.\DLLint.asm(24) : error A2008: syntax error : r
2>.\DLLint.asm(25) : error A2008: syntax error : D
2>.\DLLint.asm(30) : error A2008: syntax error : u
2>.\DLLint.asm(31) : error A2008: syntax error : p
2>.\DLLint.asm(32) : error A2008: syntax error : m
2>.\DLLint.asm(33) : error A2008: syntax error : a
2>.\DLLint.asm(34) : error A2008: syntax error : p
2>.\DLLint.asm(35) : error A2008: syntax error : m
2>.\DLLint.asm(36) : error A2008: syntax error : r
2>.\DLLint.asm(37) : error A2008: syntax error : s
2>.\DLLint.asm(42) : error A2008: syntax error : d
2>.\DLLint.asm(43) : error A2008: syntax error : p
2>.\DLLint.asm(44) : error A2008: syntax error : m
2>.\DLLint.asm(45) : error A2008: syntax error : s
2>.\DLLint.asm(46) : error A2008: syntax error : p
2>.\DLLint.asm(47) : error A2008: syntax error : m
2>.\DLLint.asm(48) : error A2008: syntax error : r
2>.\DLLint.asm(49) : error A2008: syntax error : o
2>.\DLLint.asm(54) : error A2008: syntax error : i
2>.\DLLint.asm(55) : error A2008: syntax error : p
2>.\DLLint.asm(56) : error A2008: syntax error : f
2>.\DLLint.asm(57) : error A2008: syntax error : f
2>.\DLLint.asm(58) : error A2008: syntax error : f
2>.\DLLint.asm(59) : error A2008: syntax error : f
2>.\DLLint.asm(60) : error A2008: syntax error : p
2>.\DLLint.asm(61) : error A2008: syntax error : m
2>.\DLLint.asm(62) : error A2008: syntax error : r
2>.\DLLint.asm(63) : error A2008: syntax error : s
2>.\DLLint.asm(65) : error A2008: syntax error : E
2>.\DLLint.asm(65) : error A2088: END directive required at end of
file
2>Project : error PRJ0019: A tool returned an error code from
"Assembling..."
1>c:\documents and settings\ala\desktop\interja\interja\main.cpp(33) :
warning C4305: 'argument' : truncation from 'double' to 'float'
2>Build log was saved at "file://c:\Documents and Settings\Ala\Desktop
\interJA\DLLint\Debug\BuildLog.htm"
2>DLLint - 44 error(s), 0 warning(s)
1>Compiling manifest to resources...
1>Linking...
1>LINK : C:\Documents and Settings\Ala\Desktop\interJA\Debug
\interJA.exe not found or not built by the last incremental link;
performing full link
1>Embedding manifest...
1>Build log was saved at "file://c:\Documents and Settings\Ala\Desktop
\interJA\InterJA\Debug\BuildLog.htm"
1>interJA - 0 error(s), 1 warning(s)
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ==========
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1925
Author: Michal Schulz
Date: Tue, 26 May 2009 14:28
9 lines
1037 bytes
MrokU wrote:

> zupełnie nie znam asemblera, a muszę napisać bibliotekę dll,

Nie chce sie wtracac, ale co ma pisanie biblioteki dll wspolnego z 
assemblerem? ;)

-- 
Michal Schulz
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1926
Author: MrokU
Date: Tue, 26 May 2009 15:11
7 lines
1516 bytes
Właściwie to poza tym, że biblioteka ma być napisana w ASMie, to
nic :)

PS. Spojrzał już ktoś może na te errory/ Bo kurde nie umiem sobie z
tym poradzić...

pozdr
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1927
Author: Remek
Date: Tue, 26 May 2009 16:01
38 lines
1909 bytes
Użytkownik "MrokU" napisał:

> Spojrzał już ktoś może na te errory/ Bo kurde nie
> umiem sobie z tym poradzić...

Nie używam VC, więc wyodrębniłem kod DLL-ki do MrokU.asm :)

Skompilowało się po usunięciu jednego błędu:

sinus PROC kat:DQ

Masm32 akurat nie rozumie tej deklaracji. Musiałem podać:

sinus PROC kat:QWORD

ale wówczas nie zgadza mu się linia:

        mov eax, kat

ze względu na niezgodność rozmiarów operandów. Masm nie umie rzutować tak
jak HL-e. Dałem więc:

sinus PROC kat:DWORD

I teraz działa. Można również tak:


sinus PROC kat:QWORD

   ...

   mov eax, dword ptr kat

Zależy co ma być wykorzystane. W tym przypadku do eax zostanie zapisany
"górny" dword. Nie analizoeałem szczegółowo tej procedurki, więc nie wiem
czy to wystarczy. Analizować "w locie" potrafi Bogdan.

Remek
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1928
Author: MrokU
Date: Tue, 26 May 2009 16:29
9 lines
1664 bytes
No MASMem też to kompilowałem i nie miał problemów...

Tylko to zasrane VS mi się rzuca nie wiadomo o co... Więc to chyba nie
jest kwestia samej składni, tylko środowiska...

W czym jeszcze można robić tego typu projekty? W sensie C++ z ASMem,
żeby się normalnie debugować dało i kompilować jako jeden projekt?

pozdrawiam
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1920
Author: Bogdan (bogdro)
Date: Tue, 26 May 2009 16:52
50 lines
3550 bytes
MrokU pisze:
>>  Możesz nie pisać PUSHAD i POPAD, bo używasz tylko rejestru EAX, który
>> nie tylko można dowolnie zmieniać, ale przy wyjściu zawiera wynik.
> 
> No właśnie muszę używać, bo Visual mi się pluje, że coś robię nie tak
> z rejestrem ESI. Nie wiem o co chodzi, ale jak te instrukcje dodam, to
> żadnych błędów mi nie wyrzuca...

 Aha. No skoro tak, to nie ruszaj. Bo właśnie EBX, EBP, ESI i EDI nie
wolno ruszać (chyba że zachowa się i przywróci poprzednią wartość).

>>  Swoją drogą, chyba "wynik" jest od tego, by otrzymać wynik, a nie "kat"?
> 
> o FINIT nie wiedziałem. Jak na razie to jedyna funkcja, która używa
> liczb zmiennoprzecinkowych, ale domyślnie będzie to działało tak, że
> jedna duża funkcja będzie liczyła interpolację dla danego punktu, w
> związku z tym FINIT będzie tylko raz (aczkolwiek to na razie plany).
> Wynik jest do tego, żeby sobie spróbować zwrócić wynik w inny sposób
> niż przez eax, ale jak na razie tego nie robiłem, bo nie do końca wiem
> jak :P chociaż pewnie trzeba przekazać wskaźnik i modyfikować adres.
> Tylko nie zastanawiałem się jeszcze jak to robić.

 Jeśli "wynik" to adres zmiennej, to ładujesz go do rejestru, np. EAX,
po czym wynik z FPU ładujesz do [EAX].

>> #include <math.h>
>> #ifndef M_PI
>> #define M_PI 3.141592653589793238462643383279502884197 blablabla...
>> #endif
> 
> nie widziałem sensu dołączania całej biblioteki, skoro potrzebuję
> tylko PI (chociaż jak już mówiłem, to są dopiero próby i przymierzanie
> się do pisania programu).

 To nie jest dołączanie biblioteki w sensie binarnym (chyba że
środowisko/linker jest naprawdę tępy). To jest dołączanie pliku
nagłówkowego, a biblioteka fizycznie powinna zostać dołączona do
programu tylko jak są wywoływane z niej jakiekolwiek funkcje.

> No a z liczeniem sinusa 30 stopni, to nie ma sensu robić to z #define,
> bo nie będę liczył stałych wartości kątów. Wszystko leci na wzorach i
> będzie wyliczane na bieżąco.

 OK, to była tylko porada w razie czego.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1924
Author: Bogdan (bogdro)
Date: Tue, 26 May 2009 16:52
57 lines
3503 bytes
MrokU pisze:
> A czy wiecie może, co może być skutkiem nagłej zmiany w Windowsach i
> wysypu błędów?
> 
> Bo w pewnym momencie coś się VS odwidziało i kod, który się normalnie
> kompilował, nagle wyrzuca coś takiego (dla pewności kompilowany kod):

[...]

> KOMPILACJA:
> 1>------ Rebuild All started: Project: interJA, Configuration: Debug
> Win32 ------
> 1>Deleting intermediate and output files for project 'interJA',
> configuration 'Debug|Win32'
> 2>------ Rebuild All started: Project: DLLint, Configuration: Debug
> Win32 ------
> 2>Deleting intermediate and output files for project 'DLLint',
> configuration 'Debug|Win32'
> 2>Assembling...
> 1>Compiling...
> 1>main.cpp
> 2> Assembling: .\DLLint.asm
> 2>.\DLLint.asm(1) : error A2044: invalid character in file
> 2>.\DLLint.asm(2) : error A2008: syntax error : .
> 2>.\DLLint.asm(4) : error A2008: syntax error : .
> 2>.\DLLint.asm(6) : error A2008: syntax error : P
> 2>.\DLLint.asm(8) : error A2109: only white space or comment can
> follow backslash
> 2>.\DLLint.asm(10) : error A2109: only white space or comment can
> follow backslash
> 2>.\DLLint.asm(12) : error A2109: only white space or comment can
> follow backslash
> 2>.\DLLint.asm(14) : error A2109: only white space or comment can
> follow backslash
> 2>.\DLLint.asm(16) : error A2109: only white space or comment can
> follow backslash

 Wygląda, jakby nie tego narzędzia używał, choć niby pisze
"assembling". Cokolwiek zmieniłeś w opcjach projektu, cofnij to :)
 Sprawdź, czy kompiluje tym, co trzeba (nie wiem jak, nie pytaj - może
wystarczy gdzieś włączyć opcję pokazującą wykonywane komendy).
Sprawdź, czy opcje są dobre. Sprawdź, czy rozszerzenie jest dobre (w
niektórych kompilatorach na przykład ".c" a ".C" robi różnicę). Bo
wyglądałoby na to, że parsuje ten plik preprocesorem C, czego nie
powinien robić.

> 2>Build log was saved at "file://c:\Documents and Settings\Ala\Desktop
> \interJA\DLLint\Debug\BuildLog.htm"
> 2>DLLint - 44 error(s), 0 warning(s)

 Sprawdź, co napisał w tym pliku.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1929
Author: Remek
Date: Tue, 26 May 2009 17:56
20 lines
1988 bytes
Użytkownik "MrokU" napisał:

> No MASMem też to kompilowałem i nie miał problemów

Taki kod jaki podałeś? I nie zgłosił błędów? Próbowałeś uzyc tej DLLki w
jakims programie zrobionym w HLu?


> W czym jeszcze można robić tego typu projekty? W sensie C++ z ASMem,
> żeby się normalnie debugować dało i kompilować jako jeden projekt?

Moim zdaniem normalne to jest robienie DLLi jako samodzielnych projektów.
Przecież mają służyć wielu innym programom. No i jak asembler, to asembler,
a nie HL. Nie jestem mocny w językach wyższego poziomu, ale wydaje mi się,
że do kompilacji wstawek asemblerowych używają osobnych narzędzi np.
produkty Borlana - Tama, MS - Masma. Niektóre umożliwiają wybór z wielu
dostępnych (trzeba je wtedy doinstalować oddzielnie). I co to znaczy
"normalnie debugować"?

Remek
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1930
Author: MrokU
Date: Fri, 29 May 2009 17:49
48 lines
3635 bytes
W tym logu nie napisał nic ciekawego, to co wkleiłem plus informacje,
że linkuje i jakie programy do tego odpala...
Ale.
Już wszystko działa, nie wiem czemu nagle mu się odwidziało...

> Taki kod jaki podałeś? I nie zgłosił błędów? Próbowałeś uzyc tej DLLki w
> jakims programie zrobionym w HLu?

Nie no zgłosił błędy, ale po poprawieniu składni wszystko się
skompilowało.
DLLki używam w programie w C++. VS ma na tyle fajną możliwość, że
możesz w jednym projekcie mieć 2 podprojekty - jeden z HL i jeden jako
DLL w ASMie.

> Moim zdaniem normalne to jest robienie DLLi jako samodzielnych projektów.
> Przecież mają służyć wielu innym programom. No i jak asembler, to asembler,
> a nie HL. Nie jestem mocny w językach wyższego poziomu, ale wydaje mi się,
> że do kompilacji wstawek asemblerowych używają osobnych narzędzi np.
> produkty Borlana - Tama, MS - Masma. Niektóre umożliwiają wybór z wielu
> dostępnych (trzeba je wtedy doinstalować oddzielnie). I co to znaczy
> "normalnie debugować"?

No właśnie to jest DLLka, którą piszę na projekt na zaliczenie i ona
domyślnie służy do tego, żeby nauczyć się robić takie rzeczy i jest
dedykowana dla tego jednego programu. Zresztą jak będzie działać z
jednym, to z resztą również.

I nie chodzi tutaj o żadne wstawki, tylko o normalnego ASMa.

Normalnie debugować... Chodziło mi o to, że jestem w stanie w jednym
środowisku prześledzić kod w C++, przeskoczyć do DLL, prześledzić
rejestry i wrócić z powrotem do głównego programu.



No i teraz kolejne pytanie:
mam napisać funkcję, która wywoływana jest rekurencyjnie i zwraca
wartość double.
Na razie zwracałem wartości zmiennoprzecinkowe tylko wpisując wynik
pod adres podany jako zmienna wejściowa (tak jak napisał Bogdan).
Generalnie wyliczać mam taki wzorek:

U(k) = f(x) + 2 * U(k+1) * cos(B) - U(k+2)

zresztą mniejsza o to, możecie podpowiedzieć, jak zrobić takie
wywołanie rekurencyjne i zwrócenie wartości double przez funkcję?

pozdrawiam
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1931
Author: MrokU
Date: Sat, 30 May 2009 10:45
108 lines
4715 bytes
Na razie, po pierwszych próbach funkcja (oczywiście nie działa dobrze)
wygląda tak:

;******************************************************************
;****** 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
LOCAL t1:QWORD, t2:QWORD, t3:QWORD, t4:QWORD, temp:DWORD, tempptr:PTR
	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 eax, tab				; zachowanie adresu tablicy
	mov tempptr, eax
	add tempptr, 32			; przesuniecie sie do nastepnego elementu tablicy

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

	fld QWORD PTR [eax]		; 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 eax, tab				; zachowanie adresu tablicy
	mov tempptr, eax
	add tempptr, 64			; przesuniecie sie w tablicy o 2 elementy

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

	fld QWORD PTR [eax]		; odczytanie wyniku zwroconego przez wspU
	fstp t4					; zapisanie wyniku

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

	fmul st(0), st(1)			; st0 = 2 * cos(beta) * U(k+1)
	fld t1					; st0 = f(x)
	fadd st(0), st(1)			; st0 = f(x) + 2 * cos(beta) * U(k+1)
	fsub st(0), st(3)			; st0 = f(x) + 2 * cos(beta) * U(k+1) - U(k+2)

	popad

	fstp QWORD PTR [eax]	; zapisanie wyniku

	jmp Koniec

Zwroc0:
	fldz						; ladujemy 0 do st0
	popad
	fstp QWORD PTR [eax]; zapisanie zera pod adres wynikowy

Koniec:
	ret ;koniec funkcji



No i teraz nie wiem dlaczego, ale modyfikowane są wartości tab[].x
czyli te, pod adresami tab + x * 32 (bo tyle zajmują 4 double).

na szczęście błąd ten jest mało ważny. Jednak dla identycznych
parametrów, funkcja w C i w ASMie zwraca zupełnie inne wyniki i tego
już nie kumam... Patrze w te instrukcje i nie widzę gdzie może być
błąd...

wspU ENDP
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1932
Author: Bogdan (bogdro)
Date: Sat, 30 May 2009 14:06
94 lines
4358 bytes
MrokU pisze:
[...]
> Generalnie wyliczać mam taki wzorek:
>
> U(k) = f(x) + 2 * U(k+1) * cos(B) - U(k+2)
[...]

> Na razie, po pierwszych próbach funkcja (oczywiście nie działa dobrze)
> wygląda tak:
> 
> ;******************************************************************
> ;****** 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

 Wiesz, że ten prototyp wygląda inaczej niż ten z C i musisz tę
funkcję (znacznie) inaczej uruchamiać, prawda?

> LOCAL t1:QWORD, t2:QWORD, t3:QWORD, t4:QWORD, temp:DWORD, tempptr:PTR
> 	pushad
> 	finit
> 
> 	mov eax, k
> 	cmp eax, n				; if (k > n)
> 
> 	ja Zwroc0				; return 0;

 Załóżmy najpierw, że w tym punkcie warunek jest spełniony i skok JA
wykonany. W końcu kiedyś będzie się to musiało zdarzyć. Spójrz teraz,
co się dzieje pod "Zwroc0".

[...]
> 	fmul st(0), st(1)			; st0 = 2 * cos(beta) * U(k+1)
> 	fld t1					; st0 = f(x)
> 	fadd st(0), st(1)			; st0 = f(x) + 2 * cos(beta) * U(k+1)
> 	fsub st(0), st(3)			; st0 = f(x) + 2 * cos(beta) * U(k+1) - U(k+2)
> 
> 	popad
> 
> 	fstp QWORD PTR [eax]	; zapisanie wyniku

 Ta sama uwaga, co poniżej dla zwracania zera.

> 	jmp Koniec
> 
> Zwroc0:
> 	fldz						; ladujemy 0 do st0
> 	popad
> 	fstp QWORD PTR [eax]; zapisanie zera pod adres wynikowy

 Wielkie pytanie, co jest w EAX w tym miejscu, gdy "ja Zwroc0"
zostanie wykonane. A z resztą, nawet jak nie będzie wykonane, to co
jest w EAX? Wykonując POPAD, przywracasz wartość z momentu
uruchomienia funkcji, a rejestr EAX jest używany dowolnie, więc jego
wartość jest nieokreślona. Piszesz więc pod nieznany adres (przy
pierwszym uruchomieniu funkcji). Inicjalizuj EAX na tyle, ile trzeba
(czyli pewnie tab+8).

> No i teraz nie wiem dlaczego, ale modyfikowane są wartości tab[].x
> czyli te, pod adresami tab + x * 32 (bo tyle zajmują 4 double).
> 
> na szczęście błąd ten jest mało ważny. Jednak dla identycznych
> parametrów, funkcja w C i w ASMie zwraca zupełnie inne wyniki i tego
> już nie kumam... Patrze w te instrukcje i nie widzę gdzie może być
> błąd...

 Pewnie wszystko wina niezainicjalizowanych wskaźników. Jeśli nie, to
pokaż kod wywołujący.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1933
Author: MrokU
Date: Sat, 30 May 2009 15:01
138 lines
5701 bytes
>  Wiesz, że ten prototyp wygląda inaczej niż ten z C i musisz tę
> funkcję (znacznie) inaczej uruchamiać, prawda?

Wiem wiem.
Wywołanie z C jest dobre. Robię to poprzez wskaźnik na funkcję i
przekazanie odpowiednich parametrów (zresztą, trochę już pozmieniałem)

Skoki były ok, a pod eax były rzeczywiście wartości inne niż
oczekiwana. Teraz już normalnie zwracam wynik przez wpisanie go pod
adres, który dostaję do funkcji.

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 eax, tab			; zachowanie adresu tablicy
	mov tabptr, eax
	add tabptr, 32			; przesuniecie sie do nastepnego elementu tablicy

	lea eax, twynik			; wyluskanie adresu zmiennej twynik

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

	lea eax, twynik			; zaladowanie adresu wyniku
	fld QWORD PTR [eax]		; 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 eax, tab			; zachowanie adresu tablicy
	mov tabptr, eax
	add tabptr, 64			; przesuniecie sie w tablicy o 2 elementy

	lea eax, twynik			; wyluskanie adresu zmiennej twynik

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

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

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

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

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

	popad

	jmp Koniec

Zwroc0:
	fldz					; ladujemy 0 do st0

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

	popad

Koniec:
	ret ;koniec funkcji

wspU ENDP

Przy czym teraz to wszystko bardzo dziwnie działa...
Oba INVOKE wykonują się dobrze i zwracają poprawny wynik (nie
wchodzimy głębiej w rekurencję, bo tam wszystko dobrze się liczy).
Jednak, w momencie, gdy próbuję po nich wczytać jakąś lokalną zmienną,
dostaję błąd...

[...]
	fld t4					; st2 = U(k+2)
	fld t3					; st1 = U(k+1)
	fld t2					; st0 = 2 * cos(beta)

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

po wykonaniu powyższego, w st0 i st1 mam 1#IND... Najdziwniejsze jest
to, że dzieje się tak tylko na tym najwyższym poziomie rekurencji
(czyli w pierwszej wywołanej funkcji)...

No a wywołanie w C wygląda tak (oczywiście po maksymalnym okrojeniu):


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

Element *tab;
double *c, *e;
MYPROC4 ProcU;
HINSTANCE hinstLib;

main:
	hinstLib = LoadLibrary ("sss.dll");
	ProcU = (MYPROC4) GetProcAddress(hinstLib, "wspU");

	(ProcU)(3, 1, c, tab, e);
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1934
Author: Remek
Date: Sat, 30 May 2009 15:20
11 lines
1708 bytes
Użytkownik "MrokU" napisał:

> lea eax, twynik     ; wyluskanie adresu zmiennej twynik

Dlaczego mordujesz eax do indeksowania zmniennych? :) Do tego celu masz
rejestry indeksowe esi i edi. Zużyjesz rejestr i będziesz musiał wymieniać
procesor.

Pokaż wywołanie funkcji z głównego programu.

Remek
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1935
Author: MrokU
Date: Sat, 30 May 2009 15:59
93 lines
3803 bytes
cały kod w C++ wygląda tak:

Przy czym jest mało czytelny, bo chodzi tylko o wywołanie funkcji i
sprawdzenie jej działania...

#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <math.h>

#define PI
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
//---------------------------------------------------------------------------

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

typedef int (__stdcall *MYPROC)(int, int);
typedef double* (__stdcall *MYPROC2)(double*);
typedef void (__stdcall *MYPROC3)(int, int, double*);
typedef void (__stdcall *MYPROC4)(int, int, double*, Element*,
double* );

MYPROC ProcAdd, ProcSub;
MYPROC2 ProcSin;
MYPROC3 ProcBeta;
MYPROC4 ProcU;
HINSTANCE hinstLib;

Element *tab;
double *c, *e, d, f;

double U (int n, int k, double beta, Element *tab)  //obliczanie
wspolczynnika U - wzór 28
{
	if ( k > n )
		return (0.0);
	else {
		double fx = tab[k-1].f_x;
		double cosbet = cos(beta);
		double wynik = (fx + (2.0) * ( U(n, k+1, beta, tab) * cosbet ) - U
(n, k+2, beta, tab));
		std::cout << "f(x) = " << fx << "\n cos(beta) = " << cosbet << "\n
wynik: " << wynik << std::endl;
		return wynik;
	}
}

int main(int argc, char* argv[])
{
	hinstLib = LoadLibrary ("sss.dll");								//ladowanie biblioteki
	if (hinstLib == NULL)												//sprawdzenie, czy moduł faktycznie
został załadowany
		return 1;

	ProcU = (MYPROC4) GetProcAddress(hinstLib, "wspU");
	if (NULL != ProcU) {
		e = new (double);
		tab = new Element [7];
		d = PI/2;
		c = &d;

		tab[0].f_x = 2.0;

		tab[1].f_x = 6.0;

		tab[2].f_x = 10.0;

		tab[3].f_x = 14.0;

		tab[4].f_x = 18.0;

		tab[5].f_x = 22.0;

		tab[6].f_x = 24.0;

		f = U (6, 1, d, tab);
		(ProcU)(6, 1, c, tab, e);
	}

	FreeLibrary(hinstLib);

	std::cout << *e << std::endl;
	std::cout << f << std::endl;

	system("PAUSE");
	return 0;
}
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1936
Author: MrokU
Date: Sat, 30 May 2009 18:50
67 lines
3218 bytes
No, przepełniał mi się chyba stos FPU ...
Funkcja napisana od nowa, działająca, wygląda tak:

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]

	jmp Koniec

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

Koniec:
	popad
	ret;

wspU_2 ENDP
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1937
Author: 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
Re: Visual Studio 2008 (C++ oraz DLL w asmie) Interpolacja
#1938
Author: Bogdan (bogdro)
Date: Wed, 03 Jun 2009 15:59
40 lines
3120 bytes
MrokU pisze:
> 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 :)

[...]

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

 Średnik zapewne niepotrzebny :)

 Poza tym, można byłoby pewnie uniknąć ciągłego FINIT i PUSHAD+POPAD.
Zamiast dwóch INC można użyć ADD. Do procedury można przekazać adres
zmiennej od razu, bez używania rejestru, za pomocą "offset twynik" lub
"addr twynik". Można przerobić kod, by nie ładować "t4" na stos FPU 4
instrukcje po zdjęciu tej wartości. Sprawdzenie parzystości liczby:

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

można zastąpić kodem:

	test n, 1
	je Parzysta

 I mała sztuczka optymalizacyjna: widzę, że ciągle wyliczasz "j*x", a
nie widzę, by "x" się zmieniał w tym czasie. Jeśli dobrze widzę, to
możesz ustawić sobie jakiś rejestr na "x" (bo zaczynamy od 1) i
zwiększać go o "x" za każdą iteracją zamiast ciągle mnożyć.

 To tyle z moich uwag. Najważniejsze, że program działa i problemy
zostały rozwiązane.

-- 
Pozdrawiam/Regards - Bogdan                     (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.JabberPL.org www.TorProject.org Soft (EN): miniurl.pl/bogdro-soft
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads