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.
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
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?
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
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.
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
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
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]