News:

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

Which addressing modes for win32

Started by Rainstorm, September 27, 2006, 11:12:58 PM

Previous topic - Next topic

Rainstorm

Hi.

While reading stuff in different documents on asm, I come accross different addressing modes.
I'd just like to know which addressing modes are relevant to 32bit asm & win32;...so I can
read through only those ones.
if someone could give me some guidance on the whole thing..
I just know of the normal way like,  mov ebx, [eax]  or mov eax, [var1]     to do it.

Thank-you.

Rainstorm
-

Vortex

Rainstorm,

Selecting addressing modes depends on what are you trying to do. You can find full explanation in :

MASM Programmer's Guide , Chapter 3 : Using Addresses and Pointers

Direct Memory Operands \ Indirect Memory Operands

http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_03.htm

gabor

Hello!


Besides the trivial immediate addressing (mov eax,14 or add ecx,10h) there are addressing modes for memory access.
This, I've found in one of Intel's documents:

"At the machine-code level, the selected combination of displacement, base register, index register, and scale factor is encoded in an instruction."

This means offset or effective address calculation may include 2 registers (base and index) a scale and a displacement.
So
mov eax,[esi+ecx*4+12]
is allowed, where:

  • esi is the base address
  • ecx is the index
  • the scale is 4, valid scales are (1,) 2,4 and 8
  • the displacement is 12, a 8 bit value

Important is to remember that all the registers can be used as base, and except esp every register can be used as index.











Base+Index*Scale+Displacement
eaxeax
ebxebx
ecxecx1none
edxedx28 bit
esiesi416 bit
ediedi832 bit
ebpebp
esp
[/b]

Examples:

mov eax,[esi]         ; base only
add [edx+ecx],eax     ; base+index
sub [edi+ecx*2],ebx   ; base+index*scale
mov edx,[esi+eax*4+4] ; base+index*scale+displacement


This addressing is the most powerfull feature of the flat, 32bit memory model coding.
For example a simple memory moving cycle can be coded very easily:

mov ecx,(10000h-4)/4 ; let's move 64kB in dwords
@@:
mov eax,[esi+ecx*4] ; read source dword from the end
mov [edi+ecx*4],eax ; write destination dword to the end
sub ecx,1
jnc @B


Hm, might there be a speed difference if I subtract 4 from ecx and don't use scale in the read/write instructions?

mov ecx,10000h-4 ; let's move 64kB in dwords
@@:
mov eax,[esi+ecx] ; read source dword from the end
mov [edi+ecx],eax ; write destination dword to the end
sub ecx,4
jnc @B



Greets, Gábor


Tedd

Yes there are lots different addressing modes, just as there are lots of different instructions. They all have their uses in different situations, so they are all 'relavent' at some point. But I really wouldn't worry about it, you'll pick up the most common ones as you go along, and you can find out the rest if you happen to wander that way :lol

Anyway, apart from the 'normal' way.. the next most used would be adding an index (for accessing arrays or tables or whatever)

So, you have ecx as your array index, esi pointing to the start of the array (in 32-bit these can actually be pretty much any combination of the registers; only two though!) -- mov al,[esi+ecx] will access the ecx'th element in the array pointed to by esi (assuming the elements are bytes in size.)
But array elements are often dword in size, so you can do this instead: mov eax,[esi+4*ecx] giving the ecx'th dword-element in esi's array. You're also allowed to multiply by 2 or 8, rather than just 4.
And, just to confuse matters, you're allowed to add an offset onto that! But you won't find so much use for this. Though you might sometimes use the memory address of an array (rather than in a register) and then add the index onto that (as above.)
But, like I said, don't worry too much about it, you'll find them as you need them.
No snowflake in an avalanche feels responsible.

Rainstorm

vortex & tedd,
thanks for the feedback & assistance.

vortex, am reading that link now as well as another page from the same url which states some of the differences between 32bit & 16 bit programming.

..was a little delayed in replying, due to some weird hardware probs with my comp because of
which it wouldn't boot. - Managed to get it straightened out after fiddling with it a bit...

regards

Rainstorm.

Rainstorm

Hiya Gabor,

As always I  learn something new in your posts.

thanks again for the info & the examples    :)

Regards

Rainstorm.
-

Rainstorm

hi,

just trying somethings
the following code doesn't work - it assembles without an error
but when run,,it brings about the windows error msg about the application
having to close because of a prob

    .data

blockk dd 8 dup (?)


    .code

start:


  mov blockk, 65000
  mov ecx, 8
  mov eax, [blockk]    ; get the base address
 
    @@:

    mov edx, [eax+ecx*4]

  print ustr$(edx),13,10
 
  sub ecx, 1
  jnc @B

  inkey
  exit


end start

gabor

Hi!

The problem is here:
Quote from: Rainstorm on October 05, 2006, 12:17:27 PM

mov eax, [blockk] ; get the base address
 

This instruction loads the dword value stored at symbol blockk into edx, in this case this value is 65000, and not its address! This value is probably not an available address in your program's address space, so a general protection fault occures (access violation).

To load the base address you have to use the offset keyword or the lea instruction. Like this:

mov eax,offset blockk

; OR

lea eax,[blockk]


The lea instruction is slower, so when loading a base address only, no scaling or displacing used, mov reg,offset symbol is recommended!
Use lea only if there is a scaling and/or a displacement:

lea eax,[blockk+4*ecx+12]

; without lea this would look like this:
mov eax,offset blockk ; base address
shl ecx,2 ; multiply ecx by 4 - index and scaling
add eax,12 ; displacement
add eax,ecx
; this is definitly slower then the lea instruction and it modifies the ecx...

Well, I am glad, that you are asking questions over and over again, because this tells me that you do deal with learning asm!  :U


Greets, Gábor

Rainstorm

Gabor, thanks..

QuoteThis instruction loads the dword value stored at symbol blockk into edx, in this case this value is 65000, and not its address!

So in this case..
mov eax, [blockk]
and
mov eax, blockk

are both the same thing ? (i.e they both load eax with the value stored at the address)

so the usage of
mov eax, [var]  ; (to get the address of 'var')..is only valid when its declared in the data section like
var dd 0
something like that..- is that right ?
just want to know where the usage,     mov eax, [var]   is valid for getting the address of the variable.

PBrennick

rainstorm,

var dd 0
is fine. Then as Gábor said, using
mov eax, offset var
will get the address of var.

One thing, for convention sake, eax is usually a data carrier and is not used for addressing.  For addressing you really should use esi or edi so why not use the following
mov esi, offset var

I have seen eax used in an addressing method called dereferencing but, personally, I seldom use the method.
Paul
The GeneSys Project is available from:
The Repository or My crappy website

gabor

Hello!

Good question Rainstorm! Honestly I cannot tell the difference between with square brackets and without them except the lea instruction.
So
mov eax,var
mov eax,[var]

seem to be the same. But
lea eax,var
gives a compile error, the square brackets must be used.


Refering to PBrennick's post I agree that eax is used for calculations (like the old fashion accumulator register). For indexing it is common to use esi (source index) edi (destination index) and also ebx. For example the table using instruction xlat (that is not really used any more) uses bx as the table's pointer.
As for me I like to use edx too as a pointer all the other registers are used.
It is good to remember that esi and ebx are preserved across winapi calls that means that this registers are not changed after a window function call.

Greets, Gábor

Rainstorm

thanks for the replies guys...

p.s - was out of town for a bit & couldn't reply immediately.