I keep getting a weird eax value for a room number in my in-progress HLA text adventure. Here is the link for the game:

http://panks.tripod.com/hlaadv.html

Download it, run it, and you'll see what I mean. I made sure to print out all relevant values when the player issues a "go <direction>" command (e.g. go north, go south, go east, etc.)

The game starts out in the village guild. Typing "go east" (based on the map: http://members.tripod.com/~panks/hlaadv.html) should place the player in the room with the village well. It does that, and you can go back to the guild via "go west", go any attempt to move north, south or east from the village well makes the destination room some crazy, out of bounds number like 657163. This is not a valid room number. If I attempt to go in any direction from this false room, the program then crashes with HLA Exception ($c000_0005) "Memory Access Violation".

The routine for the go verb (the command for how the player moves about the adventure) is in lines 1078 through 1089.

Any ideas as to what is causing eax to go wacky?

Here's the code for lines 1078 through 1089:

stdout.put(r,nl);
mov(r,eax);
imul(r);
stdout.put(r,nl);
add(s,eax);
mov(eax,r);
stdout.put(eax,nl);
if(m>0) then
mov(m,r);
stdout.put(r,nl);
jmp Room;
endif;

"jmp Room" just sends the program back to the routine for printing out the new room description.

Regards,

Paul Panks
dunric@yahoo.com
Posted on 2003-05-03 06:36:23 by Paul Panks

I keep getting a weird eax value for a room number in my in-progress HLA text adventure. Here is the link for the game:

http://panks.tripod.com/hlaadv.html

any attempt to move north, south or east from the village well makes the destination room some crazy, out of bounds number like 657163. This is not a valid room number.
Here's the code for lines 1078 through 1089:

stdout.put(r,nl);
mov(r,eax);
imul(r);
stdout.put(r,nl);
add(s,eax);
mov(eax,r);
stdout.put(eax,nl);
if(m>0) then
mov(m,r);
stdout.put(r,nl);
jmp Room;
endif;

"jmp Room" just sends the program back to the routine for printing out the new room description.

Regards,

Paul Panks
dunric@yahoo.com


mov(r,eax);
imul(r);

Computes r*r into EAX. Is this what you wanted?
Also, don't forget that imul wipes out the value in EDX -
hopefully it doesn't contain a value you want preserved.

If m is a multi-dimensional array that you want to access
as m then the computation you want is

(c*(size of row) + r) * (size of array element).
Cheers,
Randy Hyde
Posted on 2003-05-03 09:23:16 by rhyde
Randy,

Do I inset the mov(eax,r), imul(r) in a second time? Or are you suggesting the code is reversed of what I want? Does this fix it from crashing?

Paul
Posted on 2003-05-03 12:10:47 by Paul Panks

Randy,

Do I inset the mov(eax,r), imul(r) in a second time? Or are you suggesting the code is reversed of what I want? Does this fix it from crashing?

Paul

No, I was just commenting that your sequence produces r*r and you
probably want r*n where n is the number of columns.

The intmul instruction, btw, is perfect for computing array indexes.
Assuming n is a constant, you can compute r*n -> eax with a single
instruction, e.g.,

intmul( n, r, eax );

or, in your case,

intmul( 6, r, eax );

btw, HLA has a compile-time function you might be interested in using,
@dim that returns an array constant containing the bounds for each
dimension of the array (i.e., @dims(m) in your example would return the
array constant [42, 6]). You can use this to improve the maintainability
of your code as follows:

intmul( @dim(m)[1], 4, eax );

@dim(m) returns the array constant [42, 6] and the [1] subscript returns the
number of columns (i.e., the row size).

Along with the @elementSize compile-time function, you can make a completely
general array access using code like the following:




program t;
static
r :uns32;
c :uns32;
m :int32[ 42, 6 ];

begin t;

// Code to index into array m[ r, c ];

intmul( @dim(m)[1], r, eax );
add( c, eax );

// Must multiply by element size.
// Note that this isn't really necessary for int32
// objects as you can use the [eax*4] addressing mode
// instead, but this is the general solution.

intmul( @elementSize(m), eax );

// ebx = m[r,c];

mov( m[eax], ebx );


end t;



The cool thing about this code is that you can change the array dimensions and type
to your heart's content and the code will automatically work (with just a recompile)
with no other changes.

Cheers,
Randy Hyde
Posted on 2003-05-04 19:15:41 by rhyde
Randy,

I tried your example but for some reason I kept getting repeats (e.g. m[1*5] versus m[5*1]).

I then simplified the code as follows, and included the map portion in the same block of code. See: http://www.geocities.com/dunric/hlaadv.html for a map of the game):

verb1:
// room 1
mov(5,m[3]);
mov(2,m[6]);

// room 2
mov(4,m[7]);
mov(1,m[10]);

// room 3
mov(5,m[13]);

// room 4
mov(2,m[20]);

// room 5
mov(1,m[26]);
mov(6,m[27]);
mov(3,m[28]);
// room 6
mov(5,m[37]);
mov(11,m[38]);
mov(7,m[39]);
mov(10,m[40]);

// room 7
mov(8,m[50]);
mov(6,m[53]);

// room 8
mov(7,m[66]);
mov(9,m[67]);

// room 9
mov(8,m[85]);

// room 10
mov(6,m[103]);

// room 11
mov(6,m[122]);
mov(12,m[123]);

// room 12
mov(11,m[145]);
mov(13,m[146]);

// room 13
mov(12,m[170]);
mov(14,m[171]);

// room 14
mov(13,m[197]);
mov(28,m[198]);
mov(22,m[199]);
mov(29,m[200]);

// room 15
mov(19,m[227]);

// room 16
mov(20,m[258]);

// room 17
mov(18,m[292]);
mov(16,m[295]);

// room 18
mov(17,m[328]);

// room 19
mov(15,m[362]);
mov(22,m[363]);
mov(20,m[364]);

// room 20
mov(16,m[401]);
mov(23,m[402]);
mov(21,m[403]);
mov(19,m[404]);

// room 21
mov(20,m[445]);

// room 22
mov(19,m[485]);
mov(27,m[486]);
mov(23,m[487]);
mov(14,m[488]);

// room 23
mov(20,m[530]);
mov(26,m[531]);
mov(24,m[532]);
mov(22,m[533]);

// room 24
mov(23,m[580]);

// room 25
mov(26,m[629]);

// room 26
mov(23,m[677]);
mov(25,m[679]);

// room 27
mov(22,m[730]);

// room 28
mov(14,m[795]);

// room 29
mov(14,m[844]);
mov(30,m[845]);

// room 30
mov(29,m[903]);
mov(31,m[904]);

// room 31
mov(32,m[962]);
mov(30,m[964]);
mov(34,m[965]);

// room 32
mov(33,m[1025]);
mov(31,m[1026]);

// room 33
mov(32,m[1091]);

mov(r,eax);
imul(r);
add(s,eax);
stdout.put(m,nl);
if(m>0) then
mov(m,ebx);
mov(ebx,r);
stdout.put(r,nl);
jmp Room;
endif;

console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put( "You can't go that way!", nl);
jmp parse;

The code section:

mov(r,eax);
imul(r);
add(s,eax);
stdout.put(m,nl);
if(m>0) then
mov(m,ebx);
mov(ebx,r);
stdout.put(r,nl);
jmp Room;
endif;

Works going from Room#10 (the guild) to the village well (#6) but trying to go from the village well (#6) to Rooad (#5), inflates "r" to an impossible room number. Is there a reason this occurs? If m is greater than 0, then:

mov(m,ebx);
mov(ebx,r)
Jmp Room;

Any ideas? m is m ("r" is the current room number; "s" is 1 through 6, 1 for north, 2 for south, 3 for east, 4 for west, 5 for up and 6 for down).

Regards,

Paul Panks
dunric@yahoo.com
Posted on 2003-05-04 19:34:15 by Paul Panks

Randy,

I tried your example but for some reason I kept getting repeats (e.g. m[1*5] versus m[5*1]).

I then simplified the code as follows, and included the map portion in the same block of code. See: http://www.geocities.com/dunric/hlaadv.html for a map of the game):


Any ideas? m is m ("r" is the current room number; "s" is 1 through 6, 1 for north, 2 for south, 3 for east, 4 for west, 5 for up and 6 for down).

Regards,

Paul Panks
dunric@yahoo.com


1*5 and 5*1 should definitely not generate the same value for the row-major computation. Given this array:

m:dword[42,6];

Then the "rowsize" is 6 (six elements per row).

Row major computation to access element m is

r*rowsize+c.

IOW:

r*6+c

with r=1 and c=5 you should have

1*6+5 = 11

with r=5 and c=1 you should have

5*6+1 = 30

If you're getting the same result when swapping the value of r and c,
then your code sequence that does the row-major order computation
is incorrect.

I still argue that it's much better to use the HLA arrays module to
do this computation for you. Given *any* array you declare in HLA,
you can write

array.index( <some-32-bit-register>, arrayName, <<list of indexes>> );
and this will place the appropriate index into the register you specify.
So, for example, to access m you'd use code like the following:

array.index( ebx, m, r, c );

After this, ebx would point at the specified array element.
If m is an array of double words, you could access the array element
using code like this:

mov( , eax ); // Retrieve m into eax

-or-

mov( eax, ); // Store EAX away into m


If m is an array of some other type (let's say a structure of type "room") then
you could access that array element using code like this:

mov( (type room ).SomeFieldInRoom, eax );

The array.index code is actually a macro that is fairly smart and
generates decent code to access the array element. In some special
cases you can beat it by writing the code out manually, but most of the
time you shouldn't be afraid to use this macro from the HLA Standard Library.
It's so easy to use, and will save you all the headaches you're having,
I heartily recommend that you consider using it.
Cheers,
Randy Hyde
Posted on 2003-05-04 21:37:16 by rhyde
The code I wish to use is the following:
<code>
stdout.put(r,nl);
mov(r,eax);
imul(eax);
stdout.put(r,nl);
add(s,eax);
mov(eax,r);
stdout.put(eax,nl);
if(m>0) then
mov(m,r);
stdout.put(r,nl);
jmp Room;
endif;
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put( "You can't go that way!", nl);
jmp parse;
</code>

Let me explain what I am trying to do here.

I first move "r" (the current room number) into eax.
I then multiply eax by eax (value of r*r since "r" is in eax, so "imul(eax) )
I then add s to the value of eax (add (s,eax) )

This should be equivalent to the following (if I did the code correctly):

m

"s" is assigned a value earlier in the program based on what is entered for the noun. 1 for north, 2 for south, 3 for east, 4 for west, 5 for up, 6 for down.

Earlier in the program I set m to equal room numbers based on the values of room*room together, added to s. So in the case of moving from the guild (room #10) to the village well (Room #6), the following code should work:

m(10*10+3]:=6

or

m[103]:=6

"10" is the current room number (the guild), "3" is the direction (east) and "6" is the destination room (the village well).

I had to issue about 50 or 60 lines of mov(x,m) for it to work. You can download and view source code at: http://members.tripod.com/~panks/hlaadv.html

But when I do the code below:

<code>
stdout.put(r,nl);
mov(r,eax);
imul(eax);
stdout.put(r,nl);
add(s,eax);
mov(eax,r);
stdout.put(eax,nl);
if(m>0) then
mov(m,r);
stdout.put(r,nl);
jmp Room;
endif;
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put( "You can't go that way!", nl);
jmp parse;
</code>

I receive the following output:

Guild
You are standing in a large guild room. A large crescent flag
with a star emblazoned on it drapes down from the ceiling. A few
tables and chairs are here, as well as a large fireplace.
Exits: <east>
>go east
10
0000_0064
0000_0067
6
Village well
You are looking down on your reflection over a deep artisan
well. The water rises some 100 feet below ground level, and
the sides are green with moss.
Exits: <north,south,east,west>
>go north
6
0000_0024
0000_0025
168233733
>

It is the "168233733" which concerns me most. In the previous room:

Guild
You are standing in a large guild room. A large crescent flag
with a star emblazoned on it drapes down from the ceiling. A few
tables and chairs are here, as well as a large fireplace.
Exits: <east>
>go east
10
0000_0064
0000_0067
6
Village well
You are looking down on your reflection over a deep artisan
well. The water rises some 100 feet below ground level, and
the sides are green with moss.
Exits: <north,south,east,west>

The value of m[10*10+3] was equal to 6, and so the player moved to the village well. You can also move back from the well to the guild:

Village well
You are looking down on your reflection over a deep artisan
well. The water rises some 100 feet below ground level, and
the sides are green with moss.
Exits: <north,south,east,west>
>go west
6
0000_0024
0000_0028
10
Guild
You are standing in a large guild room. A large crescent flag
with a star emblazoned on it drapes down from the ceiling. A few
tables and chairs are here, as well as a large fireplace.
Exits: <east>
>

You might be wondering what "6","0000_0024" and other numbers mean. In my code below:

<code>
stdout.put(r,nl);
mov(r,eax);
imul(eax);
stdout.put(r,nl);
add(s,eax);
mov(eax,r);
stdout.put(eax,nl);
if(m>0) then
mov(m,r);
stdout.put(r,nl);
jmp Room;
endif;
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put( "You can't go that way!", nl);
jmp parse;
</code>

stdout.put(r,nl) is printing out the room location. Later on, "stdout.put(eax,nl) should be printing out the value results of "mov(r,eax); imul(eax); add(s,eax);".

What I'm trying to figure out is why a room number such as "168233733" is assigned to "r" when the player moves north from the village well:

6
Village well
You are looking down on your reflection over a deep artisan
well. The water rises some 100 feet below ground level, and
the sides are green with moss.
Exits: <north,south,east,west>
>go north
6
0000_0024
0000_0025
168233733
>

Sorry if this is terribly confusing. :)

Regards,

Paul Panks
dunric@yahoo.com
Posted on 2003-05-04 23:31:33 by Paul Panks
Paul, you should be using r*42+c (r * n + c) not r * r + c.

Where n is the total number of rows you have initialized the array for.
Posted on 2003-05-05 01:28:35 by V Coder
V Coder,

Yes, that is true. But it still doesn't explain the weird eax values. I can't seem to pinpoint why they occur from my code.

Paul
Posted on 2003-05-05 05:52:05 by Paul Panks

V Coder,

Yes, that is true. But it still doesn't explain the weird eax values. I can't seem to pinpoint why they occur from my code.

Paul


The weird values are almost certainly due to the fact that you're indexing the
array as though it were a byte array, but you're storing and retrieving dword
values. You need to use the edx*4 address mode when accessing elements
of a dword (int32) array.
Cheers,
Randy Hyde
Posted on 2003-05-06 22:45:59 by rhyde