I've been studying assemby for about a semester now. I am having a horrible time figuring out how to access the data I pass from C++ to ASM. The data is a array of strings which I will have to sort in ASM and return a sorted array back to C++. The biggest problem I am having is accessing the data itself. The array is being passed at ... Any help with this is appreciated.

This is the C++ code I'm working with;
extern "C" int Sort (char [] [20], int, int);

	Sort (Strings, 10, 20);
cout << "Sorted Strings are" << endl;
for (i = 0; i < 10; i++)
cout << '\t' << Strings << endl;

You can probably ignore my code, but I figure I would put it anyways;
_Sort proc

push ebp
mov ebp, esp
push edi

mov eax,
mov array_ptr, eax
mov eax,
mov array_length, eax
mov eax,
mov bytes_per_line, eax

mov eax, array_length
cmp eax, 0 ;jump if array has length of 0
jnae EndTRow

mov ebx, found_length
inc ebx ;add 1 to found_length's sum
cmp ebx, eax ;jump if at last row
ja EndTrow
; mov found_length, ebx

mov eax, char_position
mov ebx, bytes_per_line
cmp eax, ebx
jnb TRows

... ...and it becomes useless jargon here

pop edi
pop ebp
_Sort endp

Posted on 2006-11-26 23:17:26 by of1983vintage
The biggest problem you're going to have is that you should be sorting your strings into a temporary buffer..
This avoids trashing of the source buffer during sorting.
After sorting, you can simply overwrite the source buffer with the temporary one in order to return the sorted array in the input buffer.

Unless you know EXACTLY what you're doing with ebp and esp, I'd leave them alone .. the assembler can insert them for you :)

Here's a typical asm procedure.. note that the input params at ebp+8,12,16 are equivalent to your first three input params ;)

Sort proc uses esi edi ecx lpStrings:dword,cbSizeTotal:dword,dwBytes_per_line:dword
LOCAL array_length
; Let the assembler set up the stackframe for us
; push ebp
; mov ebp, esp

push edi
mov esi, lpStrings
xor ecx,ecx
.while ecx<cbSizeTotal
push ecx
;Perform sort operation here..
pop ecx
inc ecx
pop edi
; ;Let the assembler clean up the stackframe for us
; pop ebp
Sort endp

Posted on 2006-11-27 00:38:50 by Homer
I appreciate your response but I still don't know how to access the information inside of the array, I tried to run your code and its telling me...
Assembling: .\Lab9.asm
.\Lab9.asm(26) : error A2119: language type must be specified
Project : error PRJ0019: A tool returned an error code from "Assembling..."

line 26 is where your intiail line for the proc is.
Sort proc uses esi edi ecx lpStrings:dword,cbSizeTotal:dword,dwBytes_per_line:dword

I see that you are storing the edi and ecx registers, I'm assuming because most string compare functions use those for the strings, string length, and then use cx (ecx) as a counter...but how do i get it from the address or in your examples case lpStrings (I think) to using the string itself. Sorry Im having a horrible time with this...I've done excellent in the class until this.
Posted on 2006-11-27 09:27:12 by of1983vintage
points to the start of your buffer

A simple way to process each character is to write:

.model flat, c

Sort proc Strings:ptr byte, nb_row:dword, nb_col:dword
p textequ <eax>
i textequ <ecx>
j textequ <edx>
  cmp nb_col, 0
  je  Done
  mov p, Strings
  mov i, nb_row
  jmp RowT
  mov j, nb_col
  ; ... process
  inc p
  dec j
  jnz TCol
  dec i
  jge TRow
Sort endp


if needed reassign p, i, j, etc. to memory location (registers are better of course)

To process each character sequentially (argument checking omitted) :

Sort proc Strings:ptr byte, nb_row:dword, nb_col:dword
p textequ <eax>
p_limit textequ <ecx>
  mov p, Strings
  mov p_limit, p
  add p_limit, nb_row
  add p_limit, nb_col
  ; process
  mov dl,
  inc p
  cmp p, p_limit
  jnz TChar
Sort endp

You can also use a negative index to save a test

Sort proc Strings:ptr byte, nb_row:dword, nb_col:dword
p textequ <eax>
i_neg textequ <ecx>
  mov p, Strings
  mov i_neg, nb_row
  add i_neg, nb_col
  add p, i_neg
  neg i_neg
  ; process
  mov dl,
  inc i_neg
  jnz TChar
Sort endp

The Art Of Assembly Language has a chapter on array access:

Posted on 2006-11-27 12:34:41 by Dr. Manhattan
Thank you for the clarification, I am at work right now but will try it out again as soon as I get back to my house. I've read a number of different chapters about accessing arrays in assembly from different books and resources but none have really been much help for this problem at hand. I am probably making it more difficult than it really is, as everyhting is assembly has came to me easily until now...

From what I see, I need a pointer to the address of the array, mov the pointer to a register and then use the newly assigned register to navigate the array?

mov eax, dword ptr ; you guys are using the proc to pull the variables instead of addressing them yourself.
mov ebx,

if I wanted the X column and Y charater it would be
(rows being 20 bytes long, using dword's @ 4 bytes each, so a 5 elements per row)

mov ebx,

mov ecx, ;mov value derived from  (row*20)+(column*4) in ecx
mov ebx,

ebx would then be the char located at that position?

Am I understanding this correctly? The only difference between traversing the array normally and doing so with the array coming from the C++ program is the initial pointer to the array? This is all still theory to me, since I am not at home I can't test any of this.
Posted on 2006-11-27 16:24:55 by of1983vintage
In a rectangular array, arrij is located at

arr_base + i*row_byte_size + j*element_byte_size
= arr_base + i*column_declared_size*element_byte_size + j*element_byte_size

If row size is 20 bytes, why do you believe the element (char) size is 4 bytes ?

Have you looked at All About Arrays?
Posted on 2006-11-27 19:19:27 by tenkey
Well I've been reading Assembly Language For Intel-Based Computers - Fourth Edition by Kip R. Irvine, plus looking at anything that googles up from "Assembly Array" "Passing Array" and so on... But I will read your link here in a bit...

The reason I think that the element is 4 bytes is it is a dword, and the fact that I know what Im looking at as far as the array to be proccessed...but now after looking at the data defining section again I think i might be completely off with the assumption of the element being 4 bits (now im nto sure where I even came up with that at initially, probably some late night experiment that just held over. From my book it looks like a dword is 32 bit unsigned, so... in a couple hours I'll have to dig in again and see what I can come up with...Thanks for your comments and such guys... I'll be back in about 2 hours to start coding again.

The array I am looking at is...

	char Strings [10] [20]
= { "One",
"Ten" };

(maybe I got the 4 from this; Max elements is 5 -> bits per row = 20 -> 20/5=4 -> each element in row = 4bits)
Completely wrong probably but thats the only explanation I can come up with right now...
Posted on 2006-11-27 20:04:38 by of1983vintage
This is supposed to be spelled out somewhere in your C++ documentation. (Maybe I ought to start recommending the Kernighan & Ritchie book The C Programming Language, if it's still in print.)

The C++ array is the same as a C array. If you use two pairs of [], then it is a rectangular matrix (or array of arrays), not an array of pointers. Each element in the matrix is a char according to your C++ declaration.

Therefore, in reality, you are defining a 10 row by 20 column char matrix.

To the compiler, an array name is a pointer value, not an array object (except when used with the sizeof operator).

This ought to point you to the correct solution.
Posted on 2006-11-30 16:12:08 by tenkey
yup, C syntax is pretty messy with arrays
Posted on 2006-11-30 19:40:38 by vid
Thanks for the help, in actuality I was accessing them correctly, I just had then as dwords instead of as bytes so I didn't know I had already begun traversing the array...only problem Im having now is exchanging the data between the positions in the array. I keep copying one of them into the others position but then i've lost the second string.
Posted on 2006-11-30 21:11:56 by of1983vintage