Complex Addressing Modes

(FBSL v3 Dynamic Assembler Code)

Moderator: Mike Lobanovsky

Complex Addressing Modes

Unread postby Mike Lobanovsky » Thu Mar 03, 2011 5:24 pm

The following is a short tutorial by Steve Hutchesson published for PowerBasic inline asm users a while ago HERE. It applies literally to Fbsl's Dynamic Assembler too.

Quote: "Many people learning x86 assembler have problems with the notation but once you understand how it works, it is in fact very clear precise notation that you know exactly what it is doing.

Here is a small tute showing how it works in... "
... FBSL:

Code: Select all
' =========================================================
' @2009 Steve Hutchesson http://www.masm32.com/board/index.php
' =========================================================
' ML: A few comments changed/added by me to impose Fbsl v3 syntax
' =========================================================
'    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
' ======================= S T A R T ==========================

#AppType Console
#Option Strict

   Dim iarr[0 To 9] As Integer ' 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
   
DoIt(@iarr[0], AddressOf PrintIt) ' get the address of the first element ' ML: ... and the pointer to the printing routine

Pause

' ========================= E N D ===========================

' =========================================================
' ML: Wrapper to be called from Asm.
' Fbsl's Print does much conversion internally based on Fbsl's intrinsic
' data type evaluation which assembler has no knowing of. So use ByVal
' to suppress it and declare the incoming value as an explicit integer.
Sub PrintIt(ByVal What As Integer)
   Print What
End Sub
' =========================================================

' =========================================================
' ML: "Push" instructions supply integer parameters for
' our PrintInt wrapper sub by passing them on stack.
' Both PrintIt and Print preserve ESI and EDI internally
' exactly like we do it in our Asm below so that they
' don't interphere with each other.
Asm DoIt(ArrayPointer As Integer, PrintItPointer As Integer)

' ML: That's exactly where they will be located on stack
#Define ArrayPointer [ebp + 8]
#Define PrintItPointer [ebp + 12]

.data ' ML: Static data storage is here

@ctable
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 0, 0: db 0, 0, 0: db 0 ' numbers
   db 0, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1 ' upper case
   db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 0: db 0, 0, 0: db 0
   db 0, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1 ' lower case
   db 1, 1, 1: db 1, 1, 1: db 1, 1, 1: db 1, 1, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0
   db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0, 0, 0: db 0

.code ' ML: Entry point is here

enter 0, 0 ' ML: Set up new stack frame
push esi ' ML: Preserve regs by convention
push edi

   mov esi, ArrayPointer ' use ESI as the BASE  REGISTER
   xor edi, edi ' use EDI as the INDEX REGISTER ' ML: ... so clear it for now
   
   ' --------------------------------
   ' read array by altering the INDEX
   ' --------------------------------
   push [esi + edi * 4] ' push the content of member ZERO in one instruction
   call PrintItPointer
   
   add edi, 6
   push [esi + edi * 4] ' get the content of member SIX in one instruction
   call PrintItPointer
   
   ' ---------------------------------------
   ' read array by altering the displacement
   ' ---------------------------------------
   push [esi + 16] ' get the contents of member FOUR in one instruction
   call PrintItPointer
   
   push [esi + 32] ' get the contents of member EIGHT in one instruction
   call PrintItPointer
   
   ' -----------------------------------------
   ' 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] ' ML: I have "movzx eax, [$00f5c52b]" in Delphi's disassembler
   push eax
   call PrintItPointer
   
   ' 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] ' ML: Confirmed: "movzx eax, [edi+$00f5c4f8]" for Fbsl
   push eax
   call PrintItPointer

pop edi ' ML: Restore regs saved by convention
pop esi
leave ' ML: Restore old stack frame

ret ' ML: Return control to Fbsl
End Asm
' =========================================================


Enjoy!
Mike
"Я старый солдат, мадам, и не знаю слов любви."
"I am an old soldier, ma'am, and I don't know the words of love."
"Je suis un vieux soldat, madame, et je ne connais pas les mots d'amour."

__________________________________________________________________________________________________________________________________________
(2.2GHz Core2 Duo, 4GB RAM / 2 x GeForce 8600 GTS SLI-bridged, 1GB VRAM)
(x86 Win XP Pro Russian Sp3/x86 Win Vista Ultimate SP1/x64 Win 7 Ultimate Sp1/x64 Win 8 Consumer Preview)
User avatar
Mike Lobanovsky
FBSL Administrator
FBSL Administrator
 
Posts: 1474
Joined: Tue Apr 19, 2005 8:22 am
Location: Republic of Belarus

Return to Assembly Code

Who is online

Users browsing this forum: No registered users and 0 guests