Link to home
Start Free TrialLog in
Avatar of 00transam
00transam

asked on

Reading in two floating point arrays from a C++ driver using a subprogram in assembly.

Hi all, I am in need of a some help with a subprogram that will read in two floating point arrays. These arrays are matricies. The dimensions of the matricies are as follows X = n1 * n2 Y=n2*n3 and z which is going to be the computed matrix is X * Y. The C++ driver program is below. It displays both matricies and their resultant matrix, along with the floating point matrix that the subprogram is supposed to compute.  I have tried to read in the arrays.  From what I have read these arrays are passed by reference pointer or address. So the first argument of the address is the address of an array of addresses.  Each address in the array is the address of a row of the matrix. Well here is the driver.

#include <iostream>

using namespace std;

// asm_matmult prototype
extern "C"
  void asm_matmult(double **X, double **Y, double **Z, int n1, int n2, int n3);

int main()
{
   int i, j;
   const int N1 = 3, N2 = 2, N3 = 4;
   double AI[N1][N2] = { 1, 2, 3, 4, 5, 6 };
   double BI[N2][N3] = { 1, 2, 3, 4, 5, 6, 7, 8 };
   // Result from Matlab
   double CI[N1][N3] = {11, 14, 17, 20, 23, 30, 37, 44, 35, 46, 57, 68 };
   double DI[N1][N3];

   // AI, BI and DI (above) are 2D array types.

   // In C++ it is preferrable to work with pointers to pointers than
   // 2D array types (see Stroustrup C.7.2 & C.7.3 for problems with
   // 2D arrays).
   // A, B, and D are corresponding pointers to arrays of pointers.
   // Each pointer in an array points to a row in the corresponding
   // AI, BI, or DI 2D array.

   double **A = new double*[N1];
   for(i=0; i<N1; i++)
      A[i] = AI[i];

   double **B = new double*[N2];
   for(i=0; i<N2; i++)
      B[i] = BI[i];

   double **D = new double*[N1];
   for(i=0; i<N1; i++)
      D[i] = DI[i];

   cout << "A =\n";
   for (i=0; i<N1; i++) {
      for (j=0; j<N2; j++) {
         // printf("%10.4f    ", A[i][j]);
         cout << A[i][j] << "   ";
      }
      cout << '\n';
   }
   cout << endl;

   cout << "B =\n";
   for (i=0; i<N2; i++) {
      for (j=0; j<N3; j++) {
         cout << B[i][j] << "   ";
      }
      cout << '\n';
   }
   cout << endl;

   cout << "A*B is equal to\n";
   for (i=0; i<N1; i++) {
      for (j=0; j<N3; j++) {
         cout << CI[i][j] << "   ";
      }
      cout << '\n';
   }
   cout << endl;

   asm_matmult(A, B, D, N1, N2, N3);

   cout << "Value computed by asm_matmult() is\n";
   for (i=0; i<N1; i++) {
      for (j=0; j<N3; j++) {
         cout << D[i][j] << "   ";
      }
      cout << '\n';
   }
   cout << endl;

   return 0;
}

and here is what I have so far for the assembly subprogram. Its not much because I cannot get the array passed to the fpu stack where I can manipulate it.

.globl _asm_matmult
      
.section .text

_asm_matmult:
      
mat:
      pushl %ebp                                    #save the stack data pointer            
    movl %esp, %ebp                              #move the stack pointer to the stack data pointer
    movl 8(%ebp), %eax      
                  
      finit                                          #initializes the FPU stack
                                                                        
      
      movl %ebp, %esp                              #move the stack pointer back
    popl %ebp                                    #restore ebp

    ret

Thanks for any help that can be provided.
Avatar of 00transam
00transam

ASKER

I have a subprogram now that will read  the arrays in one at a time.  I cant figure out how to them in to the fpu stack row by column so that I can multiply them. Here is the subprogram

#  X at   8(%ebp) # Y at 12(%ebp) Z at 16(%ebp) # n1 at 20(%ebp) # n2 at 24(%ebp) # n3 at 28(%ebp)
#  i at  -4(%ebp) #   j at -8(%ebp)
# X = 1,2,3,4,5,6
# Y = 1,2,3,4,5,6,7,8
# N1 = 3
# N2 = 2
# N3 = 4
.globl _asm_matmult
      
.section .text

_asm_matmult:
      
      pushl      %ebp                        # set up stack frame reg
      movl      %esp,%ebp
      subl      $104,%esp                # making room for local variables

      # for(int i=0; i<n1; i++) {
      movl      $0, -4(%ebp)            # i = 0
begfor_i:
      movl      -4(%ebp),%eax            # EAX = i
      cmpl      20(%ebp),%eax            # if (i<n1)
      jge      endfor_i

      # for(int j=0; j<n2; j++) {
      movl      $0, -8(%ebp)            # j = 0
begfor_j:
      movl      -8(%ebp),%eax            # EAX = j
      cmpl      24(%ebp),%eax            # if (j<n2)
      jge      endfor_j

      movl      8(%ebp),%eax            # EAX = **X
      movl      -4(%ebp),%ecx            # ECX = i
      movl      (%eax,%ecx,4),%eax      # EAX = X[i] (a pointer)
      movl      -8(%ebp),%ecx            # ECX = j
      fldl      (%eax,%ecx,8)            # FPU: X[i][j]
      #call      print_double
      ffree      %st(0)                        # FPU: empty
      #movl      $' ,%eax
      #call      print_char
   
      incl      -8(%ebp)
      
      
      jmp      begfor_j
endfor_j:
      #call      print_nl

      incl      -4(%ebp)            # i++
      jmp      begfor_i
endfor_i:
       %eax
      movl      %ebp, %esp             # restore previous stack frame ptr
      popl      %ebp
      ret

 the above part reads in the X array and the below part will read in the Y array I just need to read in one row of the x array and multiply it by the first column in the Y array

For example 1*1 + 2*5 so the first element of the resultant array would be 11.

readY:

      #pushl      %ebp                        # set up stack frame reg
      #movl      %esp,%ebp
      #subl      $104,%esp                # making room for local variables

      # for(int i=0; i<n1; i++) {
      movl      $0, -4(%ebp)            # i = 0
begfor1_i:
      movl      -4(%ebp),%eax            # EAX = i
      cmpl      24(%ebp),%eax            # if (i<n1)
      jge      endfor1_i

      # for(int j=0; j<n2; j++) {
      movl      $0, -8(%ebp)            # j = 0
begfor1_j:
      movl      -8(%ebp),%eax            # EAX = j
      cmpl      28(%ebp),%eax            # if (j<n2)
      jge      endfor1_j

      movl      12(%ebp),%eax            # EAX = **X
      movl      -4(%ebp),%ecx            # ECX = i
      movl      (%eax,%ecx,4),%eax      # EAX = X[i] (a pointer)
      movl      -8(%ebp),%ecx            # ECX = j
      fldl      (%eax,%ecx,8)            # FPU: X[i][j]
      #call      print_double
      ffree      %st(0)                        # FPU: empty
      #movl      $' ,%eax
      #call      print_char
   
      incl      -8(%ebp)
      movl 24(%ebp), %eax
      cmpl -8(%ebp), %eax
      jg readY
      jmp      begfor1_j
endfor1_j:
      #call      print_nl

      incl      -4(%ebp)            # i++
      jmp      begfor1_i
endfor1_i:

      movl      %ebp, %esp             # restore previous stack frame ptr
      popl      %ebp
      ret
ASKER CERTIFIED SOLUTION
Avatar of PeterdLo
PeterdLo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of Jose Parrot
Jose Parrot
Flag of Brazil image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial