News:

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

Main Menu

minimum problem with invoke macro

Started by HSE, April 03, 2021, 11:24:31 AM

Previous topic - Next topic

HSE

Hi Hutch!

I'm testing print functions from msvcrt.lib. Happen they read R8 an R9 even when values are bytes, words or dword and invoke macro correctly fill for example R8b and R9b. Then is necessary to clean the register previously:
      IF ssize GT 8                             ;; handle BYTE PTR
        lead SUBSTR <anum>,1,8
        IFIDNI lead,<BYTE PTR>
          xor qreg, qreg      ; <----
          mov breg, anum
          goto elbl
        ENDIF
      ENDIF

      IF ssize GT 8                             ;; handle WORD PTR
        lead SUBSTR <anum>,1,8
        IFIDNI lead,<WORD PTR>
          xor qreg, qreg      ; <----
          mov wreg, anum
          goto elbl
        ENDIF
      ENDIF

      IF ssize GT 9                             ;; handle DWORD PTR
        lead SUBSTR <anum>,1,9
        IFIDNI lead,<DWORD PTR>
          xor qreg, qreg      ; <----
          mov dreg, anum
          goto elbl
        ENDIF
      ENDIF


Same thing using directly subregisters:
  IF getattr(anum) EQ REG                           ;; REGISTER
        sreg = regsize(anum)
        IF sreg EQ 0
          .err
        ELSEIF sreg EQ 1
          xor qreg, qreg      ; <----
          mov breg, anum
          goto elbl
        ELSEIF sreg EQ 2
          xor qreg, qreg      ; <----
          mov wreg, anum
          goto elbl
        ELSEIF sreg EQ 4
          xor qreg, qreg      ; <----
          mov dreg, anum
          goto elbl
        ELSEIF sreg EQ 8
          mov qreg, anum
          goto elbl
        ENDIF
      ENDIF


Regards, HSE.
Equations in Assembly: SmplMath

hutch--

Hi Hector,

It might just be the time of day but I don't get what the problem is. The macro that the "invoke" wrapper calls fill each location with whatever the data size is and it clears the register or memory location first. That is not in the 64 bit ABI but it works well so I left it there.

HSE

Quote from: hutch-- on April 03, 2021, 12:36:21 PM
It might just be the time of day

   :biggrin:

Procedure_call in package don't clean registers, I writed that.

Perhaps tomorrow :thumbsup:
Equations in Assembly: SmplMath

Vortex

No any problem. Here is a quick example :

include \masm32\include64\masm64rt.inc

.data

string1 db 'rdx = %X',13,10
        db 'r8  = %X',13,10
        db 'r9  = %X',13,10,13,10,0
.code

start PROC

    mov     rdx,-1
    mov     r8,rdx
    mov     r9,rdx

    invoke  vc_printf,ADDR string1,\
            rdx,r8,r9

    mov     rdx,-1
    mov     r8,rdx
    mov     r9,rdx

    mov     dl,1
    mov     r8w,1
    mov     r9d,1  ; moving a DWORD clears
                   ; the HIDWORD of r9

    invoke  vc_printf,ADDR string1,\
            rdx,r8,r9

    invoke  ExitProcess,0

start ENDP

END


rdx = FFFFFFFF
r8  = FFFFFFFF
r9  = FFFFFFFF

rdx = FFFFFF01
r8  = FFFF0001
r9  = 1


HSE

Hi!
Perhaps was the day  :biggrin:, I forgot a lot:      IF getattr(anum) EQ REG                           ;; REGISTER
        sreg = regsize(anum)
        IF sreg EQ 0
          .err
        ELSEIF sreg EQ 1
          IFIDNI <breg>,<anum>
            and qreg, 0FFh
          ELSE
            xor qreg, qreg
            mov breg, anum
          ENDIF
          goto elbl
        ELSEIF sreg EQ 2
          IFIDNI <wreg>,<anum>
            and qreg, 0FFFFh
          ELSE
            xor qreg, qreg
            mov wreg, anum
          ENDIF
          goto elbl
        ELSEIF sreg EQ 4
          IFIDNI <dreg>,<anum>
            and qreg, 0FFFFFFh
          ELSE
            xor qreg, qreg
            mov dreg, anum
          ENDIF
          goto elbl
        ELSEIF sreg EQ 8
          IFIDNI <qreg>,<anum>
          ELSE
            mov qreg, anum
          ENDIF
          goto elbl
        ENDIF
      ENDIF

Quote from: Vortex on April 03, 2021, 08:28:32 PM
No any problem. Here is a quick example :
   i8xfmt  BYTE " %3d  %3d  %3d", 0, 0
    xmmtoa_args textequ <addr i8xfmt , byte ptr _testxmmx.i8[3], byte ptr _testxmmx.i8[4], byte ptr _testxmmx.i8[5]>
    %invoke vc_sprintf, pbuf, xmmtoa_args


Without modifications: i8x$(xmm6) = 1243652  1244421    6

Press any key to continue...


With modifications: i8x$(xmm6) =   4    5    6

Press any key to continue...


Regards, HSE.
Equations in Assembly: SmplMath

HSE

#5
Quote from: hutch-- on April 03, 2021, 12:36:21 PM
That is not in the 64 bit ABI ....

Apparently in Win ABI only must be stored QWORD size variables. Changing that (several things in macros64.inc), printf function is working:    xmmtoa_args textequ <pi8xfmt,sbyte ptr testxmmx.i8[0],sbyte ptr testxmmx.i8[ 1],sbyte ptr testxmmx.i8[ 2],sbyte ptr testxmmx.i8[ 3],\
sbyte ptr testxmmx.i8[4],sbyte ptr testxmmx.i8[5],sbyte ptr testxmmx.i8[6], sbyte ptr testxmmx.i8[ 7]>
    xmmtoa_args2 textequ <pi8xfmt,sbyte ptr testxmmx.i8[8],sbyte ptr testxmmx.i8[9],sbyte ptr testxmmx.i8[10],sbyte ptr testxmmx.i8[11],\
sbyte ptr testxmmx.i8[12],sbyte ptr testxmmx.i8[13],sbyte ptr testxmmx.i8[14],sbyte ptr testxmmx.i8[15]>

   xmmtoa_args textequ <ADDR u8xfmt, byte ptr testxmmx.u8[0], byte ptr testxmmx.u8[ 1],byte ptr testxmmx.u8[ 2], byte ptr testxmmx.u8[ 3],\
                                      byte ptr testxmmx.u8[4], byte ptr testxmmx.u8[ 5], byte ptr testxmmx.u8[ 6], byte ptr testxmmx.u8[ 7]>
    xmmtoa_args2 textequ <ADDR u8xfmt, byte ptr testxmmx.u8[8], byte ptr testxmmx.u8[ 9], byte ptr testxmmx.u8[10], byte ptr testxmmx.u8[11],\
                                       byte ptr testxmmx.u8[12], byte ptr testxmmx.u8[13], byte ptr testxmmx.u8[14], byte ptr testxmmx.u8[15]>




i8x$(xmm6) =   1  -2   3   4  -5   6   7   8   9  10 -11  12  13  14  15  16

u8x$(xmm6) =   1 254   3   4 251   6   7   8   9  10 245  12  13  14  15  16

Press any key to continue...
Equations in Assembly: SmplMath

hutch--

You can store from BYTE to QWORD at the same 64 bit location as the shadow space and stack locations are all 64 bit. With XMM data, you can either use the calling convention which allow 4 XMM registers xmm0 to xmm3 or from memory, the ABI allows 8 of the 16 registers to be used. Depending on what data you wish to pass, you could load data in XMM registers and also pass a normal argument list for other values.

HSE

Quote from: hutch-- on April 08, 2021, 08:33:36 AM
You can store from BYTE to QWORD at the same 64 bit location as the shadow space and stack locations are all 64 bit.
Yes, you are wright. Still you have to clean the qword position for this API functions. It's not clear what convention they follow, but modified invoke macro work well with examples64.

Quote from: hutch-- on April 08, 2021, 08:33:36 AM
With XMM data, you can either use the calling convention which allow 4 XMM registers xmm0 to xmm3 or from memory, the ABI allows 8 of the 16 registers to be used. Depending on what data you wish to pass, you could load data in XMM registers and also pass a normal argument list for other values.
The convention say xmm0-xmm3 must be used for floating point arguments if they are in 4 firsts places and "at same time" in registers . Printf readed from R8 and R9 in the test.
Anyway I'm not passing owords to this functions but passing bytes, sbytes, etc.
In your own procs you can be a little more creative  :biggrin: 
Equations in Assembly: SmplMath