News:

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

Main Menu

Hutch ML64 macros64.inc and UASM

Started by LiaoMi, August 30, 2018, 07:16:04 AM

Previous topic - Next topic

LiaoMi

Hi,

I figured out why the Hutch macros dont work :biggrin: :P Uasm doesn't understand the dot in the macro names, since we are committed to compatibility, I would like to suggest the introduction of a dot symbol definition in macros on UASM, just because the macro assembler supports this feature  ;) :icon_exclaim: What do you think about this?

Examples of macros that UASM does not understand


    .switch MACRO arg
    ;; ---------------------------------
    ;; checks the size and type of "arg"
    ;; ---------------------------------
      IF getattr(arg) eq LAB or getattr(arg) eq IMM
        % echo **************************************
        % echo Only a memory operand or a register is
        % echo allowed as the source in .switch macro
        % echo **************************************
        .err <parameter error>
        goto byebye
      ELSEIF getattr(arg) eq LOC or getattr(arg) eq GLO
        goto isvar
      ELSEIF getattr(arg) eq REG
        goto isreg
      ENDIF

    :isvar
      IF varsize(arg) eq 8
        .switch_macro arg,rax
      ELSEIF varsize(arg) eq 4
        .switch_macro arg,eax
      ELSEIF varsize(arg) eq 2
        .switch_macro arg,ax
      ELSE
        % echo Unknown arg
        .err
      ENDIF
      goto byebye

    :isreg
      IF regsize(arg) eq 8
        .switch_macro arg,rax
      ELSEIF regsize(arg) eq 4
        .switch_macro arg,eax
      ELSEIF regsize(arg) eq 2
        .switch_macro arg,ax
      ELSE
        % echo Unknown arg
        .err
      ENDIF

    :byebye
    ENDM

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

    .switch_macro MACRO _var:req, _reg:=<rax>
        mov _reg, _var
        $casstk CATSTR <_reg>, <#>, $casflg, <#>, $casstk
        $casvar equ _reg
        $casflg equ <0>                                 ;; 0 = emit an .if, 1 an .elseif
    ENDM

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

    .case MACRO _args:vararg                            ;; like Pascal: case id1. id4 .. id8, lparam, ...
                                                        ;; does an or (case1 || case2 || case3...)
      $cas textequ <>
      FOR $v, <_args>                                   ;; for each case
        t@ INSTR <$v>, <..>                             ;; range ?
        IF t@                                           ;; yes
          $LB SUBSTR <$v>, 1, t@-1                      ;; lbound = left portion
          $LB CATSTR <(>, $casvar, <!>=>, $LB, <)>      ;; ($casvar >= lbound)
          $UB SUBSTR <$v>, t@+2                         ;; ubound = right portion
          $UB CATSTR <(>, $casvar, <!<=>, $UB, <)>      ;; ($casvar <= ubound)
          $t CATSTR <(>, $LB, <&&> , $UB,<)>            ;; (($casvar >= $lb) && ($casvar <= $ub))
        ELSE                                            ;; no, it's a value (var/const)
          $t CATSTR <(>, $casvar, <==>, <$v>, <)>       ;; ($casvar == value)
        ENDIF
        $cas CATSTR <|| >, $t, $cas                     ;; or this case w/ others
      ENDM
      $cas SUBSTR $cas, 3                               ;; lose the extra "|| " in front
        IFIDN $casflg, <0>                              ;; 0 = 1'st case
          % .if $cas                                    ;; emit ".if"
        ELSE                                            ;; all others
          % .elseif $cas                                ;; emit ".elseif"
        ENDIF
        $casflg equ <1>                                 ;; NOT 1'st
    ENDM

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

    .default MACRO _default:vararg
        .else
        _default
    ENDM

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

    .endsw MACRO _cmd:vararg
        IFIDN $casstk, <>
            .err <endsw w/o switch>
        ELSE
            t@ INSTR $casstk, <#>
            $casvar SUBSTR $casstk, 1, t@-1
            $casstk SUBSTR $casstk, t@+1
            t@ INSTR $casstk, <#>
            $casflg SUBSTR $casstk, 1, t@-1
            IFIDN $casstk, <#>
                $casstk equ <>
            ELSE
                $casstk SUBSTR $casstk, t@+1
            ENDIF
            .endif
        endif
    ENDM


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

    .do MACRO
      do_macro
    ENDM

    .loop MACRO args
      bottom_evaluate args
    ENDM

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

;;    invoke MACRO fname:REQ,args:VARARG
;;      procedure_call fname,args
;;    ENDM


  ; -------------------------------

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

    .rept MACRO args
      top_evaluate args
    ENDM

    .endr MACRO
      te_end
    ENDM

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

; -------------------------------------------------------------------------
; *************************************************************************

    .return MACRO arg
      IF arg ne 0
        mov rax, arg
        ret
      ELSE
        xor rax, rax
        ret
      ENDIF
    ENDM

    .multiple_instruction MACRO delm:REQ,args:VARARG
      LOCAL arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg0
      LOCAL argA,agrB,argC,argD,argE,argF,cntr,flag

      cntr = 1                      ;; counter determined which buffer is being written to
      flag = 0                      ;; flag starts as clear

      arg1 equ <>
      arg2 equ <>
      arg3 equ <>
      arg4 equ <>
      arg5 equ <>
      arg6 equ <>
      arg7 equ <>
      arg8 equ <>
      arg9 equ <>
      arg0 equ <>
      argA equ <>
      argB equ <>
      argC equ <>
      argD equ <>
      argE equ <>
      argF equ <>

    ;; ---------------------------------
      FORC char,<args>
        IFIDN <char>,<delm>         ;; test if char is the delimiter
          IF flag eq 0
            cntr = cntr + 1         ;; only increment the counter if the flag is clear
          ENDIF
          flag = 1                  ;; set the flag so you only get 1 increment of cntr
          goto over
        ENDIF
        flag = 0                    ;; clear the flag when the next char is not a space

        IF cntr eq 1
          arg1 CATSTR arg1,<char>   ;;
        ELSEIF cntr eq 2
          arg2 CATSTR arg2,<char>   ;;
        ELSEIF cntr eq 3
          arg3 CATSTR arg3,<char>   ;;
        ELSEIF cntr eq 4
          arg4 CATSTR arg4,<char>   ;;
        ELSEIF cntr eq 5
          arg5 CATSTR arg5,<char>   ;;
        ELSEIF cntr eq 6
          arg6 CATSTR arg6,<char>   ;;
        ELSEIF cntr eq 7
          arg7 CATSTR arg7,<char>   ;;
        ELSEIF cntr eq 8
          arg8 CATSTR arg8,<char>   ;;
        ELSEIF cntr eq 9
          arg9 CATSTR arg9,<char>   ;;
        ELSEIF cntr eq 10
          arg0 CATSTR arg0,<char>   ;;
        ELSEIF cntr eq 11
          argA CATSTR argA,<char>   ;;
        ELSEIF cntr eq 12
          argB CATSTR argB,<char>   ;;
        ELSEIF cntr eq 13
          argC CATSTR argC,<char>   ;;
        ELSEIF cntr eq 14
          argD CATSTR argD,<char>   ;;
        ELSEIF cntr eq 15
          argE CATSTR argE,<char>   ;;
        ELSEIF cntr eq 16
          argF CATSTR argF,<char>   ;;
        ELSEIF cntr eq 17
          % echo *********************************************
          % echo ERROR : too many arguments, 16 argument limit
          % echo *********************************************
          .err < <<< too many arguments >>> >
          goto over
        ENDIF
      :over
      ENDM
    ;; ---------------------------------

      arg1
      arg2
      arg3
      arg4
      arg5
      arg6
      arg7
      arg8
      arg9
      arg0
      argA
      argB
      argC
      argD
      argE
      argF

    ENDM

; --------------------------------

    .mi MACRO args:VARARG           ;; multiple instructions
      .multiple_instruction :,args
    ENDM

    .ma MACRO args:VARARG           ;; multiple arguments
      .multiple_instruction #,args
    ENDM

    .mn MACRO args:VARARG           ;; alternate multiple arguments
      .multiple_instruction &,args
    ENDM

    .mx MACRO args:VARARG           ;; alternate multiple arguments
      .multiple_instruction ^,args
    ENDM

  ;; --------------------------------
  ;; These delimiters also work * $ |
  ;; --------------------------------

; -------------------------------------------------------------------------
; *************************************************************************

    .exit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM


ERROR: The process "mspdbsrv.exe" not found.
Translated Windows SDK 10 64 bits
windef WIN_INTERNAL manque ENDIF
macros64_Uasm.inc(2413) : Error A2222: Doesn't work with 32-bit segments: .exit
macros64_Uasm.inc(2413): Included by
  mywindow1.asm(32): Main line code
macros64_Uasm.inc(2415) : Error A2163: Unmatched macro nesting
macros64_Uasm.inc(2415): Included by
  mywindow1.asm(32): Main line code
mywindow1.asm: 97 lines, 1 passes, 186 ms, 0 warnings, 2 errors
Microsoft (R) Incremental Linker Version 14.14.26433.3
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1181: cannot open input file 'mywindow1.obj'
ERROR: The process "mspdbsrv.exe" not found.
Press any key to continue . . .

hutch--


jj2007

include \masm32\include\masm32rt.inc

option dotname
.yes macro
inkey "it does, of course"
endm

.code
start:
  .yes
  exit

end start


However, that won't help much, as discussed here: "it is possible to use both Microsoft ML64 (requiring .if eax}=edx) and UAsm (happy with .if eax>=edx) with identical sources and include files". Scroll down for "occasional switch" 8)

LiaoMi

Hi Hutch, Jochen,

UASM does not support "option dotname", I just checked it.

QuoteHowever, that won't help much, as discussed here: "it is possible to use both Microsoft ML64 (requiring .if eax}=edx) and UAsm (happy with .if eax>=edx) with identical sources and include files". Scroll down for "occasional switch" 8)

In this case it would help, I have compiled all the macros, except those listed above. Hutch did not use such constructs in his macro set, I'm not talking about other macros, such as  .if eax}=edx, we will have to correct this entry manually, and the dot works by default in macro assembler. Then, I can write any other similar macro with a dot without the parentheses type definitions, this is another level of compliance, at the code level, and not at the macro level. As I wrote in the first post
Quote"just because the macro assembler supports this feature"
. The final goal is not willing to support the macros of Vasiliy  ::) I hope that I clearly explained my thoughts  :biggrin:  :P  :redface:

jj2007

Quote from: LiaoMi on August 30, 2018, 05:57:13 PMUASM does not support "option dotname", I just checked it.
Check once more. I test my code before posting it...

LiaoMi

Once again, my test  8) Assemble with the latest version of uasm64  :eusa_boohoo:

.686
.MMX
.XMM
.x64

option casemap:none
option win64:11
option frame:auto
option stackbase:rsp
option dotname
;option proc:private
WIN32_LEAN_AND_MEAN equ 1
.nolist
.nocref


ERROR: The process "mspdbsrv.exe" not found.
Translated Windows SDK 10 64 bits
windef WIN_INTERNAL manque ENDIF
macros64_Uasm.inc(2413) : Error A2222: Doesn't work with 32-bit segments: .exit
macros64_Uasm.inc(2413): Included by
  mywindow1.asm(33): Main line code
macros64_Uasm.inc(2415) : Error A2163: Unmatched macro nesting
macros64_Uasm.inc(2415): Included by
  mywindow1.asm(33): Main line code
mywindow1.asm: 98 lines, 1 passes, 137 ms, 0 warnings, 2 errors
Microsoft (R) Incremental Linker Version 14.14.26433.3
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1181: cannot open input file 'mywindow1.obj'
ERROR: The process "mspdbsrv.exe" not found.
Press any key to continue . . .


I'm testing on a simple macro
    .exit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM

hutch--

 :biggrin:

There is an old expression in English that fits the bill here, "People in glass houses should not throw stones".

> "it is possible to use both Microsoft ML64 (requiring .if eax}=edx)

Look at this tangled mess in MasmBasic.

  For_ ct=0 To MyInts(?)-1
        test MyInts(ct), 1
        setne al
        movsx ecx, al
        Print #ecx, Str$("%__i ", MyInts(ct))

You appear to be confused with the distinction between win32 and win64, ML64 does not assembler 32 bit code.

In MASM 32 bit you would use,

  .if eax >= edx


This inherently is the problem of relying on legacy knowledge of 32 bit instead of writing true 64 bit, cat scratching about notation that you simply don't understand.

HSE

Quote from: LiaoMi on August 30, 2018, 06:51:28 PM
I'm testing on a simple macro
    .exit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM


You have a collition, because a lot of "dots-something" are new UAsm directives. You can disable that rebuildind UAsm after change directives names. In contrast Asmc allow you to disable all new directives using options for that (then AsmC work almost exactly like Masm)
Equations in Assembly: SmplMath

hutch--

I think you would have to ask John to add the MASM format DOT prefix as it is very useful in doubling the naming range. This has been reliable in MASM since before the 1990 MASM 6.0 so if the Watcom forks are supposed to be MASM compatible, they should be able to do this.

mov     ; intel mnemonic
.mov    ; macro

Many others as well.

.if
.If
.IF
; any form of IF in MASM is a conditional assembly directive.

LiaoMi

Quote from: HSE on August 30, 2018, 10:36:52 PM
Quote from: LiaoMi on August 30, 2018, 06:51:28 PM
I'm testing on a simple macro
    .exit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM


You have a collition, because a lot of "dots-something" are new UAsm directives. You can disable that rebuildind UAsm after change directives names. In contrast Asmc allow you to disable all new directives using options for that (then AsmC work almost exactly like Masm)

Hi HSE,
:t :eusa_dance: Absolutely right! That's exactly what I needed, I just renamed the name of the macro after the dot symbol and it works! The description of the error "Error A2222: Doesn't work with 32-bit segments: .exit" led me to doubt. excellent!

hutch--

The simplest approach is to write your own macros, although the Watcom forks claim to be MASM compatible, if they add capacity that differs the compatibility is lost.

I run into the same problem with a compiler that I use for some types of string work, so many common names are taken by the compiler so you have to keep finding other names.

    .exit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM

This is possible in ML64 because it is an unconfigured assembler so you can create your own dot prefix named macros without any problems. When the assembler uses that naming range with reserve words you have to find a new naming convention and there should be many that you can use.

@exit MACRO etc ....
.exit? MACRO etc ....
exit? MACRO etc ....

The general drift is to use a method that is consistent across the range of macros so they are easily recognised.

LiaoMi

Quote from: hutch-- on August 30, 2018, 10:17:23 PM
"People in glass houses should not throw stones".

Great expression!  :biggrin:

Quote@exit MACRO etc ....
.exit? MACRO etc ....
exit? MACRO etc ....

This macro definition looks beautiful  :P Microsoft in the past used a similar style, so we will be like the old fashion programmers  :t

hutch--

 :biggrin:

Here is the real McCoy, three original macro files from MASM 6.00 in 1990. I had to load them with the PWB editor and save them as text files. I still have this ancient stuff on a PIV that has XP on it. It cames out of a PIII archive I saved long ago.

hutch--

LiaoMi,

Give something like this a blast.

    .quit MACRO optvar:=<0>
      invoke ExitProcess,optvar
    ENDM

The trick is to get a list of the reserve words in UASM so you don't try and duplicate them then look for expressions that represent what you want to do with the macro. Terminating an application is an easy one as you can use any number of names. If UASM supports the dot prefix which I gather it does, you can use it when you are doing control flow things or low level items that are not covered by the UASM assembler.

You don't need macros for ".if", ".switch" and similar as I gather they are provided by UASM and there is some wisdom in not using dot prefixes for normal code components as they lose their easy readability if you use too many of them.

jj2007

IMHO the message Error A2222: Doesn't work with 32-bit segments: .exit indicates that this is a relic from 16-bit times; and indeed, 16-bit code containing .exit assembles just fine. With ML and UAsm btw, their behaviour is identical.