News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Passing 2d arrays and 1d arrays from c++ to asm

Started by pawkondr, January 13, 2015, 03:18:19 AM

Previous topic - Next topic

jj2007

Quote from: qWord on January 18, 2015, 04:56:02 AMthen he just has to use something like

Yes indeed, see reply #6. The problem is not so much the declaration but that this giant "project" is scattered over 100 MB in 200+ files in akward locations and so occasionally one may lose the overview where the valid DLL version was placed, and where which version of the "project" expects it to be (hint:release and debug have their own respective paths).

qWord

Quote from: jj2007 on January 18, 2015, 05:09:29 AM
Quote from: qWord on January 18, 2015, 04:56:02 AMthen he just has to use something like

Yes indeed, see reply #6. The problem is not so much the declaration but that this giant "project" is scattered over 100 MB in 200+ files in akward locations
Most of this files are generated by the IDE, the actual project has just 15 files. The large files are for the autocomplete-database and the precompiled headers. You can delete most of these generated files and folders (debug, release, precompiled headers) before sharing to reduce the project size to some KB.

Quote from: jj2007 on January 18, 2015, 05:09:29 AMoccasionally one may lose the overview where the valid DLL version was placed, and where which version of the "project" expects it to be (hint:release and debug have their own respective paths).
the output of the projects is placed in the same directory after building - not that complicated.
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on January 18, 2015, 05:29:59 AMthe output of the projects is placed in the same directory after building - not that complicated.

I meant the input files, i.e. the DLL. Anyway, new set of files attached. Place in the folder where main.cpp sits, i.e. Przyklad
hDll = LoadLibrary("..\\Przyklad\\Asm2Cpp.dll");
cout << "loaded, hDll=" << hDll << "\n";

if (hDll != NULL){
myAsmProc = (DLLFunc)GetProcAddress(hDll, "myAsmAlgo");
cout << "GetProcAddress = " << myAsmProc << "\n";
if (myAsmProc != NULL)
result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
else
result = -1;
cout << "Result from dll: " << result;
cout << "\nFreeLibrary result is " << FreeLibrary(hDll);

qWord

Each project has its own debug/release/(what ever other configuration) folder, but after building the output is copied to the corresponding folder of the project solution. So there is no need for relative path, because the DLL and the EXE are in the same directory after building.
MREAL macros - when you need floating point arithmetic while assembling!

pawkondr

The problem is that he passes wrong parameters. In the screen below you can see that n value is 0. And when I want to print that array on screen:
for (int i = 0; i < rowA; ++i){
for (int j = 0; j < rowA; ++j){
cout << arrayAlfa[i][j] << endl;;
}
}

That runtime error occures. Maybe i am doing something forbidden?
I also changed to this line:
typedef int(__cdecl * DLLFunc)(double** A, double* B, double** alfa, double* beta, int n);


jj2007

Quote from: pawkondr on January 18, 2015, 06:01:59 AM
The problem is that he passes wrong parameters.

Check the latest version posted above. No runtime errors, but it might well be that I misunderstand how the matrices are built. For now it seemed more important to get the build system running.

myAsmAlgo proc uses esi edi ebx pA, B, pAlfa, beta, n   ; double** A, double* B, double** alfa, double* beta, int n)
  mov esi, pA
  mov esi, [esi]   ; **matrix

  mov edi, pAlfa
  mov edi, [edi]   ; **matrix

qWord

The ASM code is assuming a flat "2D" array, which is not correct.
MREAL macros - when you need floating point arithmetic while assembling!

pawkondr

Here is what I found:
I run program with your main.cpp and your dll, as you said no runtime errors but results are wrong. Here is screen:

Here are correct results from my c++ library, which i think works properly (Numbers below "Result from library"):



My professor requires from me my own dll so i put that MyAsmAlgo proc to my library and tried it. Errors are still there but there are diffrent values of parameters and n is correct -> 3 not 0 like before.

qWord

try this one
.686
.xmm
.model flat, C

PREAL8 typedef ptr REAL8
PVOID typedef DWORD

.code
option prologue: none
option epilogue: none
MyProc proc C uses esi edi ebx A: ptr PREAL8, B: ptr REAL8, alfa: ptr PREAL8, beta: ptr REAL8, n: SDWORD

; save nonvolatile registers
push esi
push edi
push ebx
push ebp
PUSHED = 4*DWORD

; load pointers
mov ebx, [esp + 1*PVOID + PUSHED] ; A
mov esi, [esp + 2*PVOID + PUSHED] ; B
mov edi, [esp + 3*PVOID + PUSHED] ; alfa
mov edx, [esp + 4*PVOID + PUSHED] ; beta

xor ebp,ebp

; for each row-pointer
xor ecx,ecx
.while ecx < [esp+5*PVOID + PUSHED] ; i < n

; for each value in current row
xor eax,eax
.while eax < [esp+5*PVOID + PUSHED] ; j < n

; 0 =  default value
xorpd xmm0,xmm0

; if i != j
.if ecx != eax

; load A[i][j]
mov ebp,[ebx+ecx*PREAL8]
movsd xmm1,REAL8 ptr [ebp+eax*REAL8]

; load A[i][i]
mov ebp,[ebx+ecx*PREAL8]
movsd xmm2,REAL8 ptr [ebp+ecx*REAL8]

; avoid div. by zero
comisd xmm0,xmm2
je @err

; div A[i][j] by A[i][i]
divsd xmm1,xmm2

;  change sign
subsd xmm0,xmm1

.endif

; store alfa[i][j]
mov ebp,[edi+ecx*PREAL8]
movsd REAL8 ptr [ebp+eax*REAL8],xmm0

; next value
add eax,1
.endw

; load B[i]
movsd xmm0,REAL8 ptr [esi+ecx*REAL8]

; div B[i] by A[i][i]
mov ebp,[ebx+ecx*PREAL8]
divsd xmm0,REAL8 ptr [ebp+ecx*REAL8]

; store beta[i]
movsd REAL8 ptr [edx+ecx*REAL8],xmm0

; next row
add ecx,1
.endw

pop ebp
pop ebx
pop edi
pop esi

; indicate success (?)
xor eax,eax
retn

align 16
@err:

pop ebp
pop ebx
pop edi
pop esi

; indicate error (?)
mov eax,-1
retn

MyProc endp

end

(calling convention = __cdecl)
MREAL macros - when you need floating point arithmetic while assembling!

pawkondr

qWord, your code that you gave me works perfectly. Results are the same as it should be. No errors.
Thanks for your help qWord and jj2007. I will keep testing, writing and learning :)

jj2007

Quote from: pawkondr on January 18, 2015, 09:06:12 AM
qWord, your code that you gave me works perfectly. Results are the same as it should be. No errors.
Thanks for your help qWord and jj2007. I will keep testing, writing and learning :)

You are welcome :icon14:

My code didn't work correctly because I had no time to find out how the matrices were constructed. I am glad that qWord's version works fine (he is a bright coder :t), but be aware that 1. your teacher can use Google, too and 2. you may have to explain to him how movsd, comisd, subsd etc work. You can find them in the Intel manuals under SIMD or SSE2. My code uses the FPU, which is a bit older but does the job perfectly. So how is this assembler experience for you? Will you come back from time to time and play with us, or will you stick to C/C++?  ;)