Indirect Memory Addressing

Memory can be referenced directly using an absolute address like this:

 mov eax,MonkeyBrainSoup 

or with some displacement. The assembler resolves the address with the offset for a new address:

 mov eax,MonkeyBrainSoup+8 

This is still an absolute address. The address is simply adjusted and the new address is encoded into the code. If MonkeyBrainSoup were in data memory at location 1000h, then adding the displacement merely would encode the address as 10008h. A structure is referenced in the same way.

 vmp3DVector STRUCT       x       REAL4 ? ;float  ?       y       REAL4 ? ;float  ?       z       REAL4 ? ;float  ? vmp3DVector ends      MyPos    vmp3Dvector    <1.0, 2.0, 3.0> 

So addressing this static structure directly:

 mov   eax.MyPos.x mov   ecx.MyPos.y mov   edx.MyPos.z 

really maps to:

 mov   eax,DWORD PTR MyPos+0 mov   ecx,DWORD PTR MyPos+4 mov   edx,DWORD PTR MyPos+8 

We could address this indirectly by setting ebx to the base address:

 mov   ebx,offset MyPos mov   eax,(vmp3Dvector PTR[ebx]).x mov   ecx,(vmp3Dvector PTR[ebx]).y mov   edx,(vmp3Dvector PTR[ebx]).z 

Or how about as an array of floats as shown below? Note that 0*4, 1*4, and 2*4 are not addressing multipliers. They are base address multipliers. To truly be a multiplier a register has to be the prefix argument, such as EDX*8 or EAX*2, etc. What the following really says is the base address of 0—1=0 or 1—4=4 or 2—4=8 + the value in ebx = the adjusted base address.

 mov   eax,[ebx+0*4] mov   ecx,[ebx+1*4] mov   edx,[ebx+2*4] 

Or an indexed element of the array:

 mov   eax,1            ; Using eax as the element index mov   ecx,[ebx+eax*4]  ; 4 byte float 

Those were just some examples, as almost any register can be used alone, in a pair addition, with an optional base address and/or scale factor of {2, 4, or 8}, but note that there are some limitations in regard to the ESP register. For address memory the equivalent scaling factor is needed: int16=—2, int32=—4, int64=—8. During code reviews of other programmers'assembly code I have seen single registers with and without scaling but rarely multiple register addition; instead there is usually some discrete logic to calculate a base address. (That is a waste of CPU time when hardware can resolve some of the addressing for you!)

In regard to the following mapping mechanisms I have read a lot of books and they usually have some minimal reference or simple tables made to show multiple register referencing.

image from book
Table 3-10: 64-bit memory reference (64-bit Mode)
image from book
Table 3-11: 32-bit memory reference (Protected Mode)
image from book
Table 3-12: 16-bit memory reference (Real Mode)

I have never seen them in a verbose table such as that in Appendix C. Even the data books direct from the chip manufacturers seem to be lacking in this information, and so here it is. Seeing it should help you remember and then entice you to use them.

uint32 OddTable[ ]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

1

3

5

7

11

13

17

19

23

29

31

37

41

43

47

53

 ebx = 0   edx = 1 mov eax, OddTable                   ; = 1 mov eax, OddTable[ebx]              ; = 1 mov ecx, OddTable[eax * 4]          ; = 11 mov ebx, OddTable[ebx + ecx]        ; = 37 mov ebx, OddTable[ecx + edx * 4]    ; = 53 mov esi, offset OddTable mov eax, [esi + ebx * 4] 

Since the table is 32-bit (4 byte) a multiplier of —4 can be used to reference the correct array cell . If the table were 16-bit, the multiplier would be —2, 64-bit then —8.

The same kind of memory reference used to access an element in a memory table or array can also be used to access a jump or call vector.

LEA Load Effective Address

LEA destination , source

Mnemonic

P

PII

K6

3D!

3Mx+

SSE

SSE2

A64

SSE3

E64T

LEA



32.64-Bit 80X86 Assembly Language Architecture
32/64-Bit 80x86 Assembly Language Architecture
ISBN: 1598220020
EAN: 2147483647
Year: 2003
Pages: 191

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net