Click to See Complete Forum and Search --> : Comparing C++ Char's in Assembly, and working with arrays.


Vintage1983
November 17th, 2006, 04:44 AM
I am in my first semester of assembly on the intel 86x processor. Basicly I have been working on this problem and another for about two weeks and my book and net references haven't been able to help me out.

I have two basic problems I am dealing with right now. I am basicly traversing a array of strings (multi-dimensional array) and ordering the strings based on alpha-order. The array is made in C++ and being passed to my Assembly code in a .asm file. My .asm file will then sort the array. My first problem is I am having trouble understanding how to traverse a array while parameters are being passed after the array. To me it doesn't make sense that the reference to the array would be [ebp+8] and we normally would traverse the array by incrementing [ebp] but yet we can get the second parameter @ [ebp+12]. I've read about using OFFSET but i don't fully understand it. I can imagine how this could be used but I can't seem to figure it out.

My second issue is how to deal with the char data once I've brought it into my proc, I can't seem to find very much information related to Assembly and chars (assuming because they become ascii value?). Is a greater char (ex:T) always going to have a greater ascii value than a lesser char (ex: A).

This is my proc at the moment, I'm not so worried about traversing the array once I understand how to get the initial values as I have worked out the logic of this all before hand, just mostly looking for a decent example or clear instruction on how it works.


.386

.model flat

public _Sort

.data

zero word 0
switch word 0
array_length dword ?
found_length dword 0
char_position dword 0
bytes_per_line dword ?
holdover dword ?
POS1 dword ?
POS2 dword ?
array_addy dword ?

.code

_Sort proc

push ebp
mov ebp, esp
mov eax, [ebp+8]
mov array_addy, eax
mov eax, [ebp+12]
mov array_length, eax
mov eax, [ebp+16]
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

Tcolumns:
mov eax, char_position
mov ebx, bytes_per_line
cmp eax, ebx
jnb H1

mov ebx, OFFSET array_addy

add ebx, (found_length+1) ;getting second string
mov ecx, char_position
mov eax, [ebx + ecx]
push eax


H1:
; mov eax, found_length ;increasing found_length
; inc eax
; mov found_length, eax

; mov ebx, [ebp+8]
; mov ebx, OFFSET eax
; add ebx, (bytes_per_line*found_length)
; mov esi, 0
; mov ax, 0 ;to hold char1
; mox dx, 0 ;to hold char2




EndTrow:
pop ebp
ret
_Sort endp

end



This is the C++ code I have to work with...


extern "C" int Sort (char [] [20], int, int);

...

main...some code...

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


Any help is much appreciated, I have worn myself out playing with this stuff.

kahlinor
December 3rd, 2006, 03:34 AM
I have two basic problems I am dealing with right now. I am basicly traversing a array of strings (multi-dimensional array) and ordering the strings based on alpha-order.

My assumption is that you have an array of string pointers. On a 32 bit machine, each reference is 4 bytes long.

My first problem is I am having trouble understanding how to traverse a array while parameters are being passed after the array.

On a single dimension array, you traverse it by adding the element size to your current pointer. For an array of string pointers, this would be 4.


To me it doesn't make sense that the reference to the array would be [ebp+8] and we normally would traverse the array by incrementing [ebp]

No. You don't increment [EBP]. If [EBP+8] is the address of the array, then just move it into a base register (eg: ebx is good choice).

mov ebx, [EBP+8] ; ebx = starting address

From here, [ebx] is the first element. To get the next element, you add 4 to ebx. If you want to get the next element without changing the index;

eg:

mov ebx, [ebp+8]; ebx = address of array
mov eax, [ebx] ; eax = address of 1st string
mov ecx, [ebx+4] ; ecx = address of 2nd string in array
; call some function to compare strings by address
add ebx, 4 ; point ebx to the next element in the array
...

; if you want to use a base register and an index register:
mov eax, 0 ; eax is index register
mov ebx, [ebp+8] ; ebx is base register
mov ecx, [ebx+eax*4]; ecx = element # in eax



Using a base + index register allows you to use a method similar to what you would use in C.


but yet we can get the second parameter @ [ebp+12]. I've read about using OFFSET but i don't fully understand it. I can imagine how this could be used but I can't seem to figure it out.

I'm not too keen on MASM syntax, but I think OFFSET is for getting the address of automatic variables (variables declared as local in the proc). It won't help you here.

kahlinor
December 3rd, 2006, 03:54 AM
Anyway, just to give you an idea, here is some HLA code that displays an array of strings. As an exercise, translate it to your assembly syntax and it will give you something to work on. Remember, in HLA, source and destination operands are reversed!
So
mov (eax, ebx); in HLA is the same as

mov ebx, eax in your assembler.


program strarray;

#includeonce ("stdlib.hhf")

?@nodisplay := true;
?@noalignstack := true;

static
// form an array of strings
strs :string[] :=
[ "string one",
"string two",
"string three",
"string four" ];

procedure showStrs; @noframe;
begin showStrs;
push (ebp);
mov (esp, ebp);

mov ([ebp+12], ebx); // get address of array in ebx
mov ([ebp+8], ecx); // get number of elements in ecx

// for (i=0; i < ecx; i++)
xor (eax, eax); // eax is our index = 'i'
printStrs:
cmp (eax, ecx);
je done;
mov ([ebx+eax*4], edx);
pushd (edx);
call stdout.puts;
call stdout.newln;
inc (eax);
jmp printStrs;
done:

pop (ebp);
ret();
end showStrs;


begin strarray;

pushd (&strs); // push address of array
pushd (@elements (strs)); // push number of array elements
call showStrs;
add (8, esp); // balance the stack!

end strarray;