...eax has decided to go into the stratosphere again.

In the code below:


mov(26,eax);
mov(3,lo); // put clerk in shop r#3
mov(27,eax);
mov(6,lo); // put villager at well r#6
mov(28,eax);
mov(14,lo); // put wolf at intersection r#14
mov(29,eax);
mov(30,lo); // put warrior at winding road r#30
mov(30,eax);
mov(20,lo); // put ghost in Redwood forest r#20
mov(31,eax);
mov(22,lo); // put goblin in Path r#22
mov(32,eax);
mov(27,lo); // put elf in Rolling Hills r#27
mov(33,eax);
mov(18,lo); // put hobbit in Grassroof hut r#18
mov(34,eax);
mov(10,lo); // put paladin in Village guild r#10
mov(35,eax);
mov(85,lo); // put skeleton in Caverns r#85
mov(36,eax);
mov(92,lo); // put vampire in Caverns r#92
mov(37,eax);
mov(94,lo); // put sorcerer in Caverns r#94
mov(38,eax);
mov(39,lo); // put dragon at Cave entrance r#39


I am assigning monsters in the game to various locations in the game. The locations of the monsters are being "Mov"ed into lo, a subscripted array variable.

They are then printed out to the screen like so:


// place noun#7
mov(7,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("lantern",nl);
endif;

// place noun#8
mov(8,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("oil",nl);
endif;

// place noun#9
mov(9,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("rope",nl);
endif;

// place noun#10
mov(10,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("key",nl);
endif;

// place noun#11
mov(11,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("bottle",nl);
endif;

// place noun#12
mov(12,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("dagger",nl);
endif;

// place noun#13
mov(13,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("sword",nl);
endif;

// place noun#14
mov(14,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("axe",nl);
endif;

// place noun#15
mov(15,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("scimitar",nl);
endif;

// place noun#16
mov(16,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("longsword",nl);
endif;

// place noun#17
mov(17,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("broadsword",nl);
endif;

// place noun#18
mov(18,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("battleaxe",nl);
endif;

// place noun#19
mov(19,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("cleaver",nl);
endif;

// place noun#20
mov(20,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("armor",nl);
endif;

// place noun#21
mov(21,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("shield",nl);
endif;

// place noun#22
mov(22,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("helmet",nl);
endif;

// place noun#23
mov(23,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("gauntlets",nl);
endif;

// place noun#24
mov(24,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("cloak",nl);
endif;

// place noun#25
mov(25,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("ring",nl);
endif;

// place noun#26
mov(26,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("clerk",nl);
endif;

// place noun#27
mov(27,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("villager",nl);
endif;

// place noun#28
mov(28,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("wolf",nl);
endif;

// place noun#29
mov(29,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("warrior",nl);
endif;

// place noun#30
mov(30,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("ghost",nl);
endif;

// place noun#31
mov(31,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("goblin",nl);
endif;

// place noun#32
mov(32,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("elf",nl);
endif;

// place noun#33
mov(33,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("hobbit",nl);
endif;

// place noun#34
mov(34,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("paladin",nl);
endif;

// place noun#35
mov(35,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("skeleton",nl);
endif;

// place noun#36
mov(36,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("vampire",nl);
endif;

// place noun#37
mov(37,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("sorcerer",nl);
endif;

// place noun#38
mov(38,ebx);
mov(lo,eax);
if(eax=r) then
console.setOutputAttr( win.fgnd_LightRed | win.bgnd_Black );
stdout.put("dragon",nl);
endif;


However, upon doing a stdout.put(lo[26],nl);
it prints out an out of range number for lo[26]:

43654543

or something like that. lo[26] should be 3, not 43654543:


mov(26,eax);
mov(3,lo); // put clerk in shop r#3


Any ideas as to what I'm doing wrong? :)

Sincerely,

Paul Panks
dunric@yahoo.com
Posted on 2003-05-07 14:14:14 by Paul Panks
It's the same problem that has plagued you're earlier code.
You're confusing 80x86 addressing modes with array indexes
in a high level language.

lo does *not* mean access the ebx-th element of array
"lo"; it means to access the ebx-th byte beyond the base
address of the "lo" array. Because each element is four bytes,
you're storing data into locations that overlap the elements
of your array.

I strongly recommend that you take a look at the following two
subjects:

http://webster.cs.ucr.edu/Page_AoAWin/HTML/MemoryAccessandOrg.html#999656

and

http://webster.cs.ucr.edu/Page_AoAWin/HTML/Arrays.html#1003722

You have a very fundamental misunderstanding of how arrays work
in assembly language programming. Several posters have given you
the code you need to correct your problems, but you don't seem to understand
the points they're making. Before you attempt another line of code on this
project, you need to stop and learn about how you define arrays in assembly
and how you access elements of those arrays.
Cheers,
Randy Hyde
Posted on 2003-05-07 20:52:59 by rhyde
Randy,

In a previous post you mentioned that I needed to multiply edx * 4 for dword int32 arrays. Does this hold true for my current situation as well? e.g. lo. From reading the material you suggested this would seem to also be the case.

Paul
Posted on 2003-05-07 22:26:52 by Paul Panks

Randy,

In a previous post you mentioned that I needed to multiply edx * 4 for dword int32 arrays. Does this hold true for my current situation as well? e.g. lo. From reading the material you suggested this would seem to also be the case.

Paul


Whenever you access *any* array element, you need to multiply the index by the size of the array element. The only time you multiply by one (that is, you leave the index alone) is when you access elements of a byte (char) array. In all other cases you must multiply by the size of the array element.
The 80x86 provides "scaled indexed addressing modes" that automatically multiply by four common sizes:
*1, *2, *4, and *8, e.g., m. For any other size you'll have to manually do the multiplication yourself (technically, this is not completely true. There are a couple of sizes you can do a multiplication by "cheating", specifically *3, *5, and *9 by using addressing modes like , , and ; however, *1, *2, *4, and *8 are, by far, the most common scaled index values).

BTW, this applies to constant indicies as well (if I haven't mentioned this already).
e.g.,

mov( 1, m[1]);

is *not* correct if m is a dword array.
This tells the CPU to access the memory location *one byte* beyond the address of the start of m.
If m is a dword array, then the second element (at index one) is four bytes beyond the start of m.

Generally when working with constants, you use the following type of code:

mov( 1, m[1*4] ); // This multiplication is all constants, so it can be done at compile time!
mov( 3, m[3*4] );
mov( 5, m[7*4] );
etc.

You could also type "mov( 1, m[4] );" and "mov( 3, [12] );" (etc.), but the explicit multiplication makes it clear that you are accessing elements of a dword array rather than elements of a byte array.

Cheers,
Randy Hyde
Posted on 2003-05-08 16:42:12 by rhyde
Hello Randy,

So to do the following:

mov(26,eax);
mov(3,lo); // put clerk in shop r#3

I need to go:

mov(26,edx)
mov(3,lo);

??

I just want to make element lo[26] store a value of 3 (placing noun #26, i.e. lo[26] in room #3 (3) )

In GW-BASIC or QBASIC this would mean:

lo(26)=3

when I would type:

PRINT lo(26)

the output should be:

3

And in HLA:

stdout.put(lo[26],nl);

the output needs to be:

3

(or "lo[26]:=3"; if I could do that instead);

Sorry if this is redundant. :)

Sincerely,

Paul Panks
dunric@yahoo.com
Posted on 2003-05-08 17:26:25 by Paul Panks