Demystifying the Intel Complex Addressing Mode

Started by hutch--, December 21, 2009, 04:53:21 AM

Previous topic - Next topic

hutch--

Often this type of notation looks like a nightmare to someone learning assembler but once you get the swing of how it is constructed its a very clear and precise notation.

Here is a simple demo to show how it works.


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

    Build with PBCC50

    Intel complex addressing mode.

    BASE REGISTER --- INDEX --- MULTIPLIER --- DISPLACEMENT

    mov esi, address    ; ESI as base register
    mov edi, 16         ; EDI as the INDEX

    mov eax, [esi+edi*4+128]

    copy the contents at address + index times 4 + displacement into register EAX


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

FUNCTION PBmain as LONG

    #REGISTER NONE

    LOCAL svar as LONG
    LOCAL uvar as DWORD
    LOCAL parr as DWORD

    dim iarr(0 to 9) as LONG        ' dimension a 10 item integer array

    iarr(0) = 0000
    iarr(1) = 1111
    iarr(2) = 2222
    iarr(3) = 3333
    iarr(4) = 4444
    iarr(5) = 5555
    iarr(6) = 6666
    iarr(7) = 7777
    iarr(8) = 8888
    iarr(9) = 9999

    parr = VarPtr(iarr(0))          ' get the address of the first element

    ! mov esi, parr                 ' use ESI as the BASE  REGISTER
    ! xor edi, edi                  ' use EDI as the INDEX REGISTER

  ' --------------------------------
  ' read array by altering the INDEX
  ' --------------------------------
    ! mov eax, [esi+edi*4]          ' get the content of member ZERO in one instruction
    ! mov uvar, eax
    cout ustr(uvar)

    ! add edi, 6
    ! mov eax, [esi+edi*4]          ' get the content of member SIX in one instruction
    ! mov uvar, eax
    cout ustr(uvar)

  ' ---------------------------------------
  ' read array by altering the displacement
  ' ---------------------------------------
    ! mov eax, [esi+16]             ' get the contents of member 4 in one instruction
    ! mov uvar, eax
    cout ustr(uvar)

    ! mov eax, [esi+32]             ' get the contents of member 8 in one instruction
    ! mov uvar, eax
    cout ustr(uvar)

  ' -----------------------------------------
  ' read from a BYTE table in one instruction
  ' zero extend it to 32 bit and display it
  ' -----------------------------------------

  ' Using this notation the location "ctable" is effectively a DISPLACEMENT.
  ' For it to work it is an OFFSET determined at compile time.

    ! movzx eax, BYTE PTR ctable[51]    ' disassembly >>>  movzx   eax,byte ptr [401453h]
    ! mov uvar, eax
    cout ustr(uvar)

  ' setting a register like an INDEX changes the output OPCODE
  ' EDI becomes the BASE REGISTER and the location "ctable"
  ' is a DISPLACEMENT added to it.

    ! mov edi, 66                       ' set the INDEX
    ! movzx eax, BYTE PTR ctable[edi]   ' disassembly >>>  movzx   eax,byte ptr [edi+401420h]
    ! mov uvar, eax
    cout ustr(uvar)

    pause

    FUNCTION = 0
    Exit FUNCTION

  #align 4
  ctable:
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0        ' numbers
    ! db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1        ' upper case
    ! db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    ! db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1        ' lower case
    ! db 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    ! db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION cc_out CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD

SUB cout(a$)

  ' ***** Supported escapes *****
  ' \0 = ascii zero             0
  ' \t = tab                    9
  ' \n = newline               10
  ' \r = carriage return       13
  ' \q = double quote          34
  ' \\ = backslash             92
  ' *****************************

    #REGISTER NONE

    LOCAL src as DWORD
    LOCAL dst as DWORD
    LOCAL sln as DWORD

    src = StrPtr(a$)

    ! mov esi, src
    ! mov edi, src

  stlp:
    ! mov al, [esi]
    ! add esi, 1

    ! cmp al, "\"
    ! jne nxt

' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤

    ! cmp BYTE PTR [esi], "n"
    ! jne lb1
    ! add esi, 1
    ! mov BYTE PTR [edi], 10
    ! add edi, 1
    ! jmp stlp
  lb1:

    ! cmp BYTE PTR [esi], "r"
    ! jne lb2
    ! add esi, 1
    ! mov BYTE PTR [edi], 13
    ! add edi, 1
    ! jmp stlp
  lb2:

    ! cmp BYTE PTR [esi], "t"
    ! jne lb3
    ! add esi, 1
    ! mov BYTE PTR [edi], 9
    ! add edi, 1
    ! jmp stlp
  lb3:

    ! cmp BYTE PTR [esi], "0"
    ! jne lb4
    ! add esi, 1
    ! mov BYTE PTR [edi], 0
    ! add edi, 1
    ! jmp stlp
  lb4:

    ! cmp BYTE PTR [esi], "\"
    ! jne lb5
    ! add esi, 1
    ! mov BYTE PTR [edi], 92
    ! add edi, 1
    ! jmp stlp
  lb5:

    ! cmp BYTE PTR [esi], "q"
    ! jne lb6
    ! add esi, 1
    ! mov BYTE PTR [edi], 34
    ! add edi, 1
    ! jmp stlp
  lb6:

' ¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤=÷=¤

  nxt:
    ! mov [edi], al
    ! add edi, 1
    ! test al, al
    ! jnz stlp

    ! sub edi, src
    ! mov sln, edi

    cesc$ = left$(a$,sln)

    cc_out StrPtr(cesc$)

END SUB

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    MACRO INPUT_HANDLE  = -10&
    DECLARE FUNCTION kbflush LIB "KERNEL32.DLL" ALIAS "FlushConsoleInputBuffer" ( _
                     BYVAL hConsoleInput AS DWORD) AS LONG
    DECLARE FUNCTION hStdIn LIB "KERNEL32.DLL" ALIAS "GetStdHandle" ( _
                     BYVAL nStdHandle AS DWORD) AS DWORD
    DECLARE FUNCTION SysYield LIB "KERNEL32.DLL" ALIAS "Sleep" ( _
                     BYVAL msWait AS DWORD) AS LONG
    DECLARE FUNCTION keypress CDECL LIB "MSVCRT.DLL" ALIAS "_kbhit" () as DWORD
    DECLARE FUNCTION putz CDECL LIB "MSVCRT.DLL" ALIAS "puts" (BYVAL ptxt AS DWORD) AS DWORD

' -------------------------------------------

SUB pause()

    txt$ = "Press any key to continue ...."
    putz StrPtr(txt$)
    kbflush hStdIn(INPUT_HANDLE)

  lbl0:
    SysYield 20
    keypress
    ! test eax, eax
    ! jz lbl0

END SUB

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION ltoa CDECL LIB "MSVCRT.DLL" ALIAS "_ltoa" ( _
                     ByVal lval as LONG,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD

' -------------------------------------------

FUNCTION sstr(ByVal lval as LONG) as STRING

    LOCAL astring as ASCIIZ * 32

    ltoa(lval,VarPtr(astring),10)

    FUNCTION = astring

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_ultoa CDECL LIB "MSVCRT.DLL" ALIAS "_ultoa" ( _
                     ByVal uint as DWORD,ByVal pstr as DWORD,ByVal radix as DWORD) as DWORD

' -------------------------------------------

FUNCTION ustr(ByVal uint as DWORD) as STRING

    LOCAL astring as ASCIIZ * 32

    c_ultoa(uint,VarPtr(astring),10)

    FUNCTION = astring

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_atoi CDECL LIB "MSVCRT.DLL" ALIAS "atoi" (ByVal ptxt as DWORD) as DWORD

FUNCTION atoi(number$) as DWORD

    FUNCTION = c_atoi(StrPtr(number$))

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    DECLARE FUNCTION c_atol CDECL LIB "MSVCRT.DLL" ALIAS "atol" (ByVal ptxt as DWORD) as LONG

FUNCTION atol(number$) as LONG

    FUNCTION = c_atol(StrPtr(number$))

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php