News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Alternative calling convention for MASM Objects.

Started by Caché GB, September 23, 2018, 08:11:55 AM

Previous topic - Next topic

Caché GB

Ok I was getting my feet wet and reading up on x64 and wonderful , the first four perms are passed in regs rcx, rdx, r8, r9. Nice.
Then reading a bit further see that Linux uses six regs - rdi, rsi, rdx, rcx, r8 and r9, for User-level applications. No this is not on.
How could you let this happen M$.

Henry Miller once said, "Whatever there be of progress in life comes not through adaptation but through daring."

OK Henry Miller, challenge accepted.



vcall MACRO Who:REQ, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7

  LOCAL  VtblName, MethodName, pInterface, IPos1, IPos2
   
;=== From Biterider's ObjAsm32 : http://objasm32.tripod.com/ ===
    IPos2 = @InStr(1, <Who>, <::>)
    IF IPos2 NE 0
       pInterface SUBSTR <Who>, 1, (IPos2 - 1)
       IPos1 = @InStr(IPos2 + 1, <Who>, <.>)
       IF IPos1 NE 0
          VtblName SUBSTR <Who>, IPos2 + 2, IPos1 - IPos2 - 2   
          MethodName SUBSTR <Who>, IPos1 + 1
       ELSE
         .err <vcall format error. Dot-Method missing.>
       ENDIF
    ELSE
      .err <vcall format error. Double Colon missing.>
    ENDIF
;==============================================================
    IFNB <Arg7>
      IPos1 = @InStr(1, Arg7, <&>)
      IPos2 = @InStr(1, Arg7, <*>)
      IF IPos1
           lea  eax, @SubStr(<Arg7>, %IPos1+1)
          movd  mm7,  eax
      ELSEIF IPos2
           mov  eax, @SubStr(<Arg7>, %IPos2+1)
           mov  eax, [eax]
          movd  mm7,  eax
       ELSE
         IF OPATTR(Arg7) EQ 100100b
            mov  eax, Arg7
           movd  mm7, eax
         ELSE
           movd  mm7, Arg7
         ENDIF
       ENDIF
    ENDIF

    ...

    IFNB <Arg0>
      IPos1 = @InStr(1, Arg0, <&>)
      IPos2 = @InStr(1, Arg0, <*>)
      IF IPos1
           lea  eax, @SubStr(<Arg0>, %IPos1+1)
          movd  mm0,  eax
      ELSEIF IPos2
           mov  eax, @SubStr(<Arg0>, %IPos2+1)
           mov  eax, [eax]
          movd  mm0,  eax
       ELSE
         IF OPATTR(Arg0) EQ 100100b
            mov  eax, Arg0
           movd  mm0, eax
         ELSE
           movd  mm0, Arg0
         ENDIF
       ENDIF
    ENDIF

          mov  eax, pInterface
         call  (VtblName ptr[eax]).MethodName  ; ;  or call  [eax][VtblName.MethodName]

ENDM



So it looks like this.



.data
     szTexture02               dw L(Asserts\\minimap.jpg\0)                            ;; L macro by Ernest Murphy
     ?szTexture02              dd offset szTexture02

.code

          new  CBitmap
          mov [edi].m_Bitmap, eax
        vcall [edi].m_Camera::CCamera.GetViewMatrixPtr                           ;;  for the BaseViewMatrix : Position = 0.0, -1.0, 0.0, 0.0
         movd  mm3, eax
        vcall [edi].m_Bitmap::CBitmap.Initialize, pDevice, pDeviceContext, ?szTexture02, , ScreenWidth, ScreenHeight, 154, 154

; =============================================================================

CCamera_GetViewMatrixPtr proc ;; ViewMatrix:ptr XMMATRIX

       assume  eax:ptr CCamera

          lea  eax, [eax].m_ViewMatrix

       ;; mov  edx,  ViewMatrix
       ;; lea  eax, [eax].m_ViewMatrix
       ;; mov [edx], eax

          ret

CCamera_GetViewMatrixPtr endp

; =============================================================================

CBitmap_Initialize proc

       assume  eax:ptr CBitmap
          mov [eax].m_Caller, edi
          mov  edi, eax
       assume  edi:ptr CBitmap

         movd [edi].m_Device, mm0
         movd [edi].m_DeviceContext, mm1
         movd [edi].m_ScreenWidth, mm4
         movd [edi].m_ScreenHeight, mm5
         movd [edi].m_BitmapWidth, mm6
         movd [edi].m_BitmapHeight, mm7

          mov [edi].m_PreviousPosX, -1
          mov [edi].m_PreviousPosY, -1

         movd  ecx, mm3                                                        ;; ptr BaseViewMatrix
          lea  eax, [edi].m_BaseViewMatrix
       invoke  MatrixCopyData

         movq  mm0, mm2                                                        ;; szTexture
       vpcall  CBitmap.LoadTexture                                             ;; private call of class

       vpcall  CBitmap.InitializeBuffers

          mov  edi, [edi].m_Caller
          ret

CBitmap_Initialize endp



------------------------------------------------------------------------------------------------------------------------------
Quote from:  subconscious on my mind.
======================================================================
So what are you ganna do if you got more than eight perms???
======================================================================

Well sub, then you will have to use the wakeupcall.



wakeupcall MACRO Who:REQ, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Args:VARARG

  LOCAL Arg, ArgList, VtblName, MethodName, pInterface, IPos1, IPos2

;=== From Biterider's ObjAsm32 : http://objasm32.tripod.com/ ===

    IPos2 = @InStr(1, <Who>, <::>)
    IF IPos2 NE 0
       pInterface SUBSTR <Who>, 1, (IPos2 - 1)
       IPos1 = @InStr(IPos2 + 1, <Who>, <.>)
       IF IPos1 NE 0
          VtblName SUBSTR <Who>, IPos2 + 2, IPos1 - IPos2 - 2   
          MethodName SUBSTR <Who>, IPos1 + 1
       ELSE
         .err < wakeupcall format error. Dot-Method missing.>
       ENDIF
    ELSE
      .err < wakeupcall format error. Double Colon missing.>
    ENDIF
;==============================================================

;=================== From somewhere I can't remember. =================
    ArgList TEXTEQU <>
    IFNB <Args>
       FOR Arg, <Args>
        IF @InStr(1, <Arg>, <eax>) NE 0
           .err <wakeupcal uses eax: call will be corrupted>
         ENDIF
         ArgList CATSTR <Arg>,<,>,ArgList
       ENDM
       ArgList SUBSTR ArgList,1,@SizeStr(%ArgList)-1
       ArgList CATSTR <!<>,ArgList,<!>>
;=============================================================

     % FOR Arg, ArgList
         IPos1 = @InStr(1, Arg, <&>)
         IPos2 = @InStr(1, Arg, <*>)
         IF IPos1
              lea  eax, @SubStr(<Arg>, %IPos1+1)
             push  eax
         ELSEIF IPos2
              mov  eax, @SubStr(<Arg>, %IPos2+1)
              mov  eax, [eax]
             push  eax
          ELSE
             push  Arg
          ENDIF

       ENDM
    ENDIF

    IFNB <Arg7>
      IPos1 = @InStr(1, Arg7, <&>)
      IPos2 = @InStr(1, Arg7, <*>)
      IF IPos1
           lea  eax, @SubStr(<Arg7>, %IPos1+1)
          movd  mm7,  eax
      ELSEIF IPos2
           mov  eax, @SubStr(<Arg7>, %IPos2+1)
           mov  eax, [eax]
          movd  mm7,  eax
       ELSE
         IF OPATTR(Arg7) EQ 100100b
            mov  eax, Arg7
           movd  mm7, eax
         ELSE
           movd  mm7, Arg7
         ENDIF
       ENDIF
    ENDIF

   ; ...

    IFNB <Arg0>
      IPos1 = @InStr(1, Arg0, <&>)
      IPos2 = @InStr(1, Arg0, <*>)
      IF IPos1
           lea  eax, @SubStr(<Arg0>, %IPos1+1)
          movd  mm0,  eax
      ELSEIF IPos2
           mov  eax, @SubStr(<Arg0>, %IPos2+1)
           mov  eax, [eax]
          movd  mm0,  eax
       ELSE
         IF OPATTR(Arg0) EQ 100100b
            mov  eax, Arg0
           movd  mm0, eax
         ELSE
           movd  mm0, Arg0
         ENDIF
       ENDIF
    ENDIF

          mov  eax, pInterface
         call  (VtblName ptr[eax]).MethodName

ENDM



To all those how would like to put me in a straight jacket and throw me in a padded cell, please calm down to a panic.
This is just an ex-parra-"mental" exercise and yes, I shoud have stuck it in the Romper Room, I know.

Any regs mm0 to mm7 with values that are needed after an API call, will need to be saved first.
This is also the case before use of the coprocesser and an emms instuction is also needed before hand.

BTW 3 things happened today
1. A script kiddie said assembly sucks and that it had no place in modern day programming.
2. He got lost at sea.
3. I lost my skippers Licence. Dam I'll miss shark marlin fishing.

Caché GB's 1 and 0-nly language:MASM