Author Topic: #IF  (Read 1953 times)

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
#IF
« on: June 15, 2018, 06:29:57 AM »
Hallo
I'm still working in the translation of header files to asm http://masm32.com/board/index.php?topic=6812.msg76894#msg76894.
ATM I have a working program that that converts tons of  files, which I'm checking now.
I found a problem with lines like this:
Code: [Select]
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
The translation looks like
Code: [Select]
ifndef defined
  defined macro x
    ifdef x
      exitm <-1>
    else
      exitm <0>
    endif
  endm
endif

if defined(_MSC_VER) and (_MSC_VER ge 1020)

This code doesn't work in asm, since if _MSC_VER is not defined, the second condition is still checked producing a compilation error. This behavior is also present in ML, which I think is not correct.

Any chance to change that or to figure out a workaround?

Biterider

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #1 on: June 15, 2018, 12:16:46 PM »
instead of :if defined(_MSC_VER) and (_MSC_VER ge 1020)
it could be written as:
   if defined(_MSC_VER)
      if _MSC_VER ge 1020
           statement...
      endif
   endif

However, maybe someone comes with better idea.
Cod-Father

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
Re: #IF
« Reply #2 on: June 15, 2018, 03:40:54 PM »
Hi Habran
That's right. However, more complex statements that uses #elif or #else can not be written this way.
That is why I asked for support on your side.  ::)

As far as I can see, such a change should not brake existing code...

Biterider

jj2007

  • Member
  • *****
  • Posts: 8832
  • Assembler is fun ;-)
    • MasmBasic
Re: #IF
« Reply #3 on: June 15, 2018, 05:24:48 PM »
Workaround:
_MSC_VER=0  ; somewhere at the top of your source

... code that may set _MSC_VER ...

if _MSC_VER ge 1020
  ...

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #4 on: June 15, 2018, 05:41:50 PM »
I have tested the first version and it works as expected:
if defined(_MSC_VER) and (_MSC_VER ge 1020)

try to play with it.
I have used :
Code: [Select]
if defined(_MSC_VER) and (_MSC_VER ge 1020)
  .ERR <There is something wrong with that statement>
endif
and than tried this:
Code: [Select]
if defined(_MSC_KER) and (_MSC_VER ge 1020)  ; note _MSC_KER is fake
  .ERR <There is something wrong with that statement>
endif

so, in the second case it should throw an error but it doesn't

but with this it does throw an error:
Code: [Select]
if defined(_MSC_VER) and (_MSC_VER le 1020) ; note I have used le here
  .ERR <Tornero>
endif
Cod-Father

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
Re: #IF
« Reply #5 on: June 15, 2018, 06:03:31 PM »
Hi
@JJ: the windows header files is a house of cards that builds heavily upon the existence (definition) of symbols. If we define all of them, the result will not be the same, since we will include things we are not interested in. In case we do, we accept that all generated inc files will need to be corrected by hand (~2000 files for Win10)

@habran
I use the following test case
Code: [Select]
ifndef defined
  defined macro x
    ifdef x
      exitm <-1>
    else
      exitm <0>
    endif
  endm
endif

;Symbol equ 1

if defined(Symbol) and (Symbol eq 1)
  echo 1
else
  echo 2
endif


If Symbol is commened out, I get a compilation error (Error A2102: Symbol not defined : Symbol)

Biterider

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #6 on: June 15, 2018, 06:55:18 PM »
I can see now where is the problem ::)
I'll see what I can do about it ;)

However, it will take some time :dazzled:
Cod-Father

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: #IF
« Reply #7 on: June 15, 2018, 11:24:57 PM »
This code doesn't work in asm, since if _MSC_VER is not defined,

You cant use the Windows include files without defining _MSC_VER.

https://msdn.microsoft.com/en-us/library/b0084kay.aspx

sdkddkver.h may or may not define _MSC_VER so I use the following logic:
Code: [Select]
;
; Set Windows version
;
include sdkddkver.inc

ifndef _MSC_VER
;;
;; _MSC_VER Defined as an integer literal that encodes the major and minor number
;; elements of the compiler's version number. The major number is the first
;; element of the period-delimited version number and the minor number is the
;; second element. For example, if the version number of the Visual C++ compiler
;; is 17.00.51106.1, the _MSC_VER macro evaluates to 1700. Enter cl /? at the
;; command line to view the compiler's version number. This macro is always defined.
;;
_MSC_VER equ 1200 ;; Visual C++ version 12.0
endif
« Last Edit: June 16, 2018, 12:33:02 AM by nidud »

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
Re: #IF
« Reply #8 on: June 16, 2018, 12:17:06 AM »
Hi nidud
There are hundreds of such cases in the header files. I chose the first one I found.
You're right with _MSC_VER, but I think there are cases where the undefined symbols are a problem.

Biterider

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: #IF
« Reply #9 on: June 16, 2018, 12:34:10 AM »
Well, there are some logic in what you say given it's possible to use .if eax && [eax].foo > 1, but if you define everything you actually need on order to use it the situation may change.

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #10 on: June 16, 2018, 04:52:09 AM »
I agree with Biterider,
even if there are no undefined symbols in those headers it is obvious that assembler behaves inappropriate in such cases. 
Cod-Father

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #11 on: June 16, 2018, 05:53:56 AM »
The problem can be solved with definedmacro
it get computed: if 0 and (_MSC_KER le 1020)
Cod-Father

Biterider

  • Member
  • **
  • Posts: 241
  • ObjAsm32 - ObjAsm64
    • ObjAsm64
Re: #IF
« Reply #12 on: June 16, 2018, 06:34:28 AM »
Hi Habran
Can you be more explicit?


Thanks, Biterider

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #13 on: June 16, 2018, 07:32:36 AM »
defined macro returns 0 but it doesn't tell assembler not to continue.
In that case defined doesn't return a proper result.
if 0 and (_MSC_KER le 1020)
if 1 and (_MSC_KER le 1020)
these both cases will continue with AND
Cod-Father

habran

  • Member
  • *****
  • Posts: 1178
    • uasm
Re: #IF
« Reply #14 on: June 16, 2018, 07:42:58 PM »
I have succeeded to prevent error for the case that symbol is not defined, it will work only with "if 0 and ...".
The fix is in expreval.c starting with line 1169:
Code: [Select]
                DebugMsg1(("get_operand(%s): symbol %s not defined, pass > 1, curr proc=>%s<, \n", tokenarray[i].string_ptr, tmp, CurrProc ? CurrProc->sym.name : "NULL" ));
                if ( opnd->type && *opnd->type->name ) {
                    fnEmitErr( MEMBER_NOT_DEFINED, opnd->type->name, tmp );
                } else {
                  if ((0 == _memicmp(tokenarray[0].tokpos, "if", 2)) &&
                      (0 == _memicmp(tokenarray[1].tokpos, "0", 1)) &&
                      (0 == _memicmp(tokenarray[2].tokpos, "and", 3)))
                    ;//skip it
                  else
                    fnEmitErr( SYMBOL_NOT_DEFINED, *(tmp+1) == '&' ? "@@" : tmp );
                }
                return( ERROR );
            }
#if ALIAS_IN_EXPR /* v2.04b: added */
the fix is:
Code: [Select]
                  if ((0 == _memicmp(tokenarray[0].tokpos, "if", 2)) &&
                      (0 == _memicmp(tokenarray[1].tokpos, "0", 1)) &&
                      (0 == _memicmp(tokenarray[2].tokpos, "and", 3)))
                    ;//skip it
                  else
It is an ugly hack but it works.
Let me know if you are happy with it.
If you can not build UASM I can post it here, because it looks like John is busy lately with his garden.
Cod-Father