The MASM Forum

64 bit assembler => UASM Assembler Development => Topic started by: aw27 on August 12, 2017, 01:28:35 AM

Title: OPTION LITERALS in 32 bits
Post by: aw27 on August 12, 2017, 01:28:35 AM
It appears that OPTION LITERALS does not work properly in 32 bits.
In the code below if I remove the semicolon from "USELITERALS equ 1" the problems start. Strings are accepted in RtlInitAnsiString  but produce garbage. printf does not accept the literal.


.386

;USELITERALS equ 1

.model Flat, C
option Casemap :None
IFDEF USELITERALS
OPTION LITERALS:ON ; Allow string literals use in INVOKE
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
printf PROTO :PTR, :vararg

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
IFDEF 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
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 12, 2017, 01:40:43 AM
But if I define the prototype of printf as "printf PROTO :PTR, :PTR" it works.
In this case the variation:
      INVOKE RtlInitAnsiString, addr str1, "someStr"
      INVOKE RtlInitAnsiString, addr str2, "anotherStr"
      INVOKE RtlCompareString, addr str1, addr str2, TRUE      
      INVOKE printf, "result: %d", eax
will work.
But this will not:
      INVOKE RtlInitAnsiString, addr str1, "someStr"
      INVOKE RtlInitAnsiString, addr str2, "anotherStr"
      INVOKE RtlCompareString, addr str1, addr str2, TRUE      
      INVOKE printf, addr format, eax

That is, we will be forced to use always literals on INVOKE.
So, it appears there are 2 problems:
1) Once you use literals on one parameter it expects ptr arguments on the following parameters.
2) You can not decide when to use literals or not once you subscribe the LITERALS option.

Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 12, 2017, 05:47:08 PM
Hi aw27 :biggrin:
That is interesting find you've got there :shock:
At the moment I am busy with the SWITCH-CASE-ENDSWITCH and Johnsa is still on holidays, if he doesn't return soon I'll look at that issue as soon as I finish that new stuff that I am working on.
The fix will be included in next release together with the new stuff as soon as Johnsa returns.
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 13, 2017, 02:37:47 AM
No worries, fortunately the default alternative OPTION LITERALS:OFF  works well :t
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on August 13, 2017, 05:24:31 AM
Hey,

(Still on holiday.. sort of) :)

The decision for string literals to only work with type PTR was intentional.. There was a lot of code where one might find something like this:

aFunction PROTO :DWORD

which was being called with

invoke aFunction, "abcd"

Technically string immediates were already supported as long as it fitted in the corresponding type, "A", "AB", "ABCD" etc.. So to avoid a) confusion and b) breaking existing code I used a combination that would
never have existed previously, no one would have a called a function with a type declared as PTR with a string/character immediate value.

As for the other issues that shouldn't happen and I will investigate if Habran doesn't beat me to it :)
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 13, 2017, 03:58:14 PM
Quote from: johnsa on August 13, 2017, 05:24:31 AM
The decision for string literals to only work with type PTR was intentional
The real problem is not that, I tried to explain it with the printf case.  ;)
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on August 13, 2017, 10:21:46 PM
Got it :)

Just wanted to make that clear for anyone who was trying to use them with existing prototypes.

Will get onto the other issues asap :)
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 15, 2017, 09:00:03 AM
Hi aw27,
If you use :printf PROTO :PTR, :vararg
the INVOKE printf, "result: %d", eax will not assemble
but printf PROTO :PTR, :PTR works fine ( see example below)
That means that Johnsa prevented an purpose that to occur because vararg can contain anyting
I'll leave it to him to decide if he will change it or not.

--- strliterals.asm ------------------------------------------------------------
     1: .386
     2:
     3: USELITERALS equ 1
     4:
     5: .model Flat, C
     6: option Casemap :None
     7: IFDEF USELITERALS
     8: OPTION LITERALS:ON ; Allow string literals use in INVOKE
     9: ENDIF
    10:
    11: TRUE equ 1
    12:
    13: includelib \masm32\lib\ntdll.lib
    14: RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
    15: RtlInitAnsiString PROTO STDCALL :ptr, :ptr
    16:
    17: includelib \masm32\lib\msvcrt.lib
    18: printf PROTO :PTR, :PTR
    19:
    20: includelib \masm32\lib\kernel32.lib
    21: ExitProcess proto STDCALL :dword
    22:
    23: _STRING struct
    24: _Length word ?
    25: _Maximumlength word ?
    26: _Buffer dword ?
    27: _STRING ends
    28:
    29: .data
    30: format db 'result: %d',13,10,0
    31: s1 db "someStr",0 ;
    32: s2 db "anotherStr",0 ;
    33:
    34: .code
    35:
    36: main proc
009B1010 55                   push        ebp 
009B1011 8B EC                mov         ebp,esp 
009B1013 83 EC 10             sub         esp,10h 
    37: LOCAL str1 : _STRING
    38: LOCAL str2 : _STRING
    39:       INVOKE RtlInitAnsiString, addr str1, "someStr"
009B1016 68 49 50 9B 00       push        9B5049h 
009B101B 8D 45 F8             lea         eax,[str1] 
009B101E 50                   push        eax 
009B101F E8 90 00 00 00       call        _RtlInitAnsiString@8 (09B10B4h) 
    40:       INVOKE RtlInitAnsiString, addr str2, "anotherStr"
009B1024 68 51 50 9B 00       push        9B5051h 
009B1029 8D 45 F0             lea         eax,[str2] 
009B102C 50                   push        eax 
009B102D E8 82 00 00 00       call        _RtlInitAnsiString@8 (09B10B4h) 
    41:       INVOKE RtlCompareString, addr str1, addr str2, TRUE     
009B1032 6A 01                push        1 
009B1034 8D 45 F0             lea         eax,[str2] 
009B1037 50                   push        eax 
009B1038 8D 45 F8             lea         eax,[str1] 
009B103B 50                   push        eax 
009B103C E8 6D 00 00 00       call        _RtlCompareString@12 (09B10AEh) 
    42:       INVOKE printf, "result: %d", eax
009B1041 50                   push        eax 
    42:       INVOKE printf, "result: %d", eax
009B1042 68 3E 50 9B 00       push        9B503Eh 
009B1047 E8 6E 00 00 00       call        _printf (09B10BAh) 
009B104C 83 C4 08             add         esp,8 
    43:
    44:       INVOKE RtlInitAnsiString, addr str1, "someStr"
009B104F 68 49 50 9B 00       push        9B5049h 
009B1054 8D 45 F8             lea         eax,[str1] 
009B1057 50                   push        eax 
009B1058 E8 57 00 00 00       call        _RtlInitAnsiString@8 (09B10B4h) 
    45:       INVOKE RtlInitAnsiString, addr str2, "anotherStr"
009B105D 68 51 50 9B 00       push        9B5051h 
009B1062 8D 45 F0             lea         eax,[str2] 
009B1065 50                   push        eax 
009B1066 E8 49 00 00 00       call        _RtlInitAnsiString@8 (09B10B4h) 
    46:       INVOKE RtlCompareString, addr str1, addr str2, TRUE     
009B106B 6A 01                push        1 
009B106D 8D 45 F0             lea         eax,[str2] 
009B1070 50                   push        eax 
009B1071 8D 45 F8             lea         eax,[str1] 
009B1074 50                   push        eax 
009B1075 E8 34 00 00 00       call        _RtlCompareString@12 (09B10AEh) 
    47:       INVOKE printf, addr format, eax
009B107A 50                   push        eax 
009B107B 68 00 50 9B 00       push        9B5000h 
009B1080 E8 35 00 00 00       call        _printf (09B10BAh) 
009B1085 83 C4 08             add         esp,8 
    48:
    49: INVOKE ExitProcess,0
009B1088 6A 00                push        0 
009B108A E8 35 10 00 00       call        _ExitProcess@4 (09B20C4h) 
--- No source file -------------------------------------------------------------

Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 15, 2017, 09:24:33 AM
Here is a simple solution without changing UASM code: 8)
Quote
IFDEF USELITERALS
   OPTION LITERALS:ON ; Allow string literals use in INVOKE
    printf PROTO :PTR, :PTR
ELSE
   printf PROTO :PTR, :vararg
ENDIF



--- strliterals.asm ------------------------------------------------------------
     1: .386
     2:
     3: USELITERALS equ 1
     4:
     5: .model Flat, C
     6: option Casemap :None
     7: IFDEF USELITERALS
     8: OPTION LITERALS:ON ; Allow string literals use in INVOKE
     9:     printf PROTO :PTR, :PTR
    10: ELSE
    11:    printf PROTO :PTR, :vararg
    12: ENDIF
    13:
    14: TRUE equ 1
    15:
    16: includelib \masm32\lib\ntdll.lib
    17: RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
    18: RtlInitAnsiString PROTO STDCALL :ptr, :ptr
    19:
    20: includelib \masm32\lib\msvcrt.lib
    21:
    22: includelib \masm32\lib\kernel32.lib
    23: ExitProcess proto STDCALL :dword
    24:
    25: _STRING struct
    26: _Length word ?
    27: _Maximumlength word ?
    28: _Buffer dword ?
    29: _STRING ends
    30:
    31: .data
    32: format db 'result: %d',13,10,0
    33: s1 db "someStr",0 ;
    34: s2 db "anotherStr",0 ;
    35:
    36: .code
    37:
    38: main proc
01291010 55                   push        ebp 
01291011 8B EC                mov         ebp,esp 
01291013 83 EC 10             sub         esp,10h 
    39: LOCAL str1 : _STRING
    40: LOCAL str2 : _STRING
    41: IFDEF USELITERALS
    42: INVOKE RtlInitAnsiString, addr str1, "someStr"
01291016 68 20 50 29 01       push        1295020h 
0129101B 8D 45 F8             lea         eax,[str1] 
0129101E 50                   push        eax 
0129101F E8 90 00 00 00       call        _RtlInitAnsiString@8 (012910B4h) 
    43: INVOKE RtlInitAnsiString, addr str2, "anotherStr"
01291024 68 28 50 29 01       push        1295028h 
01291029 8D 45 F0             lea         eax,[str2] 
0129102C 50                   push        eax 
0129102D E8 82 00 00 00       call        _RtlInitAnsiString@8 (012910B4h) 
    44: INVOKE RtlCompareString, addr str1, addr str2, TRUE
01291032 6A 01                push        1 
01291034 8D 45 F0             lea         eax,[str2] 
01291037 50                   push        eax 
01291038 8D 45 F8             lea         eax,[str1] 
0129103B 50                   push        eax 
0129103C E8 6D 00 00 00       call        _RtlCompareString@12 (012910AEh) 
    45: INVOKE printf, "result: %d", eax
01291041 50                   push        eax 
01291042 68 3E 50 29 01       push        129503Eh 
01291047 E8 6E 00 00 00       call        _printf (012910BAh) 
0129104C 83 C4 08             add         esp,8 
    46: ELSE
    47: INVOKE RtlInitAnsiString, addr str1, addr s1
    48: INVOKE RtlInitAnsiString, addr str2, addr s2
    49: INVOKE RtlCompareString, addr str1, addr str2, TRUE
    50: INVOKE printf, addr format, eax
    51: ENDIF
    52:
    53: INVOKE ExitProcess,0
0129104F 6A 00                push        0 
01291051 E8 6E 10 00 00       call        _ExitProcess@4 (012920C4h) 
--- No source file -------------------------------------------------------------
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 15, 2017, 07:53:17 PM
Thank you for the hints and heads up, habran  :t
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 15, 2017, 08:27:56 PM
 :biggrin:
New, exciting UASM2.39 is coming soon, with SWITCH-CASE-ENDSWITCH with all data stored in _DATA section
so that debugging makes easy, here is an example:

   mov eax,1003
.switch eax
    .case 300
    mov edx,300
    .case 1001
    mov edx,1
  .case 1002
    mov edx,2
  .case 1003
     mov edx,3
  .case 1004
    mov edx,5
  .case 1005
    mov edx,6
  .case 1006
    mov edx,7
  .case 1009
.case 1040
     mov  edx,1 
    .case 1041
    mov edx,1
  .case 1042
    mov edx,2
  .case 1043
     mov edx,3
  .case 1044
    mov edx,5
  .case 1045
    mov edx,6
  .case 1046
    mov edx,7
  .case 1049
.case 1099
     mov  edx,1 
    .case 1031
    mov edx,1
  .case 902
    mov edx,2
  .case 1083
     mov edx,3
  .case 1084
    mov edx,5
  .case 1085
    mov edx,6
  .case 1086
    mov edx,7
  .case 1089
.case 1090
     mov  edx,1 
    .case 1121
    mov edx,1
  .case 1092
    mov edx,2
  .case 1093
     mov edx,3
  .case 1094
    mov edx,5
  .case 1095
    mov edx,6
  .case 1056
    mov edx,7
  .case 1059
    .case 1011
    mov edx,1
  .case 1052
    mov edx,2
  .case 1053
     mov edx,3
  .case 1054
    mov edx,5
  .case 1055
    mov edx,6
  .case 1066
    mov edx,7
  .case 1069
.case 1070
     mov  edx,1 
    .case 1071
    mov edx,1
  .case 1102
    mov edx,2
  .case 1103
     mov edx,3
  .case 1104
    mov edx,5
  .case 1105
    mov edx,6
  .case 1106
    mov edx,7
  .case 1109
      mov edx,1109
.case 1100
     mov  edx,1 
    .case 1061
    mov edx,1
  .case 1012
    mov edx,2
  .case 1013
     mov edx,3
  .case 1014
    mov edx,5
  .case 1015
    mov edx,6
  .case 1016
    mov edx,7
  .case 1019
    mov edx,8
  .default
    mov edx,9
.endswitch


Debug:

   146:    mov eax,1003
011D11D6 B8 EB 03 00 00       mov         eax,3EBh 
   147: .switch eax
011D11DB E9 F4 01 00 00       jmp         WndProc+204h (011D13D4h) 
   148:     .case 300
   149:     mov edx,300
011D11E0 BA 2C 01 00 00       mov         edx,12Ch 
   150:     .case 1001
011D11E5 E9 17 02 00 00       jmp         WndProc+231h (011D1401h) 
   151:     mov edx,1
011D11EA BA 01 00 00 00       mov         edx,1 
   152:   .case 1002
011D11EF E9 0D 02 00 00       jmp         WndProc+231h (011D1401h) 
   153:     mov edx,2
011D11F4 BA 02 00 00 00       mov         edx,2 
   154:   .case 1003
011D11F9 E9 03 02 00 00       jmp         WndProc+231h (011D1401h) 
   155:      mov edx,3
011D11FE BA 03 00 00 00       mov         edx,3 
   156:   .case 1004
011D1203 E9 F9 01 00 00       jmp         WndProc+231h (011D1401h) 
   157:     mov edx,5
011D1208 BA 05 00 00 00       mov         edx,5 
   158:   .case 1005
011D120D E9 EF 01 00 00       jmp         WndProc+231h (011D1401h) 
   159:     mov edx,6
011D1212 BA 06 00 00 00       mov         edx,6 
   160:   .case 1006
011D1217 E9 E5 01 00 00       jmp         WndProc+231h (011D1401h) 
   161:     mov edx,7
011D121C BA 07 00 00 00       mov         edx,7 
   162:   .case 1009
011D1221 E9 DB 01 00 00       jmp         WndProc+231h (011D1401h) 
   163: .case 1040
011D1226 E9 D6 01 00 00       jmp         WndProc+231h (011D1401h) 
   164:      mov  edx,1 
011D122B BA 01 00 00 00       mov         edx,1 
   165:     .case 1041
011D1230 E9 CC 01 00 00       jmp         WndProc+231h (011D1401h) 
   166:     mov edx,1
011D1235 BA 01 00 00 00       mov         edx,1 
   167:   .case 1042
011D123A E9 C2 01 00 00       jmp         WndProc+231h (011D1401h) 
   168:     mov edx,2
011D123F BA 02 00 00 00       mov         edx,2 
   169:   .case 1043
011D1244 E9 B8 01 00 00       jmp         WndProc+231h (011D1401h) 
   170:      mov edx,3
011D1249 BA 03 00 00 00       mov         edx,3 
   171:   .case 1044
011D124E E9 AE 01 00 00       jmp         WndProc+231h (011D1401h) 
   172:     mov edx,5
011D1253 BA 05 00 00 00       mov         edx,5 
   173:   .case 1045
011D1258 E9 A4 01 00 00       jmp         WndProc+231h (011D1401h) 
   174:     mov edx,6
011D125D BA 06 00 00 00       mov         edx,6 
   175:   .case 1046
011D1262 E9 9A 01 00 00       jmp         WndProc+231h (011D1401h) 
   176:     mov edx,7
011D1267 BA 07 00 00 00       mov         edx,7 
   177:   .case 1049
011D126C E9 90 01 00 00       jmp         WndProc+231h (011D1401h) 
   178: .case 1099
011D1271 E9 8B 01 00 00       jmp         WndProc+231h (011D1401h) 
   179:      mov  edx,1 
011D1276 BA 01 00 00 00       mov         edx,1 
   180:     .case 1031
011D127B E9 81 01 00 00       jmp         WndProc+231h (011D1401h) 
   181:     mov edx,1
011D1280 BA 01 00 00 00       mov         edx,1 
   182:   .case 902
011D1285 E9 77 01 00 00       jmp         WndProc+231h (011D1401h) 
   183:     mov edx,2
011D128A BA 02 00 00 00       mov         edx,2 
   184:   .case 1083
011D128F E9 6D 01 00 00       jmp         WndProc+231h (011D1401h) 
   185:      mov edx,3
011D1294 BA 03 00 00 00       mov         edx,3 
   186:   .case 1084
011D1299 E9 63 01 00 00       jmp         WndProc+231h (011D1401h) 
   187:     mov edx,5
011D129E BA 05 00 00 00       mov         edx,5 
   188:   .case 1085
011D12A3 E9 59 01 00 00       jmp         WndProc+231h (011D1401h) 
   189:     mov edx,6
011D12A8 BA 06 00 00 00       mov         edx,6 
   190:   .case 1086
011D12AD E9 4F 01 00 00       jmp         WndProc+231h (011D1401h) 
   191:     mov edx,7
011D12B2 BA 07 00 00 00       mov         edx,7 
   192:   .case 1089
011D12B7 E9 45 01 00 00       jmp         WndProc+231h (011D1401h) 
   193: .case 1090
011D12BC E9 40 01 00 00       jmp         WndProc+231h (011D1401h) 
   194:      mov  edx,1 
011D12C1 BA 01 00 00 00       mov         edx,1 
   195:     .case 1121
011D12C6 E9 36 01 00 00       jmp         WndProc+231h (011D1401h) 
   196:     mov edx,1
011D12CB BA 01 00 00 00       mov         edx,1 
   197:   .case 1092
011D12D0 E9 2C 01 00 00       jmp         WndProc+231h (011D1401h) 
   198:     mov edx,2
011D12D5 BA 02 00 00 00       mov         edx,2 
   199:   .case 1093
011D12DA E9 22 01 00 00       jmp         WndProc+231h (011D1401h) 
   200:      mov edx,3
011D12DF BA 03 00 00 00       mov         edx,3 
   201:   .case 1094
011D12E4 E9 18 01 00 00       jmp         WndProc+231h (011D1401h) 
   202:     mov edx,5
011D12E9 BA 05 00 00 00       mov         edx,5 
   203:   .case 1095
011D12EE E9 0E 01 00 00       jmp         WndProc+231h (011D1401h) 
   204:     mov edx,6
011D12F3 BA 06 00 00 00       mov         edx,6 
   205:   .case 1056
011D12F8 E9 04 01 00 00       jmp         WndProc+231h (011D1401h) 
   206:     mov edx,7
011D12FD BA 07 00 00 00       mov         edx,7 
   207:   .case 1059
011D1302 E9 FA 00 00 00       jmp         WndProc+231h (011D1401h) 
   208:     .case 1011
011D1307 E9 F5 00 00 00       jmp         WndProc+231h (011D1401h) 
   209:     mov edx,1
011D130C BA 01 00 00 00       mov         edx,1 
   210:   .case 1052
011D1311 E9 EB 00 00 00       jmp         WndProc+231h (011D1401h) 
   211:     mov edx,2
011D1316 BA 02 00 00 00       mov         edx,2 
   212:   .case 1053
011D131B E9 E1 00 00 00       jmp         WndProc+231h (011D1401h) 
   213:      mov edx,3
011D1320 BA 03 00 00 00       mov         edx,3 
   214:   .case 1054
011D1325 E9 D7 00 00 00       jmp         WndProc+231h (011D1401h) 
   215:     mov edx,5
011D132A BA 05 00 00 00       mov         edx,5 
   216:   .case 1055
011D132F E9 CD 00 00 00       jmp         WndProc+231h (011D1401h) 
   217:     mov edx,6
011D1334 BA 06 00 00 00       mov         edx,6 
   218:   .case 1066
011D1339 E9 C3 00 00 00       jmp         WndProc+231h (011D1401h) 
   219:     mov edx,7
011D133E BA 07 00 00 00       mov         edx,7 
   220:   .case 1069
011D1343 E9 B9 00 00 00       jmp         WndProc+231h (011D1401h) 
   221: .case 1070
011D1348 E9 B4 00 00 00       jmp         WndProc+231h (011D1401h) 
   222:      mov  edx,1 
011D134D BA 01 00 00 00       mov         edx,1 
   223:     .case 1071
011D1352 E9 AA 00 00 00       jmp         WndProc+231h (011D1401h) 
   224:     mov edx,1
011D1357 BA 01 00 00 00       mov         edx,1 
   225:   .case 1102
011D135C E9 A0 00 00 00       jmp         WndProc+231h (011D1401h) 
   226:     mov edx,2
011D1361 BA 02 00 00 00       mov         edx,2 
   227:   .case 1103
011D1366 E9 96 00 00 00       jmp         WndProc+231h (011D1401h) 
   228:      mov edx,3
011D136B BA 03 00 00 00       mov         edx,3 
   229:   .case 1104
011D1370 E9 8C 00 00 00       jmp         WndProc+231h (011D1401h) 
   230:     mov edx,5
011D1375 BA 05 00 00 00       mov         edx,5 
   231:   .case 1105
011D137A E9 82 00 00 00       jmp         WndProc+231h (011D1401h) 
   232:     mov edx,6
011D137F BA 06 00 00 00       mov         edx,6 
   233:   .case 1106
011D1384 EB 7B                jmp         WndProc+231h (011D1401h) 
   234:     mov edx,7
011D1386 BA 07 00 00 00       mov         edx,7 
   235:   .case 1109
011D138B EB 74                jmp         WndProc+231h (011D1401h) 
   236:       mov edx,1109
011D138D BA 55 04 00 00       mov         edx,455h 
   237: .case 1100
011D1392 EB 6D                jmp         WndProc+231h (011D1401h) 
   238:      mov  edx,1 
011D1394 BA 01 00 00 00       mov         edx,1 
   239:     .case 1061
011D1399 EB 66                jmp         WndProc+231h (011D1401h) 
   240:     mov edx,1
011D139B BA 01 00 00 00       mov         edx,1 
   241:   .case 1012
011D13A0 EB 5F                jmp         WndProc+231h (011D1401h) 
   242:     mov edx,2
011D13A2 BA 02 00 00 00       mov         edx,2 
   243:   .case 1013
011D13A7 EB 58                jmp         WndProc+231h (011D1401h) 
   244:      mov edx,3
011D13A9 BA 03 00 00 00       mov         edx,3 
   245:   .case 1014
011D13AE EB 51                jmp         WndProc+231h (011D1401h) 
   246:     mov edx,5
011D13B0 BA 05 00 00 00       mov         edx,5 
   247:   .case 1015
011D13B5 EB 4A                jmp         WndProc+231h (011D1401h) 
   248:     mov edx,6
011D13B7 BA 06 00 00 00       mov         edx,6 
   249:   .case 1016
011D13BC EB 43                jmp         WndProc+231h (011D1401h) 
   250:     mov edx,7
011D13BE BA 07 00 00 00       mov         edx,7 
   251:   .case 1019
011D13C3 EB 3C                jmp         WndProc+231h (011D1401h) 
   252:     mov edx,8
011D13C5 BA 08 00 00 00       mov         edx,8 
   253:   .default
011D13CA EB 35                jmp         WndProc+231h (011D1401h) 
   254:     mov edx,9
011D13CC BA 09 00 00 00       mov         edx,9 
   255: .endswitch
011D13D1 EB 2E                jmp         WndProc+231h (011D1401h) 
011D13D3 90                   nop 
011D13D4 3D 2C 01 00 00       cmp         eax,12Ch 
011D13D9 7C F1                jl          WndProc+1FCh (011D13CCh) 
011D13DB 3D 61 04 00 00       cmp         eax,461h 
011D13E0 77 EA                ja          WndProc+1FCh (011D13CCh) 
011D13E2 50                   push        eax 
011D13E3 52                   push        edx 
011D13E4 8D 15 18 51 1D 01    lea         edx,ds:[11D5118h] 
011D13EA 2D 2C 01 00 00       sub         eax,12Ch 
011D13EF 0F B7 14 42          movzx       edx,word ptr [edx+eax*2] 
011D13F3 8D 05 3A 50 1D 01    lea         eax,ds:[11D503Ah] 
011D13F9 8B 04 90             mov         eax,dword ptr [eax+edx*4] 
011D13FC 5A                   pop         edx 
011D13FD 87 04 24             xchg        eax,dword ptr [esp] 
011D1400 C3                   ret 
   256:

The actual mechanic to calculate the jump is this:

   255: .endswitch
011D13D1 EB 2E                jmp         WndProc+231h (011D1401h) 
011D13D3 90                   nop 
011D13D4 3D 2C 01 00 00       cmp         eax,12Ch 
011D13D9 7C F1                jl          WndProc+1FCh (011D13CCh) 
011D13DB 3D 61 04 00 00       cmp         eax,461h 
011D13E0 77 EA                ja          WndProc+1FCh (011D13CCh) 
011D13E2 50                   push        eax 
011D13E3 52                   push        edx 
011D13E4 8D 15 18 51 1D 01    lea         edx,ds:[11D5118h] 
011D13EA 2D 2C 01 00 00       sub         eax,12Ch 
011D13EF 0F B7 14 42          movzx       edx,word ptr [edx+eax*2] 
011D13F3 8D 05 3A 50 1D 01    lea         eax,ds:[11D503Ah] 
011D13F9 8B 04 90             mov         eax,dword ptr [eax+edx*4] 
011D13FC 5A                   pop         edx 
011D13FD 87 04 24             xchg        eax,dword ptr [esp] 
011D1400 C3                   ret 
   256:

I have on purpose used a big gap between the lowest and highest case to show that there is no data in the  _CODE section
here is the listing which shows actual data used to calculate the jump:

00000000                    *    .data
00000354                    *   _TEXT ends
0000003A                    *   _DATA segment
                            *   assume cs:ERROR
0000003A  000000000000000000*   @C0006 dd @C000B, @C001D, @C000C, @C000D, @C000E, @C000F, @C0010, @C0011, @C0012, @C002B, @C003C, @C003D, @C003E, @C003F, @C0040, @C0041, @C001C, @C0013, @C0014, @C0015
0000008A  000000000000000000*    dd @C0016, @C0017, @C0018, @C0019, @C001A, @C002C, @C002D, @C002E, @C002F, @C0029, @C002A, @C003B, @C0030, @C0031, @C0032, @C0033, @C001E, @C001F, @C0020, @C0021
000000DA  000000000000000000*    dd @C0022, @C0023, @C0025, @C0026, @C0027, @C0028, @C001B, @C003A, @C0034, @C0035, @C0036, @C0037, @C0038, @C0039, @C0024
00000116  0000              *   ALIGN 4
00000118  000037003700370037*   @C0008 dw 0,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
0000017C  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
000001E0  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000244  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
000002A8  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
0000030C  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000370  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
000003D4  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000438  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
0000049C  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000500  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000564  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
000005C8  370037000100370037*    dw 55,55,1,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
0000062C  370037003700370037*    dw 55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55
00000690  370002000300040005*    dw 55,2,3,4,5,6,7,55,55,8,55,9,10,11,12,13,14,55,55,15,55,55,55,55,55,55,55,55,55,55,55,16,55,55,55,55,55,55,55,55,17,18,19,20,21,22,23,55,55,24
000006F4  3700370019001A001B*    dw 55,55,25,26,27,28,29,55,55,30,55,31,55,55,55,55,32,55,55,33,34,35,55,55,55,55,55,55,55,55,55,55,55,36,37,38,39,55,55,40,41,55,42,43,44,45,55,55,55,46
00000758  2F0037003000310032*    dw  47,55,48,49,50,51,52,55,55,53,55,55,55,55,55,55,55,55,55,55,55,54
00000000                    *   .code
00000784                    *   _DATA ends
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 15, 2017, 08:38:23 PM
This is now not any more Ferrari but Tesla Model S P100D ;)
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 15, 2017, 09:29:30 PM
Quote from: habran on August 15, 2017, 08:38:23 PM
This is now not any more Ferrari but Tesla Model S P100D ;)
Thank you for the clarification.  :exclaim:
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 15, 2017, 10:15:45 PM
It was my pleasure :biggrin:
I was always disappointed with the garbage which that HLL creates in the code section, even MSV$ does the same, now UASM jumped  far, far ahead, as AUDI says:"vorsprung durch technik" :t
The advantage of that is not only clear debug code but we can put more data there to make it faster and it will not bloat the code section.
I have increased span between lowest and highest case from 512 to 2048 and it can be all executed with a few instructions from the above post.
So, if you need a speed for big amount of cases it can span from 0 to 2048
UASM has a smart logic to use different kind of solution for different types of cases to keep data as small as possible without affecting the speed, however, smart programmer will chose wisely what cases to put together to create optimal code.
In my opinion every programmer is smart, stupid can not be programmer, they can only think that they are ;)
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 16, 2017, 08:17:53 AM
Johnsa is still on holidays so I decided to post a new UASM here for testing SWITCH hll
here is a 64 bit
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 16, 2017, 08:20:09 AM
here is the32 bit version
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 16, 2017, 08:33:44 AM
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
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 19, 2017, 07:14:50 PM
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
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on August 19, 2017, 07:45:55 PM
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
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 19, 2017, 08:57:44 PM
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:
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 19, 2017, 09:49:18 PM
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.





Title: Re: OPTION LITERALS in 32 bits
Post by: 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
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 19, 2017, 11:15:02 PM
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 ?
Title: Re: OPTION LITERALS in 32 bits
Post by: 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

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.
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on August 20, 2017, 06:28:29 AM
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.
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 20, 2017, 08:45:57 AM
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) 

Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 20, 2017, 02:20:57 PM
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:   
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on August 20, 2017, 02:42:39 PM
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.
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on August 21, 2017, 08:08:55 PM
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.
Title: Re: OPTION LITERALS in 32 bits
Post by: nidud on August 24, 2017, 09:39:49 PM
deleted
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 24, 2017, 11:44:45 PM
Good thinking, Nidud :biggrin:
I can see that PURGE directive can be quite useful, however, I am not familiar with PURGE directive, I never used it. Can you give me one example of its usage.
I am sure that DEFINE can be implemented in C source to be more useful. I did it with macro to see if it can find a purpose in ASM programming. If so, we can than extend its usage. I'd like to have it built in as assembly directive.

Title: Re: OPTION LITERALS in 32 bits
Post by: nidud on August 25, 2017, 12:24:33 AM
deleted
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on August 25, 2017, 06:23:50 AM
I have implemented it  and works well. :t
The advantage is that it reports an error if the variable is not defined, while macro doesn't :eusa_clap:
DEFINE macro is fine in that regard and it can stay as macro.
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on August 25, 2017, 10:30:12 PM
Hey,

Right so we've put in some other changes to 2.39 and fixes apart from the really cool DEFINE/UNDEF directives which now means BOTH of these styles work simultaneously with option literals:on



.386

.model Flat, C
option Casemap :None
OPTION LITERALS:ON ; Allow string literals use in INVOKE

TRUE equ 1

includelib c:\masm32\lib\ntdll.lib
RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
RtlInitAnsiString PROTO STDCALL :ptr, :ptr

includelib c:\masm32\lib\msvcrt.lib
printf PROTO :PTR, :vararg

includelib c:\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,"%s",13,10,0
s1 db "someStr",0 ;
s2 db "anotherStr",0 ;

.code

main proc
LOCAL str1 : _STRING
LOCAL str2 : _STRING

INVOKE RtlInitAnsiString, addr str1, "someStr"
INVOKE RtlInitAnsiString, addr str2, "anotherStr"
INVOKE RtlCompareString, addr str1, addr str2, TRUE
INVOKE printf, "result: %d\n%s\n", eax, "test"

INVOKE RtlInitAnsiString, addr str1, addr s1
INVOKE RtlInitAnsiString, addr str2, addr s2
INVOKE RtlCompareString, addr str1, addr str2, TRUE
INVOKE printf, addr format, eax, addr s1


INVOKE ExitProcess,0

main endp

end main


Title: Re: OPTION LITERALS in 32 bits
Post by: hutch-- on August 25, 2017, 11:41:46 PM
Good modification John.  :t
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 06, 2017, 09:59:25 AM
include \masm32\include\masm32rt.inc

OPTION LITERALS:ON

.code
start:

  invoke WriteConsole, rv(GetStdHandle, STD_OUTPUT_HANDLE), "this is a string", 16, 0, 0
  invoke WriteConsole, rv(GetStdHandle, STD_OUTPUT_HANDLE), cfm$("this\nis a\nstring\n"), 20, 0, 0

  inkey "ok?"
  exit

end start


The first WriteConsole line chokes withError A2145: INVOKE argument type mismatch: argument 2
Tmp_File.asm(8) : Error A2274: Constant value too large: 74686973206973206120737472696E67h


Which syntax would work correctly?

The second line works fine with version 2.39, not surprisingly - after all, cfm$() is a well-tested Masm32 macro. Besides, it remains compatible with MASM, in contrast to the first line.

However, with version 2.38 of 2 August, it producessiht
a si
gnirts
?ko
;)
Title: Re: OPTION LITERALS in 32 bits
Post by: aw27 on September 06, 2017, 10:16:31 AM
@JJ,
The team has said that it is necessary the argument to be a pointer to use a literal.
The prototypes in the include directory are not made for type checking, which is a pity.
Title: Re: OPTION LITERALS in 32 bits
Post by: hutch-- on September 06, 2017, 10:49:14 AM
My comment on some of the development is that it seems to be going in the wrong direction, you have three aspects of code production in a MACRO assembler.

1. The mnemonic cruncher, IE, the assembler.
2. The MACRO engine and its capacity to write perfect assembler.
3. The dedicated libraries that can be used with the assembler.

If you maintain this set of distinctions, you can concentrate on the main work which is the assembler where if you start to blur this set of distinctions, you are starting to write a compiler. There is value in providing .IF blocks, .SWITCH blocks, call automation and the like as it improves the throughput of shovelling through high level API and similar styles of code which in turn leaves you with more time to write the stuff that matters, genuinely high speed pure mnemonic code.

Running as open an architecture as possible is the best option for an assembler where restricting the format to produce high level code is a mistake that goes in the direction of a compiler. I see that John and Habran have done some very good work in the development of UASM and I would hate to see it go into the direction of a pseudo compiler, the drift of my comments is make it into a grunty pure "can do" assembler and leave algorithm design to the libraries and macro engine.
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 06, 2017, 12:36:37 PM
Agreed :t

UAsm is an extremely valuable project, as it offers the full functionality of MASM at much higher speed (3x), at a time when Microsoft cripples ML64 to something that can be used by a compiler but sucks from a programmer's point of view.

OPTION LITERALS may be useful for some people, but if my code gets incompatible with assemblers that are still widely used by others, then I may have a problem; if the libraries need to be rewritten (:DWORDs to pointers...), I have a big problem. And there is absolutely no need for this fight: In the rare occasions when I have to pass a literal string to an API, I can use
invoke someapi, chr$("Hello World")  ; Masm32
invoke someapi, cfm$("Hello World\x")
invoke someapi, chr$("Hello World")  ; MasmBasic


What makes me reluctant at this moment to recommend UAsm (but I still do recommend it!) is this juggling with wild options, and the implicit accusation "why, didn't you read point 3.5.6, options xyz, of that nice manual that I wrote for you?".  It is a tool, it is supposed to be compatible with everything I've coded so far with MASM. It should do its job, nothing else. And I fully agree with Hutch: I really don't need yet another C compiler.
Title: Re: OPTION LITERALS in 32 bits
Post by: hutch-- on September 06, 2017, 01:44:59 PM
 :biggrin:

> invoke someapi, chr$("Hello World")


Or write a decent MACRO that allows,
invoke someapi, "Hello World"
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on September 06, 2017, 06:58:33 PM
It's always a challenge to come up with new features while maintaining the compatibility. That is the main reason for all the extra option settings.
For general use where you may want to be fully masm compatible I'd leave option literals off and use macros instead, we could/should even bundle these into the built-in macro library?

Where I personally saw the literals being useful is when you're writing a lot of custom code that deals with string processing, in which case you can easily switch literals on and then back off again.

OPTION LITERALS:ON

invoke catStr, "result is: ", ADDR resultmsg
invoke replaceItem, ADDR curString, "rd",  "road"
invoke replaceItem, ADDR curString, "rod",  "road"
invoke replaceItem, ADDR curString, "roads",  "road"

and so on.. while it's possible to use the macro method, this a) looks slightly neater and b) re-uses existing string data to reduce data bloat.. so there'd only be a single instance of "road" in this example.

Everything we do we will always try to make work in a way which is either compatible, or extended via an option of some sort.. The problem is at some point, if you start using features it will become incompatible with masm.. like switch, floating point hll comparison, conditional flags, improved union initialization and so on.. I can't see any way around this apart from being knowledgeable enough to know that if you may require that level of compatibility with other assemblers use the features sparingly or not at all.

To say that we shouldn't add these features as it breaks masm compatibility is sort of a bit defeatist, if we do that we cannot add most of the nice to have or useful stuff at all.
We also mustn't forget that we're building up a lot of use on the Linux front where compatibility with masm is non-issue, there we have users who may want us to make it nasm or gas compatible!

You cannot please everyone all of the time :)

Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 06, 2017, 09:12:32 PM
Quote from: johnsa on September 06, 2017, 06:58:33 PMTo say that we shouldn't add these features as it breaks masm compatibility is sort of a bit defeatist, if we do that we cannot add most of the nice to have or useful stuff at all.

John,

You and Habran are doing an excellent job, no doubt. And I am not against new features, but one must be careful not to break existing code. For example, a dedicated new macro library is a good thing, but it can be a nightmare if it intrudes into the namespace of an existing library. Imagine, for example, that UAsm supplies a macro library that understands
print str$("The number is %i\n", eax)

This is Masm32 SDK syntax...

This is why the default option should remain "fully compatible, no extra macros".
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on September 07, 2017, 06:09:11 PM
In terms of the macro library that is ok. The macro library is evaluated before any actual source code, so if you include macros which overlap with stuff in the library it simply replaces the library with your version of the said macro. So as long as the intention and use of the macro is equivalent then it shouldn't affect the outcome. The ones we've included so far are compatible with the implementations from MASM32, granted there are only a few so far but I agree with you 100% if we add a built-in one it should conform so that code written for assembly under ML using MASM32 macros should be identical under UASM with the built-in library. :)
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 07, 2017, 07:37:50 PM
Quote from: johnsa on September 07, 2017, 06:09:11 PMif you include macros which overlap with stuff in the library it simply replaces the library with your version of the said macro.

Sounds ok. How do you handle the case when UAsm has a built-in foo macro, and Masm32 sdk uses
Ifndef foo
  foo macro ...
Endif

?

Testcode:include \masm32\include\masm32rt.inc
.686p
.xmm
ifdef ASDOUBLExxxx
.err <already defined> ; without the xxxx, this error will be triggered
else
  ASDOUBLE macro xmmreg
EXITM FP8(1111.1111)         ; triggers "not equal"
  ENDM
endif
.code
start:
  movlps xmm0, FP8(123.456)
  movaps xmm3, xmm0
  .if (xmm0 == ASDOUBLE(xmm3))
inkey "equal, built-in mlib macro is active"
  .else
inkey "user's macro is active"
  .endif
  exit
end start
Title: Re: OPTION LITERALS in 32 bits
Post by: hutch-- on September 08, 2017, 12:06:47 AM
This may be virtuous if you are trying to remain compatible with 32 bit MASM but for 64 bit code, either for Windows or Linux you really need a completely different set of macros and here I would be inclined to tweak the macro engine for 64 bit code without having to remain MASM compatible. The old MASM macro engine can be coaxed to do most things with enough dedication but I would imagine that you can do a lot better in a brave new world of 64 bit code.
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on September 08, 2017, 06:24:39 PM
Agreed Hutch, for now we've just kept the set quite small using the ones that I didn't think would really change much between 32/64. As always I welcome suggestions for inclusions etc.. the 32bit and 64bit macro library implementations are separated out, so we can easily have totally different implementations for each.

In the IFDEF case that JJ mentions I believe that would skip the custom implementation as it would already be defined.
1) Assuming the macros are the same, then there should be no problem.
2) Alternatively, you might have to disable to macro library -nomlib option.
3) We could add a built-in variable which gives the state of the macro library's inclusion and the IFDEF could be extended to check that  as well. ?
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 08, 2017, 06:59:53 PM
Quote from: johnsa on September 08, 2017, 06:24:39 PMIn the IFDEF case that JJ mentions I believe that would skip the custom implementation as it would already be defined.
1) Assuming the macros are the same, then there should be no problem.
2) Alternatively, you might have to disable to macro library -nomlib option.
3) We could add a built-in variable which gives the state of the macro library's inclusion and the IFDEF could be extended to check that  as well. ?

1) right, but unrealistic - why build your own macro if there is one that works fine?
2) that would disable the whole UAsm macro lib
3) more precisely, let IFDEF believe that the built-in macros and constants are undefined (I can't see a case where that would cause problems)

This is certainly an exotic problem, but MASM has a known namespace that hasn't changed for decades. Extending that namespace with a user's macro library like the Masm32 macros.asm or MasmBasic is one thing, hard-coding new names into the assembler itself is a different thing.
Title: Re: OPTION LITERALS in 32 bits
Post by: habran on September 08, 2017, 07:38:17 PM
We can use now a new feature in UASM: UNDEF 8)
one example:
IFDEF FP4
UNDEF FP4
ENDIF
and then change it as we want
however, it is not necessary in this case because you can write your own FP4 which will override the one from the macrolib. I have just given an example of UNDEF usage
Title: Re: OPTION LITERALS in 32 bits
Post by: jj2007 on September 08, 2017, 09:32:47 PM
Undef is a nice feature, but my concern is a different one: There are moments where you ask "is the macro already defined?", and if the answer is yes, you use it, otherwise you define it and you launch an initialisation process. Anyway, don't bother with that, the -nomlib option will do the job.
Title: Re: OPTION LITERALS in 32 bits
Post by: johnsa on September 09, 2017, 01:08:38 AM
Quote from: jj2007 on September 08, 2017, 09:32:47 PM
Undef is a nice feature, but my concern is a different one: There are moments where you ask "is the macro already defined?", and if the answer is yes, you use it, otherwise you define it and you launch an initialisation process. Anyway, don't bother with that, the -nomlib option will do the job.

Assuming we only include macros in the library that have extremely unique names or where the names are common-place have exactly the same result as masm32 familiar users would be expecting then that should be ok. There might be a way to include the macro library stuff in some sort of special scope/namespace so that it's always unique.. that was sort of where I wanted to get to with introducing namespace support in UASM, but even then that wouldn't be masm compatible no matter what namespace resolution operator we use.
Title: Re: OPTION LITERALS in 32 bits
Post by: hutch-- on September 09, 2017, 02:57:38 AM
You may think I have an unusual view on this subject but if the macro engine can do what MASM in 32 bit does, then it may be useful but I would not cripple it to a 1990 design which masm up to the current 64 bit version has. Have MASM compatibility if you want it but be able to either turn it off OR have extra stuff that MASM never supported. You would not want to emulate MASM in 64 bit so there is no reason why you should restrict UASM to that age of design.

There are things that particularly irked me when setting up macros for 64 bit MASM, to make it more flexible you need to expand macros called by other macros inline rather than do them all before the calling macro. As far as which macros to use, it would be a lot simpler if it was left to which set of macros were used so you could have a MASM compatible set of macros, a more advanced and flexible set of macros and in 64 bit a UASM specific set of macros and none of these need to be embedded in the assembler itself. Leave it up to the punter using the assembler to pick which macros to use.

There is no problem providing macros for the punters to use as separate include files as this allows the punter to write as many of their own as they like but I suggest it is a mistake to embed a set of macros in the assembler itself.