News:

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

Main Menu

OPTION LITERALS in 32 bits

Started by aw27, August 12, 2017, 01:28:35 AM

Previous topic - Next topic

habran

Cod-Father

habran

remember, you don't need a .break because default option is SWITCHSTYLE:ASMSTYLE
so you can use:
option SWITCHSTYLE:ASMSTYLE ;this is a default
or
option SWITCHSTYLE:CSTYLE     ;this will not work without the .break

examples in previous posts are the ASMSTYLE
Cod-Father

habran

Hi aw27,
I have found out what was wrong in your first code, it was IFDEF, if you use IF instead it works
depending on USELITERALS  equ 0 or USELITERALS  equ 1 it will run desired code:

.386
.model Flat, C
  USELITERALS  equ 0

    IF  USELITERALS
     OPTION LITERALS:ON ; Allow string literals use in INVOKE
     printf PROTO :PTR, :PTR
    ELSE
      printf PROTO :PTR, :vararg
    ENDIF
     
     
     TRUE equ 1
     
     includelib \masm32\lib\ntdll.lib
     RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
     RtlInitAnsiString PROTO STDCALL :ptr, :ptr
     
     includelib \masm32\lib\msvcrt.lib
     
     includelib \masm32\lib\kernel32.lib
     ExitProcess proto STDCALL :dword
     
     _STRING struct
      _Length word ?
      _Maximumlength word ?
      _Buffer dword ?
     _STRING ends
     
     .data
     format db 'result: %d',13,10,0
     s1 db "someStr",0 ;
     s2 db "anotherStr",0 ;
     
     .code
     
     main proc
      LOCAL str1 : _STRING
    LOCAL str2 : _STRING

    IF  USELITERALS
    INVOKE RtlInitAnsiString, addr str1, "someStr"
    INVOKE RtlInitAnsiString, addr str2, "anotherStr"
    INVOKE RtlCompareString, addr str1, addr str2, TRUE
    INVOKE printf, "result: %d", eax
        ELSE
                INVOKE RtlInitAnsiString, addr str1, addr s1
      INVOKE RtlInitAnsiString, addr str2, addr s2
      INVOKE RtlCompareString, addr str1, addr str2, TRUE
      INVOKE printf, addr format, eax
      ENDIF
     
      INVOKE ExitProcess,0
main endp

end main
Cod-Father

jj2007

Yes, this one has bitten me occasionally (and Masm32 has several equates of this sort):
someswitch equ 0
IFDEF someswitch
  echo someswitch is defined
else
  echo you will NEVER reach this line
endif


better:
someswitch=0
IF someswitch
  echo someswitch is ON
else
  echo someswitch is OFF
endif

habran

Thanks JJ :t
I have found it out half logically half accidentally, however, that was a good lesson for the future 8)
It would be a painstaking job to rework the current well working code to separate PTR from CONSTANT in one function parameters. I don't say it is impossible but the question is: is it worth the effort given to make it work that way?  ::)
Anyway, if Johnsa doesn't share my opinion, he can "Go ahead, make my day" :lol:
Cod-Father

aw27

Actually what I said was:
"In the code below if I remove the semicolon from "USELITERALS equ 1" the problems start"
So, if it is not there it is not defined. It it is there, even if I put USELITERALS equ 0, it is defined.






habran

That is what we were talking about because IFDEF is not doing proper job in this case but IF
Cod-Father

aw27

Quote from: habran on August 19, 2017, 11:02:43 PM
That is what we were talking about because IFDEF is not doing proper job in this case but IF
If you are using "IF" does it work if you put
USELITERALS  equ 1

I think not, it appears that it will be equivalent to the IFDEF I used. Or is it escaping me something ?

habran

It works, why don't you try my last source from the post #17
just change USELITERALS equ 0 to  USELITERALS equ 1
The secret is to use IF instead of IFDEF

IFDEF works with system variables like IFDEF _MAC but not with constants, actually it doesn't care if it is 1 or 0, as long as it is defined it uses it as DEFINED while IF checks if it is TRUE or FALSE
This is from MSDN:

IFDEF
Grants assembly if name is a previously defined label, variable, or symbol.
IF
Grants assembly of if statements if expression1 is true (nonzero) or elseif statements if expression1 is false (0) and expression2 is true.

It gave me the idea to implement DEFINE and UNDEF in UASM for conditional assembly :idea:
It would give UASM more flexibility.
Cod-Father

jj2007

Quote from: habran on August 20, 2017, 05:44:12 AMIt gave me the idea to implement DEFINE and UNDEF in UASM for conditional assembly :idea:
It would give UASM more flexibility.

Don't make it a default option, though. While there are many people who dislike MASM for its bugs and its slowness, there are also many who simply wouldn't touch code that is only half compatible. Userbase is important, and it takes a very long time to accept that UAsm is a perfect clone...

Besides, the MySwitch=0 solution works perfectly, there is no need to change anything.

habran

It was easier than I thought :t
It will be implemented in macrolib.c
Have look at this example, with these two macros DEFINE and UNDEF both version can be assembled at ones.
Here is the source:

.386
.model Flat, C
 
  DEFINE MACRO a:req
  a  = 1
  ENDM

  UNDEF MACRO a:req
  a  = 0
  ENDM


   DEFINE USELITERALS
   IF  USELITERALS
     OPTION LITERALS:ON ; Allow string literals use in INVOKE
     printf PROTO :PTR, :PTR
    ELSE
      printf PROTO :PTR, :vararg
    ENDIF
     
     
     TRUE equ 1
     
     includelib \masm32\lib\ntdll.lib
     RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
     RtlInitAnsiString PROTO STDCALL :ptr, :ptr
     
     includelib \masm32\lib\msvcrt.lib
     
     includelib \masm32\lib\kernel32.lib
     ExitProcess proto STDCALL :dword
     
     _STRING struct
      _Length word ?
      _Maximumlength word ?
      _Buffer dword ?
     _STRING ends
     
     .data
     format db 'result: %d',13,10,0
     s1 db "someStr",0 ;
     s2 db "anotherStr",0 ;
     
     .code
     
     main proc
      LOCAL str1 : _STRING
    LOCAL str2 : _STRING

    IF  USELITERALS
    INVOKE RtlInitAnsiString, addr str1, "someStr"
    INVOKE RtlInitAnsiString, addr str2, "anotherStr"
    INVOKE RtlCompareString, addr str1, addr str2, TRUE
    INVOKE printf, "result: %d", eax
        ENDIF
        UNDEF USELITERALS
        IF  USELITERALS EQ 0
            INVOKE RtlInitAnsiString, addr str1, addr s1
      INVOKE RtlInitAnsiString, addr str2, addr s2
      INVOKE RtlCompareString, addr str1, addr str2, TRUE
      INVOKE printf, addr format, eax
      ENDIF
     
      INVOKE ExitProcess,0
main endp

end main


and here is disassembly:

     1: .386
     2: .model Flat, C
     3:   
     4:   DEFINE MACRO a:req
     5:   a  = 1
     6:   ENDM
     7:
     8:   UNDEF MACRO a:req
     9:   a  = 0
    10:   ENDM
    11:
    12:
    13:    DEFINE USELITERALS
    14:    IF  USELITERALS
    15:      OPTION LITERALS:ON ; Allow string literals use in INVOKE
    16:      printf PROTO :PTR, :PTR
    17:     ELSE
    18:       printf PROTO :PTR, :vararg
    19:     ENDIF
    20:     
    21:     
    22:      TRUE equ 1
    23:     
    24:      includelib \masm32\lib\ntdll.lib
    25:      RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
    26:      RtlInitAnsiString PROTO STDCALL :ptr, :ptr
    27:     
    28:      includelib \masm32\lib\msvcrt.lib
    29:     
    30:      includelib \masm32\lib\kernel32.lib
    31:      ExitProcess proto STDCALL :dword
    32:     
    33:      _STRING struct
    34:      _Length word ?
    35:      _Maximumlength word ?
    36:      _Buffer dword ?
    37:      _STRING ends
    38:     
    39:      .data
    40:      format db 'result: %d',13,10,0
    41:      s1 db "someStr",0 ;
    42:      s2 db "anotherStr",0 ;
    43:     
    44:      .code
    45:     
    46:      main proc
009E107C 55                   push        ebp 
009E107D 8B EC                mov         ebp,esp 
009E107F 83 EC 10             sub         esp,10h 
    47:      LOCAL str1 : _STRING
    48:      LOCAL str2 : _STRING
    49:
    50:      IF  USELITERALS
    51:      INVOKE RtlInitAnsiString, addr str1, "someStr"
009E1082 68 20 50 9E 00       push        9E5020h 
009E1087 8D 45 F8             lea         eax,[str1] 
009E108A 50                   push        eax 
009E108B E8 DE FF FF FF       call        _RtlInitAnsiString@8 (09E106Eh) 
    52:      INVOKE RtlInitAnsiString, addr str2, "anotherStr"
009E1090 68 28 50 9E 00       push        9E5028h 
009E1095 8D 45 F0             lea         eax,[str2] 
009E1098 50                   push        eax 
009E1099 E8 D0 FF FF FF       call        _RtlInitAnsiString@8 (09E106Eh) 
    53:      INVOKE RtlCompareString, addr str1, addr str2, TRUE
009E109E 6A 01                push        1 
009E10A0 8D 45 F0             lea         eax,[str2] 
009E10A3 50                   push        eax 
009E10A4 8D 45 F8             lea         eax,[str1] 
009E10A7 50                   push        eax 
009E10A8 E8 BB FF FF FF       call        _RtlCompareString@12 (09E1068h) 
    54:      INVOKE printf, "result: %d", eax
009E10AD 50                   push        eax 
009E10AE 68 3E 50 9E 00       push        9E503Eh 
009E10B3 E8 BC FF FF FF       call        _printf (09E1074h) 
009E10B8 83 C4 08             add         esp,8 
    55:         ENDIF
    56:         UNDEF USELITERALS
    57:         IF  USELITERALS EQ 0
    58:             INVOKE RtlInitAnsiString, addr str1, addr s1
009E10BB 68 0D 50 9E 00       push        9E500Dh 
009E10C0 8D 45 F8             lea         eax,[str1] 
009E10C3 50                   push        eax 
009E10C4 E8 A5 FF FF FF       call        _RtlInitAnsiString@8 (09E106Eh) 
    59:      INVOKE RtlInitAnsiString, addr str2, addr s2
009E10C9 68 15 50 9E 00       push        9E5015h 
009E10CE 8D 45 F0             lea         eax,[str2] 
009E10D1 50                   push        eax 
009E10D2 E8 97 FF FF FF       call        _RtlInitAnsiString@8 (09E106Eh) 
    60:      INVOKE RtlCompareString, addr str1, addr str2, TRUE
009E10D7 6A 01                push        1 
    60:      INVOKE RtlCompareString, addr str1, addr str2, TRUE
009E10D9 8D 45 F0             lea         eax,[str2] 
009E10DC 50                   push        eax 
009E10DD 8D 45 F8             lea         eax,[str1] 
009E10E0 50                   push        eax 
009E10E1 E8 82 FF FF FF       call        _RtlCompareString@12 (09E1068h) 
    61:      INVOKE printf, addr format, eax
009E10E6 50                   push        eax 
009E10E7 68 00 50 9E 00       push        9E5000h 
009E10EC E8 83 FF FF FF       call        _printf (09E1074h) 
009E10F1 83 C4 08             add         esp,8 
    62:      ENDIF
    63:     
    64:      INVOKE ExitProcess,0
009E10F4 6A 00                push        0 
009E10F6 E8 83 0F 00 00       call        _ExitProcess@4 (09E207Eh) 

Cod-Father

habran

JJ2007 :biggrin:
as you can see, these two macros will be implemented in next releases as macros in macrolib.c, however, if you insist to use some other assembler you can just use these macros direct in your source free of charges ;)
Our goal with UASM is not to create a clone of ml.exe or ml64.exe that would be such a waste of time and effort.
UASM is a modern assembler which is still able to assemble old sources from masm32 and newest from ml64, but also far far more advanced and capable.
We dislike tradition, conservatism and all kind of similar bullism :biggrin:   
Cod-Father

aw27

Quote from: habran on August 20, 2017, 05:44:12 AM
It works, why don't you try my last source from the post #17
just change USELITERALS equ 0 to  USELITERALS equ 1
The secret is to use IF instead of IFDEF

That is not the secret, the secret is that you changed the prototype of printf to make it work.  :icon_eek:
Actually, I was the first to mention that it would work if we change the prototype of printf. Of course, I was not saying that changing prototypes of functions to make uasm work was a solution, I was trying to provide leads to help fix the problem.

johnsa

After due consideration I will change vararg to allow string literals. I cannot see any reason for concern with doing so, it's very unlikely that someone would need or want to pass something like "abcd" to a vararg and expect it to be the numerical value, a string literal is far more likely and useful with option literals:on

That said Habran's additions with regards to define/undef are quite useful too so we'll keep both for more flexibility.

nidud

#29
deleted