Author Topic: Complex Addressing Mode example.  (Read 5963 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5944
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Complex Addressing Mode example.
« on: May 23, 2012, 07:23:00 PM »
For folks that are not familiar with the Intel notation for complex addressing mode, it can look a bit daunting but in fact it is technically simple with only a limited number of variables that effect how it works. This small example shows the basics of complex addressing mode in what I hope is a simple enough to make sense way.

Code: [Select]
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION PBmain as LONG

#IF 0  ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    there are 4 variable components of Intel addressing notation
    ------------------------------------------------------------

    1. The BASE address
    (This is usually a register but can be a displacement)

    2. the INDEX
    (an array index that is normally ADDED to the base address)

    3. the index MULTIPLIER with the range 1 2 4 8
    (matches array elements of the same byte size)

    4. the DISPLACEMENT in bytes
    (added or subtracted from the total address of any of the above if used)

    -------------------------------------------------------------------------

    Each of these capacities match an instruction built into the processor
    that is called an OPCODE. Assembler coding is normally written in what
    are called MNEMONICS as this simplifies the vast range of processor opcodes
    and makes the code much easier to read and write.

    When you try to write something that does not work, its not a syntax error,
    it is the case where there is no OPCODE to match what you are trying to do.

    The ASSEMBLER will normally detect these problems if there is no valid OPCODE
    to match what is written.

    EXAMPLES

    mov eax, pByteData  ; load the ADDRESS of BYTE data into EAX
    mov ecx, [eax]      ; copy the base address in EAX ([eax]) into the ECX register

    mov ecx, 2          ; use ECX as an INDEX
    mov edx, lpData     ; load the data address into EDX
    mov eax, [edx+ecx]  ; ADD the INDEX in ECX to the BASE ADDRESS in EDX & copy to EAX

    mov ecx, 4          ; use ECX as the INDEX
    mov edx, pArray     ; load the ADDRESS of a DWORD sized array
    mov eax, [edx+ecx*4] ; mul the index by 4 and add it to EDX then copy result to EAX

    mov ecx, 4          ; use ECX as the INDEX
    mov edx, pArray     ; load the ADDRESS of a DWORD sized array
    mov eax, [edx+ecx*4-16] ; change the ADDRESS with a displacement (in bytes).

    If the array is 16 bit (WORD sized) use a multiplier of 2
    If the array is 64 bit (QUAD sized) use a multiplier of 8

#ENDIF ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    #REGISTER NONE

    LOCAL aptr  as DWORD        ' the ARRAY POINTER
    LOCAL vshow as DWORD        ' variable for DISPLAY

    dim arr(8) as DWORD

    arr(0) = 0
    arr(1) = 1
    arr(2) = 2
    arr(3) = 3
    arr(4) = 4
    arr(5) = 5
    arr(6) = 6
    arr(7) = 7
    arr(8) = 8

    aptr = VarPtr(arr(0))       ' get the ADDRESS of the first array member

    ! mov eax, aptr             ; load it into a register
    ! mov eax, [eax]            ; get its content by dereferencing it
    ! mov vshow, eax            ; store the result in a variable

    msgbox format$(vshow)       ' display the result

    ! mov eax, aptr             ; load it into a register
    ! mov ecx, 3                ; use ECX as an array index
    ! mov eax, [eax+ecx*4]      ; change the address by changing the INDEX
    ! mov vshow, eax            ; store the result in a variable

    msgbox format$(vshow)       ' display the result

    ! mov eax, aptr             ; load it into a register
    ! mov ecx, 6                ; use ECX as an array index
    ! mov eax, [eax+24]         ; change the address by changing the DISPLACEMENT (add 24 bytes)
    ! mov vshow, eax            ; store the result in a variable

    msgbox format$(vshow)       ' display the result

    ! mov eax, aptr             ; load it into a register
    ! mov ecx, 3                ; use ECX as an array index
    ! mov eax, [eax+ecx*4-4]    ; change the address by changing the INDEX and DISPLACEMENT
    ! mov vshow, eax            ; store the result in a variable

    msgbox format$(vshow)       ' display the result

    erase arr()

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

peaslee

  • Guest
Re: Complex Addressing Mode example.
« Reply #1 on: May 25, 2012, 01:22:42 AM »
Is there an example of how to do this with a structure?

Thanks.

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5944
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Complex Addressing Mode example.
« Reply #2 on: May 25, 2012, 04:28:19 AM »
Not in high level basic, the structures cannot be addressed in this manner. You can code them as register-offests but its reasonably hard going if you are not used to it.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin: