Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

GLOBAL GOSUB or fast procedure calling with passing parameters

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • GLOBAL GOSUB or fast procedure calling with passing parameters

    according to :
    http://www.powerbasic.com/support/pb...t=35065&page=3

    Code:
    'Purpose:
    '            Fast call to global subrotine (no stack frame overhead)
    'Restriction:
    '            All global procedures must be allocated in the body of PBMAIN after EXIT FUNCTION
    '            Before using fast procedure, we need fill out Global variables which point
    '            to start address of procedure in the begining of PBMAIN and don't change never that value.
    '            (Or change it with purpose ;) if that procedure responsible for activation restricted shareware,
    '             then you can switch execution to another fake prorotype of procedure)
    'Features:
    '            Since parameters of fast global procedure is global, it possible speed up
    '            execution of procedure by assign values directly anywhere in the program,
    '            then not needed to call macro GetParamProc01.
    '            Then MACROs can be simplified to:
    '             MACRO CALLproc01
    '                ! mov ebx, pADDR01 ' pADDR01 initialized in PBMAIN as global dword
    '                ! call ebx
    '             END MACRO
    '             MACRO GetParamProc01(param1proc01, param2proc01)
    '             END MACRO
    '             MACRO END_PROC01
    '                ! ret
    '             END MACRO
    '
    '            Example: param1proc01 = 123 : param2proc01=VARPTR(some UDT as proc01UDT)
    '                     CALLproc01
    '            In that case our procedure became GLOBAL GOSUB
    '
    '
    #COMPILE EXE
    #DIM ALL
    '
    '======================================macro4Proc01 =======================
    MACRO CALLproc01(param1,param2)
       ! push param2
       ! push param1
       ! mov ebx, pADDR01 ' pADDR01 initialized in PBMAIN as global dword
       ! call ebx
    END MACRO
    '
    MACRO GetParamProc01(param1proc01,param2proc01)
       ! mov ebx, dword ptr [esp+4]
       ! mov param1proc01, ebx ; extract first param
       ! mov ebx, dword ptr [esp+8]
       ! mov param2proc01, ebx ; extract second param
    END MACRO
    '
    MACRO END_PROC01
       ! ret 8 ' two parameters, so we need to clear up stack [2 (param) * 4 (dword size) = 8]
    END MACRO
    '===============================================================
    '
    TYPE proc01UDT
      sz  AS ASCIIZ*128
      lng AS LONG
    END TYPE
    '
    '-----------------------------------------
    SUB CallProcedureFromSubrotine()
        LOCAL u1 AS proc01UDT
        LOCAL  dw2, lpU1 AS DWORD
        '
        'init params for passing to procedure
        dw2 = &haa55aa55aa???
        lpU1 = VARPTR(u1)
        u1.sz = "Receive call from subroutine, not PBMAIN"
        u1.lng = 567&
        '
        CALLproc01(dw2, lpU1)'Call fast global procedure
    END SUB
    '=============================================
    FUNCTION PBMAIN () AS LONG
              '------------------------------------------------
              GLOBAL pADDR01 AS DWORD    ' do it once in pbmain
              pADDR01 = CODEPTR(proc01)  ' for each procedure
              '------------------------------------------------
              LOCAL u AS proc01UDT
              LOCAL  dw1, lpUDT AS DWORD
              '
              'init params for passing to procedure
              dw1 = &hf1f2f3f4???
              lpUDT = VARPTR(u)
              u.sz = "Receive call from PBMAIN, where procedure allocated"
              u.lng = 1234&
              '
              CALLproc01(dw1, lpUDT)       'Call fast global procedure
              CallProcedureFromSubrotine() 'Call fast global procedure from child subrotine
              '
              ? "done"
    EXIT FUNCTION '=============================
    '
    proc01: 'CALLproc01(BYVAL param1proc01 as DWORD, BYCOPY param2proc01 as AS proc01UDT PTR)
          GLOBAL param1proc01,param2proc01 AS DWORD
          GLOBAL lpUDT_proc01 AS proc01UDT PTR
          '
          GetParamProc01(param1proc01,param2proc01)
          '
          lpUDT_proc01 = param2proc01
          '
          ? "Recevied param1 = 0x"+HEX$(param1proc01)+$CRLF+$CRLF+_
            "param2 as pointer to proc01UDT and return :"+$CRLF+_
            "UDT data: sz = "[email protected]_proc01.sz+$CRLF+_
            "UDT data: lng= "+STR$(@lpUDT_proc01.lng),,"Procedure01 respond:"
    END_PROC01
    END FUNCTION
    -=Alex=-
Working...
X