News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

32 bit direct register demo

Started by hutch--, November 04, 2022, 11:13:29 PM

Previous topic - Next topic

hutch--

 :biggrin:

This is basically how you extend the 32 bit version of the MASM32 SDK. This is not a standard interface in Win32 ALA Intel ABI but if you want lower overhead, direct register calls will do it for you.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

  ; ----------------------------------------------
  ; direct register call macros, up to 3 registers
  ; ----------------------------------------------
    reg3 MACRO algo, arg1, arg2, arg3
      mov eax, arg1
      mov ecx, arg2
      mov edx, arg3
      call algo
    ENDM

    reg2 MACRO algo, arg1, arg2
      mov eax, arg1
      mov ecx, arg2
      call algo
    ENDM

    reg1 MACRO algo, arg1
      mov eax, arg1
      call algo
    ENDM
  ; ----------------------------------------------

    .data
      buff1 db "12345678901234567890123456789012345678901234567890",0
      buff2 db "                                                  ",0

      pbuf1 dd buff1                    ; buffer pointer
      pbuf2 dd buff2                    ; buffer pointer
    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL slnth :DWORD                  ; local variable

    reg1 LenStr, pbuf1                  ; get the string length
    mov slnth, eax                      ; store it in variable

    reg3 datCopy,pbuf1,pbuf2,slnth      ; call the copy algo

    print pbuf2,13,10,0                 ; display output buffer

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

datCopy proc

    mov esi, eax
    mov edi, ecx
    mov ecx, edx
    rep movsb

    ret

datCopy endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

LenStr proc

    mov edx, eax
    sub eax, 1
  @@:
    add eax, 1
    cmp BYTE PTR [eax], 0
    jne @B

    sub eax, edx

    ret

LenStr endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start


jj2007

A flexible variant - testbed attached (pure Masm32 SDK) :cool:

rcall MACRO algo, args:VARARG
Local arg, ct, tmp$
  ct=0
  for arg, <args>
tmp$ SUBSTR <eaxecxedx>, ct*3+1, 3
ifdifi <arg>, tmp$
mov tmp$, arg
endif
ct=ct+1
  ENDM
  call algo
ENDM

hutch--

I was tempted to tweak the 64 bit "rcall" macro but with 3 registers, it was hardly worth the effort. The 3 above work fine and don't add any extra overhead.

jj2007

A shorter variant:

rcall MACRO algo, args:VARARG
Local arg, ct, tmp$
  ct=0
  for arg, <args>
tmp$ SUBSTR <eaxecxedx>, ct*3+1, 3
ifdifi <arg>, tmp$
mov tmp$, arg
endif
ct=ct+1
  ENDM
  call algo
ENDM

hutch--

 :biggrin:

You could do this one as well but its not FASTCALL.

    reg4 MACRO algo, arg1, arg2, arg3, arg4
      push ebx
      mov eax, arg1
      mov ecx, arg2
      mov edx, arg3
      mov ebx, arg4
      call algo
      pop ebx
    ENDM

daydreamer

I would like a macro using/preserve
Movd xmm0,real4 arg1
Movd xmm1,real4 arg2
Movd xmm2,real4 arg3
Movd xmm3,real4 arg4
; call scalar SSE proc
Call floating point algo ; return real4 result in xmm0
Like in this
http://masm32.com/board/index.php?topic=10277.0
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

HSE

#6
More options (a little more secure):    rcall MACRO algo:req, arg1, arg2, arg3, arg4
        ifnb <arg1>
            mov eax, arg1
            ifnb <arg2>
                mov ecx, arg2
                ifnb <arg3>
                    mov edx, arg3
                    ifnb <arg4>
                        push ebx
                        mov ebx, arg4
                    endif   
                endif   
            endif   
        endif   
       
        call algo
       
        ifnb <arg4>
            pop ebx
        endif
    ENDM



But we are to late. This guy was thinking a similar thing before us: Pseudo FASTCALL  :biggrin:

Perhaps this prevent inefficiency and errors:
    rcall MACRO algo:req, arg1, arg2, arg3, arg4
        ifnb <arg1>
            ifdifi <arg1>, <eax>
                mov eax, arg1
            endif
            ifnb <arg2>
                ifdifi <arg2>, <ecx>
                    mov ecx, arg2
                endif
                ifnb <arg3>
                    ifdifi <arg3>, <edx>
                        mov edx, arg3
                    endif
                    ifnb <arg4>
                        ifdifi <arg4>, <ebx>
                            push ebx
                            mov ebx, arg4
                        endif
                    endif   
                endif   
            endif   
        endif   


then you can write:    rcall myproc, eax, 35, edx, -1


And this ugly thing is better:   rcall MACRO algo:req, arg1, arg2, arg3, arg4
        local meax, mecx,medx,mebx
        meax = 0
        mecx = 0
        medx = 0
        mebx = 0
        ifnb <arg1>
            ifdifi <arg1>, <eax>
                mov eax, arg1
                meax = 1
            endif
            ifnb <arg2>
                ifidni <arg2>, <eax>
                    if meax eq 1
                    .err  2052      eax was overwritten
                    endif
                endif
                ifdifi <arg2>, <ecx>
                    mov ecx, arg2
                    mecx = 1
                endif
                ifnb <arg3>
                    ifidni <arg3>, <eax>
                        if meax eq 1
                        .err 2052       eax was overwritten
                        endif
                    endif
                    ifidni <arg3>, <ecx>
                        if mecx eq 1
                        .err 2052       ecx was overwritten
                        endif
                    endif
                    ifdifi <arg3>, <edx>
                        mov edx, arg3
                        medx = 1
                    endif
                    ifnb <arg4>
                        ifidni <arg4>, <eax>
                            if meax eq 1
                            .err 2052       eax was overwritten
                            endif
                        endif
                        ifidni <arg4>, <ecx>
                            if mecx eq 1
                            .err 2052       ecx was overwritten
                            endif
                        endif
                        ifidni <arg4>, <edx>
                            if medx eq 1
                            .err  2052      edx was overwritten
                            endif
                        endif
                        ifdifi <arg4>, <ebx>
                            push ebx
                            mov ebx, arg4
                        endif
                    endif   
                endif   
            endif   
        endif   
       
        call algo
       
        ifnb <arg4>
            pop ebx
        endif
    ENDM



then writing this give you error:
    rcall myproc, 10, eax, edx, -1

Equations in Assembly: SmplMath

hutch--

 :biggrin:

64 bit !

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm64\include64\masm64rt.inc

  ; ||||||||||||||||||||||||||||||||||||||||||||||

    fcall MACRO procedure,arg1,arg2,arg3,arg4,arg5
      IFNB <arg5>
        .err
        %echo   ---------------------------
        %echo
        %echo   4 argument limit exceeded
        %echo   Use "invoke" for more than
        %echo   four (4) arguments
        %echo
        %echo   ---------------------------
        goto err_exit
      ENDIF
     
      IFNB <arg4>
        mov r9, arg4
      ENDIF

      IFNB <arg3>
        mov r8, arg3
      ENDIF

      IFNB <arg2>
        mov rdx, arg2
      ENDIF

      IFNB <arg1>
        mov rcx, arg1
      ENDIF

      call procedure
      goto exit_fcall

    :err_exit

    %echo
    %echo     *******************
    %echo     assembly terminated
    %echo      ignore following
    %echo     *******************
    %echo

    end       ;; terminate assembly here

    :exit_fcall
    ENDM

  ; ||||||||||||||||||||||||||||||||||||||||||||||

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    USING r12

    SaveRegs

    fcall SendMessage,0,WM_COMMAND,1,2,x    ; extra invalid argument

    waitkey
    RestoreRegs
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

hutch--

 :biggrin:

Here is a variation of a 64 bit fastcall macro. It may not be any more efficient but it works OK.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm64\include64\masm64rt.inc

  ; ||||||||||||||||||||||||||||||||||||||||||||||

    fcall MACRO procedure:REQ,args:VARARG

      LOCAL acnt

      acnt = argcount(args)
      IF acnt eq 5
        goto lbl5
      ELSEIF acnt eq 4
        goto lbl4
      ELSEIF acnt eq 3
        goto lbl3
      ELSEIF acnt eq 2
        goto lbl2
      ELSEIF acnt eq 1
        goto lbl1
      ELSEIF acnt eq 0
        goto lbl0
      ENDIF

    :lbl5
        .err
        %echo   ---------------------------
        %echo
        %echo   4 argument limit exceeded
        %echo   Use "invoke" for more than
        %echo   four (4) arguments
        %echo
        %echo   ---------------------------
        goto err_exit

    :lbl4
      mov r9, getarg(4,args)

    :lbl3
      mov r8, getarg(3,args)

    :lbl2
      mov rdx, getarg(2,args)

    :lbl1
      mov rcx, getarg(1,args)

    :lbl0
      call procedure
      goto exit_fcall

    :err_exit

    %echo
    %echo     *******************
    %echo     assembly terminated
    %echo      ignore following
    %echo     *******************
    %echo

    end       ;; terminate assembly here

    :exit_fcall
    ENDM

  ; ||||||||||||||||||||||||||||||||||||||||||||||

    .data
      itm1 db "1234567890123456789012345678901234567890",0
      itm2 db "                                        ",0
      ptxt dq itm1
      pbuf dq itm2

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    USING r12

    SaveRegs

    fcall szLen,ptxt
    fcall bcopy,ptxt,pbuf,rax

    conout pbuf, lf

    waitkey
    RestoreRegs
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

HSE

Equations in Assembly: SmplMath

Gunther

Quote from: hutch-- on November 05, 2022, 10:37:23 PM
:biggrin:

Here is a variation of a 64 bit fastcall macro. It may not be any more efficient but it works OK.

Yes, indeed. It works well. :thumbsup:
You have to know the facts before you can distort them.