x86 - addressing modes to access elements in arrays
-
25-06-2021 - |
Вопрос
I am trying to learn assembly language. Can someone explain and/or give an example of how to use addressing modes to access elements in each of the following array types?
array of
DWORD
array of structures, where each structure contains two
DWORD
sarray of arrays, where each array has 10
DWORD
s
Решение
You don't mention which processor specifically you are targeting, but in 386+ this would work. I don't have MASM, but MASM uses Intel syntax.
Let's assume that
ebx
is the base register andesi
is the index register of the element. Standard 32-bit registers (eax
,ebx
,ecx
,edx
,ebp
,esi
,edi
) are valid for the addressing mode used here.esp
can be used as base register but not as index register. The value of index register can be optionally scaled with 2, 4 or 8. In this example we can use a scaling factor 4 for a dword array (in 386 legal scaling factors are 1, 2, 4 and 8).to read the value from array into
eax
:mov eax, [ebx+4*esi]
to store the value ofeax
into array:mov [ebx+4*esi], eax
Let's keep still
ebx
as the base address. We can use a scaling factor 8 foresi
for a struct array in which each struct consists of 2 dwords.to read the value of the first dword into
eax
:mov eax, [ebx+8*esi]
to store the value ofeax
into first dword:mov [ebx+8*esi], eax
to read the value of the second dword into
eax
:mov eax, [ebx+8*esi+4]
to store the value ofeax
into second dword:mov [ebx+8*esi+4], eax
If the index can't be hardcoded, you can just add 4 to
ebx
(or whatever registers you use to store the base address). And if you have hardcoded base-address, then you could use eg.esi
to address the struct and eg.ebx
to address the dword you want. Note that in 386+ you can't scale more than one register (the index register) in indirect addressing.Let's still assume you don't know the base address of your array beforehand, and you'll have it in
ebx
, inesi
you have the index of the struct and inedx
you have the index of the dword.To get the address of the struct you can use
lea
multiplication optimization (10 = 8 + 2):Edit: Fix:
lea esi,[4*esi]
(dword is 4 bytes)lea edi,[ebx+8*esi]
lea edi,[edi+2*esi]
Now you have the address of the struct in
edi
. You just need to add the index of the dword (stored inedx
in this example) multiplied by 4 (because each dword is 4 bytes).To read value of dword to
eax
:mov eax,[edi+4*edx]
.To store value of
eax
into dword:mov [edi+4*edx],eax
.
Другие советы
The logic is trivial.
The address of i-th element of a 1-dimensional array is just the address of the array (or the 0-th element) plus i * element size.
If you have a 2-dimensional array, you can treat it as a 1-dimensional array of 1-dimensional arrays and reduce it to the already familiar case I've just described: the address of i-th 1-dim subarray of a 2-dim array is just the address of the 2-dim array plus i * subarray size. Within that i-th subarray we already know how to calculate j-th element address.
So, the address of (i,j)-th element of a 2-dimensional array is just the address of the array plus i * subarray size + j * element size OR, equivalently, the address of the array plus (i * number of elements in the row + j) * element size.
You should be able to figure out how to do this in assembly language.