UMBC CMSC 313 -- Arrays Previous | Next


Arrays

Arrays in General

A one-dimensional array is a collection of entries, each of the same length and placed one after the other in computer memory with no gaps. An array of n entries, of s bytes is is n times s bytes of contiguous memory.

| <---- s bytes per entry ----> |
                                  
                                  
                                  
                                  
                                  
                                  
                                   
                                  
                                  

The starting point is given a label as the name of the array. Like in C, indexing into the array is 0-origin indexing, which means the first element is the 0th element. (Actually, C does it the way assembly language does it, because because so much of C is directly related to the assembly language implementation of C's features.)

To locate a specific element in the array, we take the size of the element and multiple it by its index number. The second element (with the subscript of 1) is 1 times the sizeOf( element ) plus the starting address or:

array start address + (1 * sizeOf ( element ) ) = element address An example would be if the array's starting address is 0EF00h and the size of each element is 20 bytes, the 5th element (index of 4) is 4 * 20 = 8010 or 5016. 8000EF00h + 50h = 8000EF50h To declare the array (uninitialized), we would put into our program:
N    EQU    50                    ; array holds fifty items
S    EQU     4                    ; each item is four bytes long
Ary  resd   N * S                 ; in C, this is int Ary[50];
                                  ; This is 800 bytes long.
  
Make sure that you don't try to refer the 4th item as [ Ary + 4 ] because that would really refer to the 2nd element (they are four bytes long!) You would have to refer to [Ary + 12].

Higher-dimensional arrays can be considered to be arrays of arrays.

Using Arrays

Example

If we have an byte array named counts, and wish to set the 6th element to 27, we would write:
        MOV   	[counts + 5], 27     ; Remember it is zero-based!
  

Another Example

If we have a word array named bigcounts, and wish to set the 6th element to 27, we would write:
        MOV   	[bigcounts + 2 * 5], 27     ; Remember it is zero-based, 
                                            ; and we must get to the correct byte.
  

Variable subscripts

We can use a variable to hold the subscript for us as well. We can use four (one is/are restricted usage, though) registers for this: EBX, EDI, ESI, and EBP.

EBX and EBP are the base registers. EBP is called the base pointer and is used only in stack operations. Use BP/EBP in the stack only, NEVER for general-purpose indexing!

EDI is used to hold the destination index, ESI holds the source index and EBX is used as a general purpose index register. ESI and EDI are used in string instructions as source and destination, but other instructions can use them as general indexing registers. Additionally, the can be used as general registers, but only as 32-bit registers!

Indexing Example

If we have an byte array named counts, and wish to set the 6th element to 27, we would write:
        MOV     EBX, 5                ; the index
        MOV   	[counts + EBX], 27    ; This will allow us to use loops
                                      ; and simply update the contents of
                                      ; EBX each time
  

Sample of Indexing Using a Byte Array

        MOV     EBX, 0
        MOV     ECX, 10
more:   MOV     [ counts + EBX ], 0
        INC     EBX
        LOOP    more
  
This segment will allow me to initialize the ten counts to zero.

Sample of Indexing Using a Word Array (Subscript method)

section .data
wArray	DW	1234h, 2345h, 3456h, 4567h, 5678h, 6789h, 789Ah, 89ABh, 9ABCh, 0ABCDh

section .bss

section .text
    global main                       ;must be declared for linker (ld)

main:                                 ;tell linker entry point

        MOV     EDI, 0
        MOV     ECX, 10
more:   MOV     word [ wArray + EDI ], 0
        ADD     EDI, 2               ; Remember to byte adjust!
        LOOP    more
 

        mov     ebx,0   ;successful termination of program
        mov     eax,1   ;system call number (sys_exit)
        int     0x80    ;call kernel
 

Sample of Indexing Using a Word Array (Pointer method)

        MOV     EDI, counts
        MOV     ECX, 10
more:   MOV     [ EDI ], 0
        ADD     EDI, 2                 ; Remember to byte adjust!
        LOOP    more
  

Comparision

What's the difference? MOV [ counts + EDI ], 0 instead of MOV [ EDI ], 0 Hopefully, you will intuitively see that the time to compute counts + EDI adds extra time to the loop. However, pointers add speed and indices add simplicity, which is easier to maintain.

Finally, Offset Computation

Offset = Base + (Index * Scale) + Displacement

Where:

The scale will match what you are trying to get, byte, word, double word, or quad word.

Example

Let W be an array of words and N be a word variable subscript . The assembly code to do the following C code
W[ N + 3 ] = 27;
  
would be:
	mov	edx, [ N ]
	mov	[ W + 6 + 2 * edx ], 27
  
That was confusing! The W is the address of the array, 6 is 3 * 2 (two bytes per word), and then the number of word in N has to be adjusted to be the number of bytes in N words.
By using fancier forms for memory addressing, we can get:
	mov	eax, msg
  	mov	eax, [eax + 4       ]	; add 4 to eax(!)
	mov	ebx, [eax + 2 * eax ]	; ebx = eax * 3
	mov 	ebx, [      4 * eax ]	; ebx = eax * 4
	mov	ebx, [eax + 4 * eax ]  	; ebx = eax * 5
  
Notice that this works as a fast multiplication of small numbers and does not change the flags!

IMPORTANT

In based indexing, there are two important rules:

Array Exercise


Previous | Next

©2004, Gary L. Burt