| ||
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.
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.
| 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 destination , source
Mnemonic
P
PII
K6
3D!
3Mx+
SSE
SSE2
A64
SSE3
E64T
LEA
EAN: 2147483647
Pages: 191
If you may any questions please contact us: flylib@qtcs.net