I just started writing in HLA about two weeks ago. I've found it simple and intuitive for the most part.
However, I come from VB world (that and another high-level script language are what I use at work). That means no pointers (without undocumented function hacks or API tricks anyway).
So, needless to say, my question has a lot to do with pointers I think.

I'm trying to build a snippet that creates a dynamic array of strings, fills each index with a unique string, loops through the array to edit each string (say, takes out the 2nd character or something trivial - I'm pretty strong on string manipulation), and then outputs each element.

BTW, I'm using Arrays.hhf, and Strings.hhf.

I'll happily post what I have in this snippet if anyone asks, but I'd rather see it done right than have what's wrong patched. I've learned everything I know about programming from studying other people's source first and foremost.

To Randall Hyde:
Thank you for all of the work you've put in on this project, I wish I'd had HLA available to me when I started coding, I wouldn't have gotten trapped in VB land.
Posted on 2004-09-16 19:11:11 by ChupaThingy
This is probably not what you want, but this is more of a low-level dynamic array: a linked list of string pointer objects:



program dStr;
#include("stdlib.hhf")

type
dString:record
string_ptr :string;
next :pointer to dString;
endrecord;

static
base_ptr :pointer to dString;

const
stresi :text:="(type dString[esi])";

begin dStr;
// create the first object
// allocate memory for the object, and a string of 100 chars
mem.alloc(@size(dString));
mov(eax,base_ptr);
mov(eax,esi);
mov(NULL,stresi.next);
str.alloc(100);
mov(eax,stresi.string_ptr);

//let's add 9 more string objects
mov(9,ecx);
_loop:
call _addStringObject;
dec(ecx);
jnz _loop;

// manipulate the string objects
mov(base_ptr,esi); // recover the 1st string object
mov(1,ecx);
_strloop:
str.put(stresi.string_ptr,"String #",(type uns32 ecx));
inc(ecx);
mov(stresi.next,esi);
cmp(esi,0);
jne _strloop;

// display our string objects to stdout
mov(base_ptr,esi);
_displayloop:
stdout.put(stresi.string_ptr,nl);
mov(stresi.next,esi);
cmp(esi,0);
jne _displayloop;

// done, call cleanup, this is probably not necessary, but I
// always try to cleanup before quitting
call _cleanUp;
jmp _end;

// procedures =========================
_addStringObject:
mem.alloc(@size(dString));
mov(eax,stresi.next);
mov(eax,esi);
mov(NULL,stresi.next);
str.alloc(100);
mov(eax,stresi.string_ptr);
ret();

_cleanUp:
mov(base_ptr,esi);
_cleanloop:
str.free(stresi.string_ptr);
mov(stresi.next,ebx);
mem.free(esi);
cmp(ebx,0);
je _endcleanup;
mov(ebx,esi);
jmp _cleanloop;
_endcleanup:
ret();
//=========================================
_end:
end dStr;


This program displays 10 strings (of 100 max. characters each) labled "String #1" to "String #10" that are dynamically created.
You can add more features to the record, such as the total number of strings, a "prev" pointer, etc.

Other improvements could be made to the _addStringObject procedure such as feeding it a paramter for variable-length strings for each object.
Posted on 2004-09-17 02:00:49 by Kain
This is probably not what you want, but this is more of a low-level dynamic array: a linked list of string pointer objects:


That does exactly what I asked, it's possibly more than I need though. I'll have to study it a bit to figure out what's going on (I'm still new at this).

I was looking more for a very simple example type snippet. Thank you for this, hopefully I'll be able to learn what I'm missing.
Posted on 2004-09-17 02:10:36 by ChupaThingy
No problem :)

If you want a more detailed explanation of any portion, let me know, I'll get back to you next time I'm online.

Keep in mind that this is only one of many ways to do this. My guess is that it would be easier to use arrays.hhf for a more high-level feel, but as I've never made use of it, I can't help you with it.
Posted on 2004-09-17 02:24:28 by Kain
Thanks for your help. I was trying to use arrays.hhf. After I picked apart your example (and re-read, and re-read, etc) the sections in AoA on addressing modes I finally got it. It's not pretty, and it's about as un-assembly like as it can be I'm sure, but I think I finally understand the concept behind it.

Here it is in any case just in case someone else might find it useful (and for anyone to offer criticism on how I'm doing things... no optimizations though, I've always worried about making code tight, small, and fast after I've mastered the concepts, any advice will be saved away for later weeks and years though)




Index:dword;
Elements:dword;
sHeapString:string;
pArray:dword;

. . . .

mov( 0, Index ); // Initialize the Index Counter

mov( 2, Elements ); // Determine the number of elements we want
mov( 2, ECX ); // note that realloc can grow this later

intmul( @size(dword), ECX ); // determine how much space is needed for ECX elements
malloc( ECX ); // allocate the space
mov( EAX, pArray ); // save the address of the allocated space

for( mov( 0, ECX ); ECX < Elements; inc( ECX ) ) do

stralloc( 32 ); // allocate space for the string
mov( EAX, sHeapString ); // save the address of the allocated space

str.cpy( "This should be element ", sHeapString ); // put something into the string
str.cati32( ECX, sHeapString );

mov( sHeapString, EAX ); // move the string's address into EAX
mov( pArray, EBX ); // move the array's address into EBX
mov( EAX, [ EBX + ECX * 4 ] ); // Store the string into the array?
// The above should be: Base_Address + Index * Element_Size


// replace a bit of the string directly in the array
// This is just to test that everything's working
// I tend to over-use debug output statements
str.index( [EBX + ECX * 4], "should be" );
if( (type int32 EAX) > 0 ) then
str.delete( [EBX + ECX * 4], EAX, 9 );
str.insert( "is", [EBX + ECX * 4], 5 );
endif;

endfor;

// clean up everything
mov( Elements, EDX );
mov( pArray, EBX );
for( mov( Index, ECX ); ECX < EDX; inc( ECX ) ) do
if ( (type dword [EBX + ECX * 4]) > 0 ) then
strfree( [EBX + ECX * 4] );
dbg.put( "Index ", (type int32 ECX), " freed", ", Address = ", (type int32 [EBX + ECX * 4]) );
endif;
endfor;

free( pArray );
Posted on 2004-09-17 06:37:48 by ChupaThingy
Looks pretty good at first glance. The only suggestion I can give at this time is to discontinue use of the depricated functions: stralloc, strfree, malloc and free.

Instead use the new functions in the mem and str namespaces: str.alloc, str.free, mem.alloc and mem.free

Much of what you have done here can also be done with arrays.hhf with the added advantage of allowing you to use indexed addressing mode. Missing this ability is not a big deal however as it can be done by register indirect addressing.
Posted on 2004-09-17 20:26:20 by Kain
Looks pretty good at first glance. The only suggestion I can give at this time is to discontinue use of the depricated functions: stralloc, strfree, malloc and free.


I didn't know they were deprecated. I was just following the docs (AoA mostly). I'll update it, thanks.

Much of what you have done here can also be done with arrays.hhf with the added advantage of allowing you to use indexed addressing mode. Missing this ability is not a big deal however as it can be done by register indirect addressing.


As my first post pointed out, I was trying with arrays.hhf but I couldn't seem to get it to work. I was really hoping to build the arrays in as high-level a manner as possible.

If you would be willing to update the snippet above to use arrays.hhf I'd be forever in your debt. I can't seem to get it working properly and have had even less luck finding a snippet or example to follow.
Posted on 2004-09-18 00:44:07 by ChupaThingy
:-D Somehow I knew no one would fix my code above and hand me the answer I was looking for. I had to try though (MTV generation and all). Anyway, I think I've figured it out (it compiles, and runs, and does what I want). There's just one problem. I get a slew of errors when using array.element macro:

(Version I'm using:
HLAParse Version 1.70 build 9367 (prototype)
MASM Version 6.14.8444)

Error in file "arrays.hhf" at line 239 :
Macro called in file "Src\ArrTest.hla" at line 70
Undefined symbol.
Near: << code >>

Anyone seen this before? I'll be more than happy to post the whole bit of code if needed.
Posted on 2004-09-19 12:50:20 by ChupaThingy

:-D Somehow I knew no one would fix my code above and hand me the answer I was looking for. I had to try though (MTV generation and all).


Hehe. As I mentioned earlier, I've never used arrays.hhf so I would'nt be able to help you on it.
Anyway, I did look through it and I didn't find a function to increase the size of your array once it was created... though I suppose you could create a new larger array and copy the original array into it.


Anyone seen this before? I'll be more than happy to post the whole bit of code if needed.


Please do.
Posted on 2004-09-19 17:02:20 by Kain


/************************************************************
*** This program requires a textfile containing two lines
*** I used:
*** key1=value1
*** key2=value2
************************************************************/

program Arrays;
#include( "stdlib.hhf" );
#include( "arrays.hhf" );
#include( "strings.hhf" );
#include( "fileio.hhf" );

var
aK_V: array.dArray( string, 2 );
hFile:dword;

nIndex:dword;

sReadLine:string;
sKey:string;
sValue:string;

Row:dword;
Col:dword;

begin Arrays;

fileio.open ( "C:\test.txt", fileio.r );
mov( EAX, hFile );

array.daAlloc( aK_V, 2, 3 );

mov( 0, nIndex );

repeat
fileio.a_gets( hFile );
mov( EAX, sReadLine );

str.index( sReadLine, "=" );
mov( EAX, EBX );
if( (type int32 EAX) >= 0 ) then
str.a_substr( sReadLine, 0, EBX );
mov( EAX, sKey );
add( 1, EBX );
str.length( sReadLine );
sub( EBX, EAX );
str.a_substr( sReadLine, EBX, EAX );
mov( EAX, sValue );

array.index( EDX, aK_V, nIndex, 0 );
mov( sKey, [EDX] );

array.index( EDX, aK_V, nIndex, 1 );
mov( sValue, [EDX] );

add( 1, nIndex );
endif;
until ( fileio.eof( hFile ) );

fileio.close( hFile );

fileio.openNew( "c:\Keys.txt" );
fileio.close( EAX );

// fileio.a gives Undefined symbol Near: << .a >>
// all others (.w, .wr, .r) work
fileio.open( "c:\Keys.txt", fileio.w );
mov( EAX, hFile );

mov( nIndex, EBX );

/************************************************************
*** trying to use array.element gives me these errors with
*** HLAParse Version 1.70 build 9367 (prototype)
*** MASM Version 6.14.8444
Error in file "arrays.hhf" at line 239 [errid:41348/hlaparse.bsn]:
Macro called in file "Src\ArrTest.hla" at line 70
Undefined symbol.
Near: << code >>

Error in file "arrays.hhf" at line 239 [errid:58249/hlaparse.bsn]:
Macro called in file "Src\ArrTest.hla" at line 70
Constant is not allowed as parameter here.
Near: << ( >>

Error in file "arrays.hhf" at line 239 [errid:58078/hlaparse.bsn]:
Macro called in file "Src\ArrTest.hla" at line 70
Too few actual parameters.
Near: << ( >>

Error in file "arrays.hhf" at line 239 [errid:3277/hlaparse.bsn]:
Macro called in file "Src\ArrTest.hla" at line 70
Expected ')', encountered '('.
Near: << ( >>

Error in file "arrays.hhf" at line 239 [errid:75381/hlaparse.bsn]:
Macro called in file "Src\ArrTest.hla" at line 70
Expected 'do'.
Near: << ( >>

foreach array.element( aK_V ) do
fileio.puts( hFile, [EAX] );
strfree( [EAX] );
endfor;
*/

for( mov( 0, Row ); Row < EBX; add( 1, Row ) ) do
for( mov( 0, Col ); Col < EBX; add( 1, Col ) ) do
array.index( EDX, aK_V, Row, Col );
fileio.puts( hFile, [EDX] );
endfor;

fileio.puts( hFile, nl );
endfor;

fileio.close( hFile );

array.daFree( aK_V );
end Arrays;
Posted on 2004-09-19 19:20:53 by ChupaThingy
There is an error in arrays.hhf, I'll inform Mr. Hyde, if he hasn't already seen this.
Posted on 2004-09-19 20:25:22 by Kain
There is an error in arrays.hhf, I'll inform Mr. Hyde, if he hasn't already seen this.


Oh good (well, not good, but... never mind). At least it isn't something I'm doing wrong.

By the way, thank you for HIDE. Aside from a few random crashes with no error message it's the best IDE I've found for HLA.

Is it still being worked on or have you moved over to other projects?
Posted on 2004-09-19 21:31:39 by ChupaThingy
There is an error in arrays.hhf, I'll inform Mr. Hyde, if he hasn't already seen this.


This is new, and has been fixed for the HLA v1.71 release (whenever that will be).

In the mean time, replace

code( --- )
by
#{ --- }

and you should be in business.
Cheers,
Randy Hyde
Posted on 2004-09-20 10:28:50 by rhyde


By the way, thank you for HIDE. Aside from a few random crashes with no error message it's the best IDE I've found for HLA.

Is it still being worked on or have you moved over to other projects?


Thanks. I'm still developing HIDE (a new version should be due in about a week). Can you explain more of what you were doing just before the crashes (and what OS version)?
Posted on 2004-09-20 21:39:13 by Kain
It's always when I build or save while the code window is dirty. Strange thing is, if I open HIDE back up again, make the exact same changes (only way I can be sure of that statement is there are times I've just uncommented or commented a line or changed one variable name) and repeat the same previous action (build or save via hotkey or menu, it doesn't matter) it'll usually (70-80%) crash a second time, maybe even a third. The third is less likely (maybe only 25-30%).

I'm on XP sp1. Doesn't matter which compiler I'm using (has happened both with the fasm it comes with and the masm I posted stats to above). I don't remember right now which version of HIDE it is, I d/l'd it sometime during the last week though. If you need it I can find out.

I've started (just the night before last so there's not much there yet) keeping track of exactly what I did prior to the crash (in my wish list file for HIDE :-D ). The error is always "Unhandled exception". I have yet to re-install Olly (just got a new HD) so I can't tell you where it's happening. Maybe I'll start running it through there though. I get 3-4 of these crashes a night. Fortunately, I save pretty religiously so it hasn't been a big deal (that and I know it's not release code).
Posted on 2004-09-21 06:03:53 by ChupaThingy
When the crashes happen, are you working with or without projects (it helps to isolate the problem area)?
Posted on 2004-09-21 15:57:54 by Kain
With projects. I havn't not worked with them yet. Even when I don't really need to (i.e. little snippets of one source file). Another thing that increases the chances of a crash are if I open a file but not add it to the project and build while it's open (such as one of the .hhf files or a source file from another project that has a snippet I want).
Posted on 2004-09-21 21:36:25 by ChupaThingy