Hello sorry to bother you again, but i'm experimenting with arrays, and this program behaves strangly, i have a 100 bye array and when i try to print out the data the first 40 bytes are blanks from array[0] to array[39]
Don't know what's wrong with the program, maybe you guys and gals could se what's wrong with this little program, here's the code.



// E TUTORMYSELF program from Zellennium
// This program is a way for me to learn how to acces arrays
// And do a strange counting on the stack wich i think nobody ever does
// but it's a way to learn i think maybe tha bad way but i learn.


program arraytest;

#include( "stdlib.hhf" )
const
dword_index:=10;
byte_index:=100;
static
// myArr : dword[index]:=[10,20,30,40,50,60,70,80,90,100];
myArr : dword[dword_index]:= 10 dup[0];
// to do
myArrBytes : char[byte_index]:= 100 dup ['W'];


begin arraytest;

stdout.put( "Hello, Lets do some DWORD ARRAYS counting and accessing", nl, nl );
stdout.put( "Press enter to continue: " ,nl,nl );
mov (@size(myArr),ecx); // get ARRAY size in bytes
// If all goes well @size wil give a total of 40 bytes
// so
shr (2,ecx); // ecx = ecx /4 (40/4) = 10


xor (eax,eax); // zero out eax use it as as counter
push (eax); // push it on the stack [esp+4]
push (esi); // save esi we are changing it [esp+8]

stdout.put("Data in ecx is ",(type int32 ecx),nl);
for ( mov ( 0,ebx ); ebx < dword_index; inc (ebx))
do
mov (myArr[ebx*4],edx);
stdout.put("data in Array [ ", (type int32 ebx)," ] = ", ( type int32 edx ),nl);
// maybe not the best counter ever but just experimenting with the stack

mov ([esp+4],esi); // setup eax on stack for counting
inc (esi); // increment ( eax stack) esi
mov (esi,[esp+4]); // put it back into stack location
endfor;

pop (esi); // get back saved register
pop (eax); // must contain counted data



stdout.put ("I have repeated myself ", (type uns32 eax ),nl);
stdout.put ("Press any key to continue with BYES ",nl,nl);
stdin.readLn();

//==================================================================
stdout.put( "Hello, Lets do this again but with bytes", nl, nl );
stdout.put( "Press enter to continue: " ,nl,nl );

mov (@size(myArrBytes),ecx); // get ARRAY size in bytes
// If all goes well @size wil give a total of 40 bytes
// so ecx wil be 100 bytes
// so we don't need shr instruction here


xor (eax,eax); // zero out eax use it as as counter
push (eax); // push it on the stack [esp+4]
push (esi); // save esi we are changing it [esp+8]

stdout.put("Data in ecx is ",(type int32 ecx),nl);
for ( mov ( 0,ebx ); ebx < byte_index; inc (ebx))
do
mov (myArr[ebx], edx); // things changes here no[ebx*4] because
// we have bytes now i bye remember

stdout.put("data in Array [ ", (type int32 ebx)," ] = ", ( type char dl ),nl);
// maybe not the best counter ever but just experimenting with the stack

mov ([esp+4],esi); // setup eax on stack for counting
inc (esi); // increment ( eax stack) esi
mov (esi,[esp+4]); // put it back into stack location
endfor;

pop (esi); // get back saved register
pop (eax); // must contain counted data



stdout.put ("I have repeated myself ", (type uns32 eax ),nl);
stdout.put ("Press any key to exit this program ",nl,nl);
stdin.readLn();


end arraytest;



Later.
Posted on 2004-12-15 05:27:33 by zellennium
Hi zellennium,
I notice a few things which I'll point out, there may be more problems with the code.

   stdout.put( "Hello, Lets do some DWORD ARRAYS counting and accessing", nl, nl );

stdout.put( "Press enter to continue: " ,nl,nl );


Does this really work? You need an stdin command somewhere.


  mov (@size(myArr),ecx);            // get ARRAY size in bytes

// If all goes well @size wil give a total of 40 bytes
// so
shr (2,ecx); // ecx = ecx /4 (40/4) = 10


Why do you do this? You don't even use ecx later.


xor   (eax,eax);                  // zero out eax use it as as counter

push (eax); // push it on the stack [esp+4]
push (esi); // save esi we are changing it [esp+8]


Whenever you push a value onto the stack, the system first decrements the esp register by the size of the pushed operand, then copies the value to the new memory location pointed to by esp.

As an example, if you push a dword (eax)

push (eax);

esp is subtracted by 4 and the value of eax is copied to .

Keep in mind that at any one time, the address contains the very last item you pushed.

push (eax); // eax =
push (esi ); // eax = , esi
push (ebx); // eax = , esi = , ebx =

and so on. Keep in mind that eax, esi and ebx in the comments are the original values that were pushed and not the registers themselves.

When you pop, the reverse happens:

pop (ebx); // eax = , esi =

Again, the comments indicate the original values that were in the registers.


  for ( mov ( 0,ebx ); ebx < byte_index; inc (ebx))

do
mov (myArr[ebx], edx); // things changes here no[ebx*4] because
// we have bytes now i bye remember

stdout.put("data in Array [ ", (type int32 ebx)," ] = ", ( type char dl ),nl);
// maybe not the best counter ever but just experimenting with the stack

mov ([esp+4],esi); // setup eax on stack for counting
inc (esi); // increment ( eax stack) esi
mov (esi,[esp+4]); // put it back into stack location
endfor;

pop (esi); // get back saved register
pop (eax); // must contain counted data


You are displaying the values of myArr which is initialized as 40 bytes of zeros. I think you want the information in myArrBytes.
Posted on 2004-12-15 21:59:13 by Kain
Hi zellennium,
I notice a few things which I'll point out, there may be more problems with the code.

   stdout.put( "Hello, Lets do some DWORD ARRAYS counting and accessing", nl, nl );

stdout.put( "Press enter to continue: " ,nl,nl );


Does this really work? You need an stdin command somewhere.


NO it doesn't
Hihi what was i thinking .??? FIXED IT thanks.



  mov (@size(myArr),ecx);            // get ARRAY size in bytes

// If all goes well @size wil give a total of 40 bytes
// so
shr (2,ecx); // ecx = ecx /4 (40/4) = 10


Why do you do this? You don't even use ecx later.



Really i don't know why i wasted bytes like this, sorry i really don't know
the only place where i used it was to print out the total bytes i got from @size devided true 4. :?



stdout.put( "Hello, Lets do some DWORD ARRAYS counting and accessing", nl, nl );
stdout.put( "Press enter to continue: " ,nl,nl );
//FIX:
stdin.readLn(); // FIX: This is needed here for above to work DUH
mov (@size(myArr),ecx);
// get ARRAY size in bytes
// If all goes well @size wil give a total of 40 bytes
// so
shr (2,ecx); // ecx = ecx /4 (40/4) = 10


xor (eax,eax); // zero out eax use it as as counter
push (eax); // push it on the stack [esp+4]
push (esi); // save esi we are changing it [esp+8]

// USED IT HERE stdout.put("Data in ecx is ",(type int32 ecx),nl);




xor   (eax,eax);                  // zero out eax use it as as counter

push (eax); // push it on the stack [esp+4]
push (esi); // save esi we are changing it [esp+8]


Whenever you push a value onto the stack, the system first decrements the esp register by the size of the pushed operand, then copies the value to the new memory location pointed to by esp.

As an example, if you push a dword (eax)

push (eax);

esp is subtracted by 4 and the value of eax is copied to .

Keep in mind that at any one time, the address contains the very last item you pushed.

push (eax); // eax =
push (esi ); // eax = , esi
push (ebx); // eax = , esi = , ebx =

and so on. Keep in mind that eax, esi and ebx in the comments are the original values that were pushed and not the registers themselves.

When you pop, the reverse happens:

pop (ebx); // eax = , esi =

Again, the comments indicate the original values that were in the registers.


Hmmm got to hit the books again going to fast maybe.





  for ( mov ( 0,ebx ); ebx < byte_index; inc (ebx))

do
mov (myArr[ebx], edx); // things changes here no[ebx*4] because
// we have bytes now i bye remember

stdout.put("data in Array [ ", (type int32 ebx)," ] = ", ( type char dl ),nl);
// maybe not the best counter ever but just experimenting with the stack

mov ([esp+4],esi); // setup eax on stack for counting
inc (esi); // increment ( eax stack) esi
mov (esi,[esp+4]); // put it back into stack location
endfor;

pop (esi); // get back saved register
pop (eax); // must contain counted data


You are displaying the values of myArr which is initialized as 40 bytes of zeros. I think you want the information in myArrBytes.


Yep fixed it :lol:
Posted on 2004-12-15 23:13:44 by zellennium

   push   (eax);                  // push it on the stack [esp+4]

push (esi); // save esi we are changing it [esp+8]


Hmmm got to hit the books again going to fast maybe.


One more comment I should add to this. It seems that you are using the push opcode to build automatic variables on the stack. You shouldn't do it this way as it will create confusion. Here is a better way:

sub (8, esp) ; // reserve 8 bytes of space on the stack.

// now you have 2 dwords accessed as

mov ( <somedwordvalue>, ); // this is your 1st 4-byte var object
mov ( <anotherdwordvalue>, ); // this is your 2nd 4-byte var object

But you must be careful not to push or pop other data on the stack or you will lose your pointer. If you wish to preserve your pointer, the ebp register is perfect for this (this is described in the section on low-level procedures).
Posted on 2004-12-15 23:29:53 by Kain