Now ... an array, with the size prefixed at assemble time ... followed by a dynamic array example, that uses dynamic memory, to allocate sufficient memory to hold an array of integers, with the max input size, specified by the user ... WHILE the program is running...
Note, the first program below, uses a constant to specify, at assemble time, the max array capacity. This constant value can be then easily changed to a larger value, (then reassemble your program with this new value), to accommodate a larger anticipated number of integers.
4.
// arrayInt.hla // // 2011-09-03 //
// enters integer data, finds sum, average, sorts, finds value, erase, shows
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program aryInt_demo;
#include( "stdlib.hhf" )
const
MAX_SIZE: uns32 := 4; // use small size here for simple testing purposes
type
//Aryi32: int32[MAX_SIZE];
pInt32: pointer to int32;
static
last: int32;
myAry: int32[MAX_SIZE]; // Aryi32;
pMyAry: pInt32 := &myAry;
count: uns32;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
procedure sumAry( pAry: pInt32; size:uns32 ); @nodisplay; @returns( "eax" );
begin sumAry;
push( ebx ); push( ecx );
mov( 0, eax );
mov( pMyAry, ebx );
mov( size, ecx );
for( dec(ecx) ; (type int32 ecx) >= 0; dec( ecx ) ) do
add( (type int32 [ebx + ecx*4]), eax );
endfor;
pop( ecx ); pop( ebx );
end sumAry;
procedure showAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin showAry;
push( ebx ); push( ecx );
mov( pAry, ebx );
for( mov( 0, ecx ); ecx < size; inc( ecx ) ) do
stdout.put( (type int32 [ebx + ecx*4]), " " );
endfor;
pop( ecx ); pop( ebx );
end showAry;
procedure isortAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin isortAry;
push( eax ); push( ebx ); push( ecx ); push( edx ); push( esi );
// int i, j, cmp;
mov( pAry, ebx );
// start with an array of just the first 2 elements (if exists)
for( mov( 1, ecx ); ecx < size; inc( ecx ) ) do
// get copy of this new cmp element on each outer loop
mov( [ebx+ecx*4], edx );
// get index of element just to the left of the above 'cmp'
// to start comparisons
mov( ecx, esi );
dec( esi );
while( (type int32 esi) >= 0 && (type int32 edx) < [ebx + esi*4] ) do
//ary[j+1] = ary[j]; // copy element 'up'
//--j; // decrement j in preparation for next inner loop
mov( [ebx + esi*4], eax );
inc( esi );
mov( eax, [ebx + esi*4] );
sub( 2, esi );
endwhile;
//insert element at index j+1 (since j was decremented above)
//ary[j+1] = cmp;
inc( esi );
mov( edx, [ebx+esi*4] );
endfor;
pop( esi ); pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end isortAry;
procedure findAry( pAry: pInt32; size:uns32; value: int32 );
@nodisplay; @returns( "eax" );
begin findAry;
push( ebx ); push( edx );
mov( value, edx );
mov( pAry, ebx );
for( mov( 0, eax ); eax < size; inc( eax ) ) do
if( (type int32 [ebx+eax*4]) == edx ) then break; endif;
endfor;
// check end condition ...
if( eax == size ) then mov( -1, eax ); endif;
pop( edx ); pop( ebx );
end findAry;
// if valid index erase element, return new size in eax ...
procedure eraseAry( pAry: pInt32; size:uns32; index: uns32 );
@nodisplay; @returns( "eax" );
begin eraseAry;
push( ebx ); push( edx );
mov( pAry, ebx );
mov( index, edx );
if( (type int32 edx) >= 0 && edx < size ) then
dec( size );
for( mov( index, eax ); eax < size; inc( eax ) ) do
// copy each element above, down one index, so erased
//ary[i] = ary[i+1];
inc( eax );
mov( (type int32 [ebx+eax*4]), edx );
dec( eax );
mov( edx, (type int32 [ebx+eax*4]) );
endfor;
else
dec( size );
stdout.put( nl "ERROR! Index ", index, " out of range 0..",
size, nl );
inc( size );
endif;
mov( size, eax ); // now update size and return (new - if updated) size...
pop( edx ); pop( ebx );
end eraseAry;
begin aryInt_demo;
mov( 0, ecx ); // using ecx as counter ...
repeat
// note: need to preserve/restore any reg's used when using
// try..endtry as in getValidInt below ...
push( ecx ); // preserve ecx
getValidInt( "Enter next value to sum: " ); // returns int32 in eax
pop( ecx ); // restore ecx
mov( eax, myAry[ecx*4] );
inc( ecx );
if( ecx == MAX_SIZE ) then
stdout.put( "You have reached ", MAX_SIZE, ", the max size.", nl );
break;
endif;
until( !more() );
mov( ecx, count ); // count now holds size of entered array ...
sumAry( pMyAry, count );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
stdout.puts( nl "showAry: " );
showAry( pMyAry, count );
//last = my_ary[ i-1 ];
dec( ecx );
mov( mov( myAry[ecx*4], eax ), last );
stdout.puts( nl "After isort..." nl );
isortAry( pMyAry, count );
stdout.puts( "showAry: " );
showAry( pMyAry, count );
findAry( pMyAry, count, last ); // index returned in eax ...
if( (type int32 eax) != -1 ) then // i.e. if found ...
eraseAry( pMyAry, count, eax ); // count holds size, eax holds index
mov( eax, count ); // update count ...
stdout.put( nl "After erasing ", last, "..." nl );
stdout.put( "showAry: " );
showAry( pMyAry, count );
else stdout.put( nl, last, " NOT found in myAry." nl );
endif;
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end aryInt_demo;
This next example program, uses a dynamic array, with max capacity specified by the user of the running program, when it first begins to run.
// dynamicAryInt.hla // // 2011-08-11 //
// enters integer data, finds sum, average, sorts, finds value, erase, shows
// http://developers-heaven.net/forum/index.php/topic,46.0.html
program dynamicAryInt;
#include( "stdlib.hhf" )
type
pInt32: pointer to int32;
static
last: int32;
pMyAry: pInt32;
maxSize:uns32;
count: uns32;
sum: int32 := 0;
avg: real32;
tmpStr: str.strvar( 32 );
procedure getValidInt( prompt: string ); @nodisplay; @returns( "eax" );
begin getValidInt;
forever
try
stdout.puts( prompt );
stdin.geti32(); // returns 32 bit integer in eax
stdin.flushInput();
unprotected
break;
exception( ex.ConversionError )
stdout.puts( "Invalid input! Integers only please ..." nl );
stdin.flushInput();
exception( ex.ValueOutOfRange )
stdout.puts( "Invalid input! Value out of range ... " nl );
stdin.flushInput();
endtry;
endfor;
end getValidInt;
// defaults to 'true' ... unless 'n' or 'N' entered
procedure more; @nodisplay; @returns( "al" );
begin more;
stdout.puts( "More (y/n) ? " );
stdin.getc();
stdin.flushInput();
chars.toLower( al );
if( al == 'n' ) then mov( false, al );
else mov( true, al );
endif;
end more;
procedure sumAry( pAry: pInt32; size:uns32 ); @nodisplay; @returns( "eax" );
begin sumAry;
push( ebx ); push( ecx );
mov( 0, eax );
mov( pMyAry, ebx );
mov( size, ecx );
for( dec(ecx) ; (type int32 ecx) >= 0; dec( ecx ) ) do
add( (type int32 [ebx + ecx*4]), eax );
endfor;
pop( ecx ); pop( ebx );
end sumAry;
procedure showAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin showAry;
push( ebx ); push( ecx );
mov( pAry, ebx );
for( mov( 0, ecx ); ecx < size; inc( ecx ) ) do
stdout.put( (type int32 [ebx + ecx*4]), " " );
endfor;
pop( ecx ); pop( ebx );
end showAry;
procedure isortAry( pAry: pInt32; size:uns32 ); @nodisplay;
begin isortAry;
push( eax ); push( ebx ); push( ecx ); push( edx ); push( esi );
// int i, j, cmp;
mov( pAry, ebx );
// start with an array of just the first 2 elements (if exists)
for( mov( 1, ecx ); ecx < size; inc( ecx ) ) do
// get copy of this new cmp element on each outer loop
mov( [ebx+ecx*4], edx );
// get index of element just to the left of the above 'cmp'
// to start comparisons
mov( ecx, esi );
dec( esi );
while( (type int32 esi) >= 0 && (type int32 edx) < [ebx + esi*4] ) do
//ary[j+1] = ary[j]; // copy element 'up'
//--j; // decrement j in preparation for next inner loop
mov( [ebx + esi*4], eax );
inc( esi );
mov( eax, [ebx + esi*4] );
sub( 2, esi );
endwhile;
//insert element at index j+1 (since j was decremented above)
//ary[j+1] = cmp;
inc( esi );
mov( edx, [ebx+esi*4] );
endfor;
pop( esi ); pop( edx ); pop( ecx ); pop( ebx ); pop( eax );
end isortAry;
procedure findAry( pAry: pInt32; size:uns32; value: int32 );
@nodisplay; @returns( "eax" );
begin findAry;
push( ebx ); push( edx );
mov( value, edx );
mov( pAry, ebx );
for( mov( 0, eax ); eax < size; inc( eax ) ) do
if( (type int32 [ebx+eax*4]) == edx ) then break; endif;
endfor;
// check end condition ...
if( eax == size ) then mov( -1, eax ); endif;
pop( edx ); pop( ebx );
end findAry;
// if valid index erase element, return new size in eax ...
procedure eraseAry( pAry: pInt32; size:uns32; index: uns32 );
@nodisplay; @returns( "eax" );
begin eraseAry;
push( ebx ); push( edx );
mov( pAry, ebx );
mov( index, edx );
if( (type int32 edx) >= 0 && edx < size ) then
dec( size );
for( mov( index, eax ); eax < size; inc( eax ) ) do
// copy each element above, down one index, so erased
//ary[i] = ary[i+1];
inc( eax );
mov( (type int32 [ebx+eax*4]), edx );
dec( eax );
mov( edx, (type int32 [ebx+eax*4]) );
endfor;
else
dec( size );
stdout.put( nl "ERROR! Index ", index, " out of range 0..",
size, nl );
inc( size );
endif;
mov( size, eax ); // now update size and return (new - if updated) size...
pop( edx ); pop( ebx );
end eraseAry;
begin dynamicAryInt;
getValidInt( "Max number of int's to input: " );
mov( eax, maxSize );
intmul( @size(int32), eax );
mem.alloc( eax );
mov( eax, pMyAry );
mov( pMyAry, ebx );
mov( 0, ecx ); // using ecx as counter ...
repeat
// note: need to preserve/restore any reg's used when using
// try..endtry as in getValidInt below ...
push( ecx );
getValidInt( "Enter next value to sum: " ); // returns int32 in eax
pop( ecx );
mov( pMyAry, ebx ); // restores ebx
mov( eax, [ebx+ecx*4] );
inc( ecx );
if( ecx == maxSize ) then
stdout.put( "You have reached ", maxSize, ", the max size.", nl );
break;
endif;
until( !more() );
mov( ecx, count ); // count now holds size of entered array ...
sumAry( pMyAry, count );
mov( eax, sum );
finit(); // initialize floating point (math) unit
fild( sum ); // float integer load
fild( count );
// With no operands, the FDIVP instruction pops ST0 and ST1,
// computes ST1/ST0, and pushes the result back onto the stack.
fdivp(); // find totScores / totOutOf and ...
// leave result on top of FPU stack (in st0)
fstp( avg ); // POP and store sto, the top of the FPU stack, into avg
stdout.put
(
"The average of ", count, " numbers with sum ", sum, " is "
);
conv.r32ToStr( avg, 20, 2, ' ', tmpStr );
str.delLeadingSpaces( tmpStr ); // to trim off any leading spaces ...
stdout.puts( tmpStr );
stdout.puts( nl "showAry: " );
showAry( pMyAry, count );
//last = my_ary[ i-1 ];
dec( ecx );
mov( pMyAry, ebx );
mov( mov( (type int32 [ebx+ecx*4]), eax ), last );
stdout.puts( nl "After isort..." nl );
isortAry( pMyAry, count );
stdout.puts( "showAry: " );
showAry( pMyAry, count );
findAry( pMyAry, count, last ); // index returned in eax ...
if( (type int32 eax) >= 0 ) then // i.e. if found ...
eraseAry( pMyAry, count, eax ); // count holds size, eax holds index
mov( eax, count ); // update count ...
stdout.put( nl "After erasing ", last, "..." nl );
stdout.put( "showAry: " );
showAry( pMyAry, count );
else stdout.put( nl, last, " NOT found in myAry." nl );
endif;
free( pMyAry );
stdout.put( nl "Press 'Enter' to continue/exit ... " );
stdin.readLn(); // keep 'Window' open until 'Enter' key is pressed
end dynamicAryInt;