The MASM Forum

General => The Campus => Topic started by: pawkondr on January 13, 2015, 03:18:19 AM

Title: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 13, 2015, 03:18:19 AM
Hello!
I have a problem and I would like to ask if this is possible to do.
I have asm library, and I would like to pass two arrays and two 2d arrays. First is matrix given, second is result matrix third is matrix with answers and last is matrix with results after calculations. Last parameter is length. For example if last param is 5 you have matrixes 5x5, 5, 5x5, 5.
This is code in c++:
typedef int(_stdcall *DLLFunc)(double**, double*, double**, double*, int);
than in main function:
   
hDll = LoadLibrary("FibAsmLib");

if (hDll != NULL){

//proc = GetProcAddress(hDll, "MyProc");
myAsmProc = (DLLFunc)GetProcAddress(hDll, "MyProc");

if (myAsmProc != NULL){
result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
}
}

How am I supposed to operate on this pointers in asm? How to get any value from that array?
My code in asm:
.486
.model flat, stdcall
.data
.code

PUBLIC MyProc
MyProc proc w: DWORD, x:DWORD, y:DWORD, z:DWORD, e:DWORD
mov eax, 5
ret
MyProc endp
end

Library is connected correctly.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 13, 2015, 04:50:18 AM
What you want is certainly possible. You pass pointers to matrices - just use them. Suppose you want to return the sum w(n)+y(n) in x:
MyProc proc uses esi edi w: DWORD, x:DWORD, y:DWORD, z:DWORD, e:DWORD
  xor ecx, ecx
  ; int 3
  mov esi, w
  mov edx, y
  mov edi, x
  .Repeat
        mov eax, [esi+DWORD*ecx]  ; get w value from element ecx
        add eax, [edx+DWORD*ecx]  ; add y value from element ecx
        mov [edi+DWORD*ecx], eax  ; store in destination element ecx
        inc ecx
  .Until ecx>e  ; could be > or >=, check yourself
  ret


Besides, you should certainly uncomment the ; int 3, set Olly (http://www.ollydbg.de/version2.html) as your just in time debugger, and follow step by step using the F7 key.

Welcome to the forum :icon14:
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 15, 2015, 02:13:58 AM
Hello, thanks for answer. My job is to do the same thing in c++ and in assembler and compare results.
This is my code in c++ which is in an external library.
CPPLIBRARY_API int fnCPPLibrary(double** A, double* B, double** alfa, double* beta, int n){
for (int i = 0; i < n; i++){
if (A[i][i] == 0) {
std::cout << "You cant create alfa and beta matrix" << std::endl << "Devision by 0!" << std::endl;
return 1;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j) alfa[i][j] = 0;
else
alfa[i][j] = -(A[i][j] / A[i][i]);
}
beta[i] = B[i] / A[i][i];
}
return 0;
}

Is this very complicated? I have never wrote code in assembler. Code in c++ was easy as pie. Can you give me some help?
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: dedndave on January 15, 2015, 04:51:46 AM
the forum search tool might help
i seem to recall a few threads related to C-called asm functions

probably one easy way is to use a static library
so - that might be a good search term
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 15, 2015, 06:14:16 AM
If I could find a solution myself i would try to solve it and definetly I wouldn't waste your time. I need some good advices :)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: FORTRANS on January 15, 2015, 06:24:44 AM
Hi,

Quote from: pawkondr on January 15, 2015, 02:13:58 AM
My job is to do the same thing in c++ and in assembler and compare results.


   For the following line of code;

for (int i = 0; i < n; i++) {

The assembly code could look like this:

NTest   EQU     5       ;  Assign a value for "n".  Or MOV the value
                        ; into a register to test against.

        MOV     [IndexI],0      ; int i = 0;"
ForI:                           ; Top of for loop. "for ("

        CMP     [IndexI],NTest  ; "i < n;"
        JGE     ForEnd

                                ; Do stuff "{ ... }"

        INC     [IndexI]        ;  "i++"
        JMP     ForI

ForEnd:


   Does that help or hurt?

Regards,

Steve N.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: habran on January 15, 2015, 06:46:57 AM
Hi pawkondr

My version of JWasm has built in .FOR - .ENDFOR loop
To type the separator '¦' pres ALT then type 221 and release ALT
I promise you it will work faster than C++
you can write something like this:

     .for (ebx=0¦ebx<n¦ebx++)
         .for (edi=0¦edi<n¦edi++)
              ;some code
         .endfor
     .endfor
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 15, 2015, 08:12:02 AM
Ok, thanks for answers. How to get value from correct field in array? like a[index i][index j] in c++?
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: dedndave on January 15, 2015, 08:12:46 AM
Quote from: pawkondr on January 15, 2015, 06:14:16 AM
If I could find a solution myself i would try to solve it and definetly I wouldn't waste your time. I need some good advices :)

i would help more if i could
i just don't write much code in anything but assembler
i can make a static library, however   :P
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 15, 2015, 08:59:56 AM
Here is part of the solution - more attached, with sources in *.asc aka RTF format.

Quote from: pawkondr on January 15, 2015, 08:12:02 AM
How to get value from correct field in array? like a[index i][index j] in c++?
Check in particular the lea instruction in the source.

include \masm32\include\masm32rt.inc

.code
fnCPPLibrary proc uses esi edi ebx pA, B:DOUBLE, pAlfa, beta:DOUBLE, n      ; double** A, double* B, double** alfa, double* beta, int n) $export (keyword for building the dll with RichMasm)
  mov esi, pA
  A equ <DOUBLE ptr [esi]>
  mov edi, pAlfa
  alfa equ <DOUBLE ptr [edi]>
  i equ <eax>
  j equ <ebx>
  mov i, 0
  .While i<n
      mov j, 0
      .While j<n
            push eax
            .if i==j
                  imul eax, i, DOUBLE      ; alfa[j]=0
                  imul n
                  lea eax, [eax+j*DOUBLE]
                  ; deb 4, "Loop", eax      ; debug macro needs MasmBasic (http://masm32.com/board/index.php?topic=94.0)
                  fldz      ; alfa[j]=0
            .else
                  imul eax, i, DOUBLE
                  imul n      ; i*n
                  mov edx, [esp]
                  lea eax, [eax+edx*DOUBLE]
                  fld A[eax]      ; A
                  imul eax, dword ptr [esp], DOUBLE
                  imul n
                  lea eax, [eax+j*DOUBLE]
                  ; deb 4, "Loop", eax
                  fld A[eax]      ; A[j]
                  fchs      ; change sign
                  fdiv      ; divide: alfa[j] = -(A[j] / A)
            .endif
            fstp alfa[eax]
            pop eax
            inc j
      .Endw
      inc i
  .Endw
  ret
fnCPPLibrary endp

LibMain proc instance:DWORD, reason:DWORD, unused:DWORD
    m2m eax, TRUE
    ret
LibMain endp

end LibMain


Output using a 5x5 matrix:
mxA DOUBLE 100.0, 100.1, 100.2, 100.3, 100.4
DOUBLE 101.0, 101.1, 101.2, 101.3, 101.4
DOUBLE 102.0, 102.1, 102.2, 102.3, 102.4
DOUBLE 103.0, 103.1, 103.2, 103.3, 103.4
DOUBLE 104.0, 104.1, 104.2, 104.3, 104.4

mxB DOUBLE rows*columns dup(?)

; *       c0      c1      c2      c3      c4
; r0      0.000   -0.999  -0.998  -0.997  -0.996
; r1      -1.001  0.000   -0.999  -0.998  -0.997
; r2      -1.002  -1.001  0.000   -0.999  -0.998
; r3      -1.003  -1.002  -1.001  0.000   -0.999
; r4      -1.004  -1.003  -1.002  -1.001  0.000
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 15, 2015, 02:29:13 PM
Thanks for your answer, I am impressed :)
But i need to do this as a library in visual studio. I must have code inside that library and then i need to call this function from my cpp code which i gave in first post. How to do that with that code from post above?
Thanks for all your help. I am so grateful.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: dedndave on January 15, 2015, 03:43:48 PM
you haven't said whether you want a static library or dynamic one

but, here is an example of a static lib, written in ASM
all you need is a simple C header file to include it into a C project

http://masm32.com/board/index.php?topic=2743.msg29059#msg29059 (http://masm32.com/board/index.php?topic=2743.msg29059#msg29059)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 15, 2015, 11:01:02 PM
Here is my library, project from visual studio. It must be called from this code in c++:
hDll = LoadLibrary("FibAsmLib");

if (hDll != NULL){

myAsmProc = (DLLFunc)GetProcAddress(hDll, "MyProc");

if (myAsmProc != NULL){
result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
}
}
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 16, 2015, 02:11:37 AM
You are still showing code that loads a DLL, so my previous code would perfectly fit.
However, if you prefer a static library, it's attached. The source file is in RTF format.

You call MyProc exactly as you would call your static C++ library. Just change the library name.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 16, 2015, 05:21:11 AM
Hello again, I tried to change called library name but it throws me error like this:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

And if I try to paste code that you wrote to me to my dll, that I created visual throws me some errors too:
Error   1   error A1000: cannot open file : \masm32\include\masm32rt.inc
Error   2   error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\fibAsm.obj" /W3 /errorReport:prompt  /TafibAsm.asm" exited with code 1.   C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations\masm.targets   50   5   FibAsmLib

This language is killing me :(
Thanks for answers

Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 16, 2015, 06:52:34 AM
Quote from: jj2007 on January 16, 2015, 02:11:37 AMYou call MyProc exactly as you would call your static C++ library.

Post the VS "project" where you CALL your static C++ library, complete with the arrays and the output that your proggie produces. There must be something like
  MyProc(bunch, of, paras);

That is what we need to see. And btw assembler is a lot easier and simpler than C++.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: dedndave on January 16, 2015, 07:45:06 AM
i would imagine that C procedures default to C calling convention
we often use StdCall in ASM - and most windows API's also use this convention

so - see how they are defined and how they are prototyped - you probably have a mismatch somewhere
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 17, 2015, 09:39:59 AM
Hello again, I have uploaded my whole VS2013 solution. It was much larger than 0,5 MB so, I put it on Google Drive. Here is the link:
https://drive.google.com/file/d/0B0kbQ3Gi5BRTdDgtQXJrUGw3b0E/view?usp=sharing (https://drive.google.com/file/d/0B0kbQ3Gi5BRTdDgtQXJrUGw3b0E/view?usp=sharing)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 17, 2015, 10:31:49 AM
163,154,560 bytes for a hello world proggie? I love C++ :greensml:

Besides, my version of VS doesn't like it, see below, and the only interesting part is this:
hDll = LoadLibrary("FibAsmLib");

if (hDll != NULL){

myAsmProc = (DLLFunc)GetProcAddress(hDll, "MyProc");
if (myAsmProc != NULL){
result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
}


That is code for loading a DLL, as mentioned twice in this thread, and it is only slightly different from linking to a static lib. Once you are able to link to a static C++ library, and using myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);, show us that part only.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 17, 2015, 10:48:59 AM
Ok, I will do that.
BTW. Try to open .sln file in notepad and change this lines:
Microsoft Visual Studio Solution File, Format Version 12.00
Visual Studio 2013
To:
Microsoft Visual Studio Solution File, Format Version 10.00
Visual Studio 2010
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 17, 2015, 07:20:02 PM
Quote from: pawkondr on January 17, 2015, 10:48:59 AM
Ok, I will do that.
BTW. Try to open .sln file in notepad and change this lines:
Microsoft Visual Studio Solution File, Format Version 12.00
Visual Studio 2013
To:
Microsoft Visual Studio Solution File, Format Version 10.00
Visual Studio 2010

This is a hilarious hack, but the converter swallows it :t
However, VS then complains that the toolset is not valid. OK, Google is our friend, and many many people are fighting with Microsoft, so that is also solved.

The good news: your project builds without errors, and it even runs!!!

Until it hits this simple line:
   hDll = LoadLibrary("FibAsmLib");
And then, Windows 7-64 complains that MSVCR120.dll is not present on the computer.

Seriously, what else do you expect from a hello world proggie that needs 163,154,560 bytes of disk space?

Redmond!! REEEEEDDDDDMMOOOOOOOND!!!!

QuoteThere was once a young man who, in his youth, professed his desire to become a great writer. When asked to define "great" he said, "I want to write stuff that the whole world will read, stuff that people will react to on a truly emotional level. Stuff that will make them scream, cry, and howl in pain and anger!"

He now works for Microsoft, writing error messages.

QuoteA helicopter was flying around above Seattle when an electrical malfunction disabled all of the aircraft's electronic navigation and communications equipment. Due to the clouds and haze, the pilot could not determine the helicopter's position and course to fly to the airport. The pilot saw a tall building, flew toward it, circled, drew a handwritten sign, and held it in the helicopter's window. The pilot's sign said "WHERE AM I?" in large letters. People in the tall building quickly responded to the aircraft, drew a large sign, and held it in a building window. Their sign read "YOU ARE IN A HELICOPTER." The pilot smiled, waved, looked at his map, determined the course to steer to SEATAC airport, and landed safely. After they were on the ground, the co-pilot asked the pilot how the "YOU ARE IN A HELICOPTER" sign helped determine their position. The pilot responded "I knew that had to be the Microsoft building because they gave me a technically correct, but completely useless answer."

Back to work: I attach a version of your Main.cpp that builds and runs because it uses a static lib. Main points:

#define asmLibDll 0
#if asmLibDll==0
#pragma comment(lib, "testJJ.lib") // the static library
extern "C" int __stdcall myAsmProc(double** A, double* B, double** alfa, double* beta, int n);
#endif


#if asmLibDll
DLLFunc myAsmProc;
#endif


//ASM library
#if asmLibDll==0
//_asm int 3;
cout << "\n#elements=" << rowA;
result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
//_asm int 3;
//_asm mov eax, result;
cout << "\nResult from library: " << result;
#else
cout << "\nloading FibAsmLib\n";
hDll = LoadLibrary("FibAsmLib");
cout << "loaded\n";


The asm part works in principle, i.e. it does return with eax==111111111, and the stack is balanced, but it doesn't do anything useful:
myAsmProc proc uses ecx edx esi edi ebx pA, B, pAlfa, beta, n ; double** A, double* B, double** alfa, double* beta, int n)
  mov esi, pA
  mov eax, 111111111
  ret


Main.cpp, library and asm source are attached. Hope it helps ;-)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 18, 2015, 12:25:21 AM
That static lib works perfectly, but I read once again requirements of my project and I must use dynamic library (dll) compiled in visual studio, so I returned to your code(that one from reply #9), I put it to my fibAsm.asm file inside of FibAsmLib project, I compiled it then I corrected 5 milion errors and in the end VS built it, but when i try to call that dll it throws my fauvorite error:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
This error sais: "Something is wrong find it and correct it because we dont give an shit"
Do you have an Idea what's causing it?
I am starting to hate everything connected with this project, so much that I will start to write error messages for MS  :greensml:
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 12:51:35 AM
Quote from: pawkondr on January 18, 2015, 12:25:21 AMThat static lib works perfectly, but ... a function declared with one calling convention with a function pointer declared with a different calling convention.

The problem is your declaration of DllFunc, probably hidden somewhere in the headers. I bet it is ccall.
So, attached the original DLL as CCALL, with source in RTF format. It should work, but test yourself - my VS throws that stupid error msvcrt120.dll not found. For a LoadLibrary call, good grief :eusa_boohoo:
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 18, 2015, 01:46:32 AM
How to tell compiler that the call convenction is ccall? I had _stdcall it didn't work, i deleted _stdcall, also didn't work. I tried to add something like this _ccall. Errors.

typedef int(_stdcall *DLLFunc)(double**, double*, double**, double*, int);

Or maybe is not that line or sth?
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: TWell on January 18, 2015, 02:44:58 AM
Compiling that dll in C someone can have easily exported names as excepted.

In cpp mangled names exists in dll like:
?fnFibAsmLib@@YAHXZ
?fnFibAsmLib@@3HA
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 03:33:10 AM
pawkondr,

use the following declaration in the header file FibAsmLib.h:
extern "C" FIBASMLIB_API int __cdecl MyProc(double** A, double* B, double** alfa, double* beta, int n);

The ASM file is:
.686
.xmm
.model flat, C

PREAL8 typedef ptr REAL8

.code
MyProc proc C A: ptr PREAL8, B: ptr REAL8, alfa: ptr PREAL8, beta: ptr REAL8, n: SDWORD
; ...
mov eax, 5
ret

MyProc endp

end


then
- add the project directory FibAsmLib to the include paths of project Przyklad
- add library to linker input: "$(OutDir)FibAsmlib.lib"
- do not forget to set configuration == win32.
- include FibAsmLib.h into main.cpp and call MyProc directly (means: do not use GetProcAddress)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 04:29:06 AM
Quote from: qWord on January 18, 2015, 03:33:10 AMcall MyProc directly (means: do not use GetProcAddress)
Quote from: pawkondr on January 18, 2015, 12:25:21 AM
That static lib works perfectly, but I read once again requirements of my project and I must use dynamic library (dll)

Solution is to use somealgo proc C in assembler, and something like this in C++ (tested, it works):
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);
}
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 04:38:15 AM
Quote from: jj2007 on January 18, 2015, 04:29:06 AM
Quote from: qWord on January 18, 2015, 03:33:10 AMcall MyProc directly (means: do not use GetProcAddress)
Quote from: pawkondr on January 18, 2015, 12:25:21 AM
That static lib works perfectly, but I read once again requirements of my project and I must use dynamic library (dll)

Solution is to use somealgo proc C in assembler.
?
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 04:44:29 AM
See above - teacher wants him to use LoadLibrary 8)

Attention: I lost one hour chasing a "bug" that consisted simply in believing current directory is where main.cpp sits. Nope, VS expects the DLL in the debug and/or release folders.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 04:56:02 AM
Quote from: jj2007 on January 18, 2015, 04:44:29 AM
See above - teacher wants him to use LoadLibrary 8)
then he just has to use something like:
   typedef int(__cdecl * DLLFunc)(double** A, double* B, double** alfa, double* beta, int n);
...
   hDll = LoadLibrary("FibAsmLib");

   if (hDll != NULL){

      DLLFunc myAsmProc;
     
      myAsmProc = (DLLFunc)GetProcAddress(hDll, "MyProc");

      if (myAsmProc != NULL){
         result = myAsmProc(arrayA, arrayB, arrayAlfa, arrayBeta, rowA);
      }
   }
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: 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 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).
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 05:29:59 AM
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.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 05:34:18 AM
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);
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 05:44:42 AM
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.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 18, 2015, 06:01:59 AM
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);
(http://www.img.pl/KbMg.png)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 06:16:55 AM
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
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 06:28:45 AM
The ASM code is assuming a flat "2D" array, which is not correct.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: pawkondr on January 18, 2015, 07:12:35 AM
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:
(http://www.img.pl/pcMg.png)
Here are correct results from my c++ library, which i think works properly (Numbers below "Result from library"):
(http://www.img.pl/ncMg.png)


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.
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: qWord on January 18, 2015, 07:24:15 AM
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)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: 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 :)
Title: Re: Passing 2d arrays and 1d arrays from c++ to asm
Post by: jj2007 on January 18, 2015, 12:07:18 PM
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++?  ;)