News:

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

Main Menu

FCALLTEST MACRO IMPROVEMENT

Started by GoneFishing, February 19, 2016, 09:21:52 PM

Previous topic - Next topic

GoneFishing

The macro is designed to emulate FASTCALL on Linux 64 bit .
It uses ISFLOAT? macro by QWORD.

In its current ( work in progress) state it supports up to 12 parameters, first  6 of which are passed through
rdi,rsi,rdx,rcx,r8,r9 registers while the others are pushed on the stack.
It checks if the argument is of unsupported type (float) ; if the function was not defined ; if number of parameters is greater than 12 . 
Currently all arguments should be QWORD-sized , no support / error checking for 8-,16-,32- bit ones and FPU / XMM parameters.
Here it is:

include ISFLOAT?.asm
     
OPTION CASEMAP:NONE
OPTION NOKEYWORD: <invoke>
invoke EQU FCALLTEST

EXTERN printf:PROC
EXTERN   puts:PROC
EXTERN   exit:PROC

REG1 EQU rdi
REG2 EQU rsi
REG3 EQU rdx
REG4 EQU rcx
REG5 EQU r8
REG6 EQU r9

str$ MACRO st:VARARG
     LOCAL lstr
   .data
     lstr DB st
          DB 0   
   .code
         EXITM < OFFSET lstr>
     ENDM
     
pusharg MACRO num:REQ,args:VARARG
        LOCAL cnt
        cnt = 0
        FOR arg, <args>
          cnt = cnt + 1
          IF cnt EQ num
            push arg
            EXITM
          ENDIF
        ENDM     
     ENDM
   
movarg MACRO reg, num:REQ,args:VARARG
       LOCAL cnt
       cnt = 0
       FOR arg, <args>
         cnt = cnt + 1
         IF cnt EQ num
             mov reg, arg
             EXITM <reg>
         ENDIF
       ENDM     
     ENDM

FCALLTEST MACRO procname:REQ , args:VARARG
          LOCAL argcnt, stackarg, current
          argcnt  = 0
           FOR arg, <args>
               argcnt = argcnt + 1
               IF ISFLOAT?(arg)
                  .err <*** argument &arg : floats are not supported yet ***>
               ENDIF
           ENDM
           current = argcnt         
    IFNDEF procname
          .err <procname IS NOT DEFINED>
    ENDIF     
       IF  argcnt GT 12
          .err  <ONLY 12 PARAMETERS ARE SUPPORTED>
    ENDIF       
       IF argcnt GT 6
          stackarg = argcnt - 6
          sub rsp, stackarg * 8     
          FORC i,<654321>
              IF stackarg EQ i
                 pusharg current, args
                 current  = current - 1
                 stackarg = stackarg - 1
              ENDIF
          ENDM   
    ENDIF   
          FORC i ,<654321>               
              IF current EQ i     
                 reg CATSTR <REG&i>
                 movarg reg,i,args
                 current = current - 1       
              ENDIF
          ENDM
    call  procname   
ENDM 


Obviously it needs floating point arguments support .
On linux XMM0-XMM7 are used to pass  floating point arguments ( see http://www.x86-64.org/documentation/abi-0.99.pdf, page 22) ,
RAX  with variable arguments passes information about the number of vector registers used.

List of requirements:

  • add support for floating point arguments
  • suggest further improvements


hutch--

I moved this as its a 64 bit code form, more use to tthe 64 bit crowd than bare learners.