News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Passing 2-dimensional array from C++

Started by magus841, May 10, 2010, 08:24:35 PM

Previous topic - Next topic

magus841

I have another assignment in which I'd like to pass a two dimensional array from a C++ program to a procedure in Assembly Language. And also pointers to integers. The actual code is this:


const int ROWS = 30, COLS = 100;
extern "C"{
    void Process(int numbers[ROWS][COLS], int which, int searchfor, int &rnum, int &cnum);
}


What I really want to know is how to handle the two-dimensional array and the two pointers once I get to the assembly code, which is looking like this so far:


INCLUDE Irvine32.inc

.data
mult_Val dd 1

.code
Process PROC C numbers:DWORD, which:DWORD, searchfor:DWORD, rnum:DWORD, cnum:DWORD
    ;begin filling the array

    mov eax, 0

Process ENDP


What the assembler code is supposed to do is fill the array with numbers and then search for the seventh appearance of a specific number (256). I appreciate any help I can get :) thank you very much.

clive

The array passed down is dimensionless, are you supposed to pass the size down in rnum/cnum?

Process PROC C numbers:DWORD, which:DWORD, searchfor:DWORD, rnum:DWORD, cnum:DWORD
    ;begin filling the array

    mov eax, 0

; Pointer code looks like this, modify to suit

mov edx,rnum
mov ecx,[edx] ; ecx = *rnum

mov [edx],ecx ; *rnum = ecx


mov edx,cnum
mov ecx,[edx] ; ecx = *cnum

mov [edx],ecx ; *cnum = ecx

ret

Process ENDP
It could be a random act of randomness. Those happen a lot as well.

magus841


int main(void) {
  int numbers[ROWS][COLS];
  long int start, end;
  float dif;
  int rnum, cnum;

  start = clock();                    //begin the clock
  Process (numbers,7,256,rnum,cnum);  //Finds row and column where the 7th 256 is found
  end = clock();                      //end the clock
 
  dif = (end - start)/(float) CLOCKS_PER_SEC;
  cout << "Amount of time to execute the function was " << dif  << "  seconds" << endl;

  cout << "The seventh 256 was found in row " << rnum << " and column " << cnum << endl;
}


This is the entire main function that I'm not allowed to modify. I'm supposed to return rnum and cnum so that they give the location in the array of seventh 256.

I was hoping that the size of the array would get passed with ROWS and COLS. But that doesn't seem to be the case?

clive

So how exactly does the array get initialized to have any content? At the moment it's on the local stack for main() containing whatever junk is on the stack at entry.

You could perhaps import the values in ROWS/COLS into the ASM code
It could be a random act of randomness. Those happen a lot as well.

magus841

I am initializing it and filling it in the asm code with integers.

Edit: Well no. lol. The array doesn't have any content before I call the Process function. I'm filling it in the function and then doing the search.

clive

CPP File
#include <windows.h>
#include <time.h>
#include <iostream.h>

extern "C" const int ROWS = 30, COLS = 100;

extern "C"{
    void Process(int numbers[ROWS][COLS], int which, int searchfor, int &rnum, int &cnum);
}

int main(void) {
  int numbers[ROWS][COLS];
  long int start, end;
  float dif;
  int rnum, cnum;

  start = clock();                    //begin the clock
  Process (numbers,7,256,rnum,cnum);  //Finds row and column where the 7th 256 is found
  end = clock();                      //end the clock

  dif = (end - start)/(float) CLOCKS_PER_SEC;
  cout << "Amount of time to execute the function was " << dif  << "  seconds" << endl;

  cout << "The seventh 256 was found in row " << rnum << " and column " << cnum << endl;

  return(0); // Need this
}


ASM File
        .386
        .MODEL FLAT, C

        EXTERNDEF ROWS:DWORD
        EXTERNDEF COLS:DWORD

        .CODE

Process PROC numbers:PTR DWORD, which:DWORD, searchfor:DWORD, rnum:PTR DWORD, cnum:PTR DWORD

        push    esi

; Initialize Array

        xor     eax,eax

        mov     esi,numbers

        mov     edx,ROWS

loop1:

        mov     ecx,COLS

loop2:

        mov     [esi],eax
        add     esi,4

        sub     ecx,1
        jnz     loop2

        sub     edx,1
        jnz     loop1

; Do your work here

; Put values in rnum/cnum

        mov     eax,ROWS
        mov     edx,rnum
        mov     [edx],eax

        mov     eax,COLS
        mov     edx,cnum
        mov     [edx],eax

; Leave

        pop     esi
        ret

Process ENDP

        END
It could be a random act of randomness. Those happen a lot as well.

qWord

not tested, but it could be something like this:
Process PROC C uses esi ebx pNumbers:ptr SDWORD,which:DWORD,searchfor:SDWORD,prnum:ptr DWORD,pcnum:ptr DWORD
LOCAL rnum:DWORD
LOCAL cnum:DWORD

mov eax,prnum
mov edx,pcnum
mov eax,[eax]
mov edx,[edx]
mov rnum,eax
mov cnum,edx

mov esi,pNumbers

xor eax,eax
xor ecx,ecx
.while eax < rnum
xor edx,edx
.while edx < cnum
mov ebx,SDWORD ptr [esi]
add esi,4
.if ebx == searchfor
inc ecx
.if ecx == which
mov ecx,prnum
mov esi,pcnum
mov [ecx],eax
mov [esi],edx
mov eax,1
ret
.endif
.endif
inc edx
.endw
inc eax
.endw
   xor eax,eax
   ret

Process ENDP
FPU in a trice: SmplMath
It's that simple!

Ossa

#7
Or how about the following? A bit harder to follow perhaps, but it might be a bit more efficient on the search:

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

extern "C" const int ROWS = 30, COLS = 100;

extern "C"{
    int Process(int numbers[ROWS][COLS], int which, int searchfor, int &rnum, int &cnum);
}

int main(void) {
  int numbers[ROWS][COLS];
  long int start, end;
  float dif;
  int rnum, cnum, i, j;

  for(i=0;i<ROWS;i++) for(j=0;j<COLS;j++) numbers[i][j] = 0x00;
  numbers[0][2] = 256;
  numbers[2][0] = 256;
  numbers[2][8] = 256;
  numbers[1][7] = 256;
  numbers[5][2] = 256;
  numbers[6][8] = 256;
  numbers[2][2] = 256;
  numbers[8][4] = 256;

  start = clock();                    //begin the clock
  i = Process (numbers,7,256,rnum,cnum);  //Finds row and column where the 7th 256 is found
  end = clock();                      //end the clock

  if(i==0) cout << "Failed" << endl;
  else {
    dif = (end - start)/(float) CLOCKS_PER_SEC;
    cout << "Amount of time to execute the function was " << dif  << "  seconds" << endl;

    cout << "The seventh 256 was found in row " << rnum << " and column " << cnum << endl;
  }

  return(0); // Need this
}



.386
.MODEL FLAT, C

EXTERNDEF ROWS:DWORD
EXTERNDEF COLS:DWORD

.CODE

Process PROC uses edi numbers:DWORD,which:DWORD,searchfor:DWORD,rnum:ptr DWORD,cnum:ptr DWORD
    ; Setup loop:
    ;   ecx = position counter
    ;   edx = match counter
    ;   edi = array pointer
    ;   eax = search term
   
    mov eax, ROWS
    mul COLS
    mov ecx, eax
    mov eax, searchfor
    mov edx, which
    mov edi, numbers
   
    ; Search loop
@@:
    repne scasd
    jne @F
    sub edx, 1
    jnz @B
   
    ; Found the correct value
    sub edi, numbers
    lea eax, [edi-4]
    shr eax, 2
    div COLS
    mov ecx, rnum
    mov [ecx], eax
    mov ecx, cnum
    mov [ecx], edx
    mov eax, 1
    ret
@@:

    ; Failed
    xor eax, eax
    ret
Process ENDP


[edit] Yeah, I did modify the main loop because i didn't want to confuse the asm for finding the value with that for filling the array... and I also didn't know how you need to fill the array. [/edit]
Website (very old): ossa.the-wot.co.uk