News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

array element addressing

Started by redskull, March 09, 2006, 04:57:54 AM

Previous topic - Next topic

redskull

Can anybody lay down the array referencing laws?  For example, array[ax] will spit out an error that it has to be either base or index register, however array[bx] will compile and crash the program but array[ebx] seems to work fine.  Also I seem to have very little luck with using array[8bitmemory].  Do all array element references have to be 32-bits?

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Tedd

It's a good idea to use 32-bit registers for indexing, mainly because the numerical addresses they refer to will be 32-bit numbers. This has more to do with the way programs are loaded by windows - e.g. if your array is at 401000h then trying to access it at 1000h is obviously the wrong address. This will cause an exception because the memory at 1000h is not yours.
That doesn't mean, however, that you can't access a single byte at an address (mov al,[blah])

When you access an array from a high-level language, you usually do something like myarray[10] - what this really means is 'the memory at myarray + 10'. So in asm, you have to do this directly (base = OFFSET myarray, index = 10)
No snowflake in an avalanche feels responsible.

redskull

I was under the impression that array brackets were synonymous with a + operator..for example:

if array is at 401000h, and bl=8, then array[bl] would be array+bl and refer to 401008h?  The assembler has no problem with that instruction, but the program always crashes. :'(

thanks again for the help
alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

zooba

As far as I know, all element references have to be 32-bits. This may require a 16-bit expert but my guess is that [bx] is valid for 16-bit programs but [ebx] is required for 32-bits. Also, you can't use a memory address and a memory value in the same array reference - the value must be moved into a 32-bit register first.

Hope this helps,

Zooba :U

ChrisLeslie

I would say that you need to read the general register rules for array adressing. Hutch's Help file "Introduction to 32bit Assember" section - Effective Addressing, will provide usefull information about that.

Chris

Tedd

There's possibly some detail missing here - you want to post some code?
At least then we can see why it's crashing :wink
No snowflake in an avalanche feels responsible.

redskull

no need to post code, problem is fixed.  Ironically, using non 32-bit addresses wasn't the only problem; it turns out that a .REPEAT/.UNTILCXZ uses ECX for a counter, not just CX.  D'oh!

While we're sort of on the subject, i've heard lots of unconfirmed rumors that it's better to have all your data structures 32-bits and waste the extra memory for a huge gain in speed (and in this case, less bugs :red:).   Is that 'aligning'?  Is it a better idea than using the smallest amount of memory possible?

As always, infinite thanks for indulging my ignorance.

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

AsmER

#7
The secret of working with arrays is not very difficult:
-for arrays definied like MyArray   BYTE 20 dup(?) scheme of calculating position is:
MyArray [ (BX or BP) or (SI or DI) or DIGIT ]
i.e:
mov   al, variable_name[ 2 ]
mov   al, variable_name[ bx + si +18 ]


-If you have got array 'MyArray' and its size is for example 50x100 and you want to calculate value of Array[25][4]
you must do following calculations:
MyArray[ ( 25 * one_row_length + 4 ) * one_array_element_size ]
i.e:
(if MyArray is definied as WORD array)
; mov AX to MyArray[25][4]
mov MyArray[ (25 * 100 + 4) * 2 ], AX

I hope I describe it clearly enought.
Regards, AsmER

Tedd

Quote from: redskull on March 10, 2006, 11:50:19 PM
While we're sort of on the subject, i've heard lots of unconfirmed rumors that it's better to have all your data structures 32-bits and waste the extra memory for a huge gain in speed (and in this case, less bugs :red:).   Is that 'aligning'?  Is it a better idea than using the smallest amount of memory possible?

As with everything - it depends ::)
The main slow-down comes from accessing 16-bit values, because it requires a prefix on the instruction (eg. to make it ax instead of eax) and also there's some internal masking that goes on. Internally, the cpu only deals with 32-bits, so there is some benefit to sticking with this. But, problems arise when you access mis-aligned data because instead of directly accessing the single 32-bit value, what it actually has to do is get the 2 32-bit values and then take the last part of the first and the first part of the last in order to get the 32-bit value you really wanted (because it wasn't on a 32-bit aligned address in memory.) So alignment means making sure that your 32-bit values are on 32-bit aligned addresses (address mod 4 = 0) and equally for other data sizes.
Anyway, always making your data sizes 32-bit isn't necessarily such a speed-up and can obviously be quite a waste of space. Since bytes can't be misaligned, and byte-register instructions don't need a prefix, then it's not such a bad thing to use them (though using al and ah at the same time can cause problems since tey're still aprt of the same register.) However, given the choice between 16 and 32-bit data, I'd usually go with 32, unless the space increase is disproportionate.

[Discliamer: All advice above is my own opinion and bears no relevance to reality :bdg]
No snowflake in an avalanche feels responsible.