The MASM Forum

General => The Campus => Topic started by: AssemblyChallenge on January 22, 2015, 03:59:06 AM

Title: MASM32 constant compilation.
Post by: AssemblyChallenge on January 22, 2015, 03:59:06 AM
Hi all.

Last year I found a very curious situation while working a small project. As you all know, I use -and love  :icon_cool:- EasyCode, and my first thought, of course, was to blame it for the problem but maybe not.

Let's say you declare one or more constants:

.const

MyConst1 = 1234h
MyConst2 = 4567h
.
.
etc.

The compiling goes fine and shows no error but back then my project crashed when executed. With the help of Ollydbg I found that my constant(s) became into a bunch of DBs. The reason? Using "=" instead of "Equ". Once I replaced the "="s everything came back to normal and I learned my lesson.  :lol:

I was wondering if this behavior is normal in MASM32's compiler and the "=" is not allowed for constant declaration.

Regards.
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 22, 2015, 08:32:02 AM
Hi AssemblyChallenge,

You should use EQU for constants. According to p.17 of the Masm 6.1 Programmer's Guide, once you define a constant with Equ it can't be changed later: "attempting to redefine it generates an error". If you use =, however, it can be redefined during the assembly process. Still, even with =, "a constant value is assigned during assembly for each use, and that value does not change at run time". Thus no storage location is assigned (no "bunch of DB's"). So they both define "constants", but Equ is "more constant".

I haven't checked specifically, but I'd be amazed if ML (or ML64, or JWasm) assigns a storage location for a symbol defined with =. Presumably EasyCode is doing that, mistakenly.

BTW you refer to "MASM32's compiler" .. just to clear a potential misunderstanding, MASM32 is not an assembler (or compiler), but a collection of tools and files to enhance the use of an assembler. You're probably using Microsoft's ML.exe, as you can see in your MASM32/bin directory. You could use other assemblers, such as JWasm; that's independent of MASM32. It's easy to get confused; I used MASM32 for months b4 I got this distinction.

If I'm wrong about any of this, sorry ... Ask an expert if you want to know for sure!
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 22, 2015, 08:59:00 AM
Thank you.

You are right, it is not the whole MASM32 but the compiler (in this case). I assumed not to be EasyCode's fault because it just invokes the source code with some parameters. I was using "=" to declare Constants instead of "Equ" because of the book I was reading and assumed to be the same thing.  :biggrin:

Regards.
Title: Re: MASM32 constant compilation.
Post by: rsala on January 22, 2015, 11:32:29 AM
Hi AssemblyChallenge,

Thanks for using Easy Code.

The IDE just sends the sources to the compiler (ml.exe), so the the problem (or error if any) is caused by the compiler. There is nothing I can do about that.

Regards.
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 22, 2015, 11:36:34 PM
That's my point. EasyCode just invokes ML. My real question is how "legal" the equal sign is when declaring constansts.

Regards, Master  8)

Quote from: rsala on January 22, 2015, 11:32:29 AM
Hi AssemblyChallenge,

Thanks for using Easy Code.

The IDE just sends the sources to the compiler (ml.exe), so the the problem (or error if any) is caused by the compiler. There is nothing I can do about that.

Regards.
Title: Re: MASM32 constant compilation.
Post by: dedndave on January 23, 2015, 03:51:00 AM
something is amiss, here
perhaps you can post a complete example

i have used both temporary "=" and permanent "EQU" constants for many years without problems
you must have re-assigned the value, somehow
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 23, 2015, 04:39:06 AM
Hello rsala,

I'm glad this problem, whatever it is, occurred, because it provoked me to take a look at EasyCode. It's a masterful job, and I learned a number of things from it. I finally know what's wrong with these .chm files - you have to unblock them! That one tip was worth the price of admission. My hat is off to you; EasyCode is far beyond my meager capabilities. However - even masters, you know, make mistakes. Napoleon marched on Moscow in the winter; Einstein rejected Quantum Mechanics; Fischer dropped a bishop against Spassky; Bruce Lee jumped off a tall building. In the computer world, Gary Kildall refused to sell CP/M to IBM for their new PC; Steve Jobs came out with Next; JWasm says the type of ymm0 is 8 (should be 32); and Bill Gates produced ML.exe, one of the buggiest programs ever. So if EasyCode is not perfect, you're in very good company!

Feeling foolish, I actually went and checked whether ML emitted a db statement for "=" constants. Of course, it doesn't. It may have done in this particular case; if so it's a brand new bug. So either ML did that; or EasyCode somehow modified the source to make that happen; or AssemblyChallenge misunderstood Olly's analysis (based on my experience with Olly, that's not impossible.)

Anyway, bottom line: if it's really constant, use EQU and you'll be a happy coder!
Title: Re: MASM32 constant compilation.
Post by: dedndave on January 23, 2015, 06:58:31 AM
i don't agree - i use temporaries quite often, for example...

TmpFlags=WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_CLIPCHILDREN

        INVOKE  CreateWindowEx,edi,offset szClassName,offset szAppName,TmpFlags,
                CW_USEDEFAULT,SW_SHOWNORMAL,MAIN_WIDTH,MAIN_HEIGHT,edi,edi,ebx,edi


notice that i define it, then use it right away
i don't expect it to remain the same, because i may re-define it elsewhere
Title: Re: MASM32 constant compilation.
Post by: jj2007 on January 23, 2015, 10:39:53 AM
Quote from: dedndave on January 23, 2015, 03:51:00 AM
something is amiss, here
perhaps you can post a complete example

i have used both temporary "=" and permanent "EQU" constants for many years without problems
you must have re-assigned the value, somehow

I can only echo that. MyFlag=0 is a very valid way to assign "constants", and I also use it all the time without any problems, in ML 6.15 to 10.0 and JWasm. The problem is elsewhere. Search your source code for reassignment. If your project is scattered over a dozen little includes and sources, you'll have to search them all. And don't forget that Masm32 itself *may* use constants - namespace pollution may occur, although Hutch uses EQU throughout, thus blocking the constants (which is a good thing for a library).
Title: Re: MASM32 constant compilation.
Post by: dedndave on January 23, 2015, 11:04:53 AM
in the original post, you gave us hypothetical names...

Quote from: AssemblyChallenge on January 22, 2015, 03:59:06 AM
Let's say you declare one or more constants:

.const

MyConst1 = 1234h
MyConst2 = 4567h
.
.
etc.

if you don't want to show us the complete source, at least tell us what names you actually had a problem with
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 24, 2015, 05:49:56 AM
Fortunately, I kept the message sent to Rsala back then. Also, couldn't replicate the problem; not in the original project nor a new one  :dazzled:

Please look at the attached images. I needed global variables and, following Rsala's kind advice, added a Module in my project and defined all of them there (Original code). The Constants you see were first defined with "=" and compiled successfully but the project crashed when executed. So, I set several NOPs, debugged the program with Olly and found the little mess (Bad compile). Then I replaced "=" by "Equ" in both constants, recompiled and voila, solved (Good compile). Even when several new versions of Easycode came out after that, I really really doubt about its fault and still blame the compiler.
Title: Re: MASM32 constant compilation.
Post by: ragdog on January 24, 2015, 06:22:48 AM
Analyse problem in Olly? try to delete the Udd´s
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 24, 2015, 07:06:16 AM
@rrr314159: A little bit off topic but, oh well  :biggrin:

Most part of Assembly tutorials and videos were created with Radasm and/or Winasm. Of course, I tried to learn and use those for some time but never got used to any of them; can't explain it but somehow I felt unconfortable, even when both are great and yes, took long readings (reviews) beforehand.

My love history with Easycode started a couple of years ago while browsing Woodmann's site and then  I ended up here. (http://www.woodmann.com/collaborative/tools/index.php/Category:Assembler_IDE_Tools) Visited the site, downloaded it and never looked back  :lol:
Not only is simple and powerful; Ramon gave away tons of info, good examples, and explained very clearly some key concepts and tips about Windows programming that were driving me nuts and couldn't understand before. Plus, he is quick and gentile about the bugs found or my mistakes using his IDE; in a sentence: I was home.

Easycode, FTW!  :icon14: :icon14:  :icon_cool:
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 24, 2015, 07:24:04 AM
First I was astonished as always rebuild the whole project. This is important so Ollydbg debug the right exe (with no need to get rid off Udds). I'm pretty sure about it because of the million times a project must be debugged/tested. This means I recompiled several times before realizing the cause -surprising for me- and noting the constant names close to the weird DBs; that's how I found it (and comparing with other examples, all with Equs instead).  :t

Quote from: ragdog on January 24, 2015, 06:22:48 AM
Analyse problem in Olly? try to delete the Udd´s
Title: Re: MASM32 constant compilation.
Post by: jj2007 on January 24, 2015, 07:50:12 AM
Quote from: AssemblyChallenge on January 24, 2015, 05:49:56 AMI set several NOPs, debugged the program with Olly and found the little mess (Bad compile).

The "little mess" might come from Olly not (yet) understanding your code. That happens frequently, you typically see a "mess" with db xyz statements. In that case, select a few lines before and after the interesting zone and press Ctrl A like "analyse". Olly then makes an extra effort, and your code will look much more meaningful.
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 24, 2015, 11:27:49 AM
@dedndave,

There's a minor, but interesting, semantical point here which is perhaps worth clarifying.

Consider your example, where TmpFlags is an argument to INVOKE. The assembler will emit an instruction like "push 12cf0000h" when setting up the call to CreateWindowEx - 12cf0000h is an immediate, and will certainly be constant for the duration of the program. So, we call TmpFlags a symbolic "constant".

However it won't be constant during the assembly process. A few lines later it may be redefined, via another "=", perhaps for the same purpose of reducing a long line to a shorter, more readable one. That's why you call it a "temporary constant", which is prima facie an oxymoron. It means: constant at runtime, but temporary during assembly.

OTOH WS_OVERLAPPEDWINDOW is a "permanent constant" - constant during assembly, as well as runtime. That's why it's defined in winuser.inc as: WS_OVERLAPPEDWINDOW equ 0CF0000h.

It's a good idea to have terms for these concepts. For instance, jj2007 puts quotes around the word "constant" to indicate a temporary constant; and I said "really constant" to mean a permanent constant. Both of these are indistinct; we can avoid confusion with your terms, even if one sounds like an oxymoron, and the other redundant.

Now, if you look at OP's question, it's pretty clear MyConst1 and MyConst2 are intended to be permanent constants. "=" is not illegal here; it will do the job also. The problem is that since he's created temporary constants, anyone reading the code expects them to change later on. If they appear many lines later, you can't be sure they still have the values 1234h and 4567h. These problems are avoided by using EQU.

Perhaps I'm beating the horse to death by picking at nits, but I hope this point was worth clarifying - if only to make sure I've got it right.

@AssemblyChallenge, re: off point: True. Sorry, sometimes I get carried away. But, FWIW, IMHO this place could stand to lighten up a little .. this is not life and death ... to paraphrase Mick Jagger, it's only assembler!  :biggrin:  :P  :icon_cool:  ;)  :lol:
Title: Re: MASM32 constant compilation.
Post by: dedndave on January 24, 2015, 11:45:05 AM
the symbol names only have meaning during the assembly process, however
they are simple "textual" aliases for the numeric values (or strings, in some cases)

an important thing to note is that the assembler sees the source text in a "serial" manner
that is, it processes text in a distinct order, from top to bottom, sometimes with INCLUDE files inserted
this order may be different from how code is executed   :P
Title: Re: MASM32 constant compilation.
Post by: jj2007 on January 24, 2015, 01:17:48 PM
Quote from: dedndave on January 24, 2015, 11:45:05 AMan important thing to note is that the assembler sees the source text in a "serial" manner

That is indeed a source of misunderstandings between coder and assembler :biggrin:

Here is a little snippet showing three variants of constants and their behaviour.

include \masm32\include\masm32rt.inc

.code
start:
  cnum=123
  ctxA equ 456
  ctxB equ <789>
  cnum=111
  ; ctxA equ 444 ; Symbol redefinition: ctxA
  ctxB equ <777>
  tmp$ CATSTR <print "cn is >, %cnum, <", 13, 10>
  % echo tmp$
  tmp$
  tmp$ CATSTR <print "ctA is >, %ctxA, <", 13, 10>
  % echo tmp$
  tmp$
  tmp$ CATSTR <print "ctB is >, %ctxB, <", 13, 10>
  % echo tmp$
  tmp$
  tmp$ CATSTR <print "cn is >, <cnum>, <", 13, 10>
  % echo tmp$
  tmp$
  tmp$ CATSTR <print "ctA is >, <ctxA>, <", 13, 10>
  % echo tmp$
  tmp$
  tmp$ CATSTR <print "ctB is >, <ctxB>, <", 13, 10>
  % echo tmp$
  tmp$
  exit
end start
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 24, 2015, 03:17:43 PM
MASM never ceases to surprise ... and blatantly disregard its spec.

We all know this (from Masm 6.1 programmer's manual, p. 17):

The directives EQU and = have slightly different purposes. Integers defined with the = directive can be
redefined with another value in your source code, but those defined with EQU cannot. Once you've
defined a symbolic constant with the EQU directive, attempting to redefine it generates an error.

Consider this code snippet, derived from yours:


include \masm32\include\masm32rt.inc

.code
start:

;  ctxA equ <1>
  ctxA equ 456
  ctxA equ 444          ; Symbol redefinition: ctxA
  ctxA equ <432>   ; Symbol redefinition: ctxA


  tmp$ CATSTR <print "ctA is >, %ctxA, <", 13, 10>
  % echo tmp$
  tmp$

  tmp$ CATSTR <print "ctA is >, <ctxA>, <", 13, 10>
  % echo tmp$
  tmp$


  exit
end start


When you run it, it generates the two symbol redefinition errors - fine. But now, uncomment the first line. No more errors! If the very first equ definition uses <>, after that you can use it to redefine as often as you like. For that symbol ctxA, equ now behaves like =.

U need a sense of humor to deal with MASM! :bgrin:

[edit] Actually the first equ statement tells MASM to treat ctxA as a text macro, instead of a symbolic integer. Thereafter equ is behaving like textequ, not "=". I can't find this in the documentation, but evidently that's what it's doing?
Title: Re: MASM32 constant compilation.
Post by: sinsi on January 24, 2015, 04:19:10 PM
Anything in <angle brackets> is treated as text, so <456> is a text string, but 456 is converted to a numeric value.
Just to confuse things, there is TEXTEQU as well  :biggrin:
Title: Re: MASM32 constant compilation.
Post by: qWord on January 24, 2015, 07:33:00 PM
At least some of this behavior is documented in the reference manual:
Quotename EQU expression
   Assigns numeric value of expression to name. The name cannot be redefined
   later.
name EQU <text>
   Assigns specified text to name. The name can be assigned a different text
   later. See TEXTEQU.
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 25, 2015, 08:27:16 AM
sinsi and qword, thanks for the input.

Actually I knew EQU can be used in place of TEXTEQU, but in the context of the current discussion it slipped my mind, since we've been concentrating on equ vs. =, and only numeric assignments. The use of equ does guarantee a "permanent constant" - IF we ignore text assignments (unless there's yet another point I'm missing). But if the assembler sees a previous (in serial order) text assignment statement in the source text, "MyConst1 equ <sometext>" (with or w/o angle brackets), then "MyConst1 equ 1234h" will only assign a new (text) value. Text values, of course, are always temporary constants. jj2007's snippet made me think of that (perhaps that was the point?), and incorrectly leap to the conclusion that it was a "bug". No, it was just another "feature I don't understand yet". Hope I've got it right now, but wouldn't want to bet on it.

BTW AFAIK (at this time) textequ is redundant, and can be replaced by equ. Still, qword regularly uses textequ for text assignments - maybe, just for clarity?

Oh well .... fortunately I CMA'd in my first post: "If I'm wrong about any of this, sorry ... Ask an expert if you want to know for sure!" :icon_redface: Thx to all u experts for your help & patience.
:
Title: Re: MASM32 constant compilation.
Post by: hutch-- on January 25, 2015, 01:19:34 PM
This discussion has fascinated me, I thought everyone and their dog knew that there is a difference between a EQU and an assignment "=". Now if fact you can write some interesting code using the assignment operator but it is highly order dependent and can catch you out with forward referencing if you are not careful.

EQU means an equate that cannot be RE-assigned.
"=" is a RE-assignable equate.

MASM does not support dynamic code assignment with the "=" operator, you specifically MOV one value, (reg or mem) into another reg or mem noting that you cannot MOV mem to mem.

> "feature I don't understand yet"

:biggrin:
Now here is a man who actually understands what MASM is, a bundle of operators for screwing mnemonics together. It has never been softened into a user friendly tool, it will bite your hand, not hold it and any mistakes will explode in your face. Once you learn its "features" you learn to write code that does not have mistakes in it and you rarely every need error handlers unless you are dealing with external source data from hardware or the internet.

This is much of its fatal charm, a bad mannered old pig that forces you to write decent code.  :P
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 26, 2015, 06:04:22 AM
hutch,

I hate to contradict, but ... the whole point of the above posts is that equ does NOT necessarily mean "an equate that cannot be RE-assigned". Consider the following code snippet.
; a equ sometext
a equ 4
a equ 34

%echo a
tmp equ <%a>
%echo &tmp

When you run this (under ML64), it says "Error A2005:symbol redefinition : a" on the line "a equ 34". "a" gets the numeric value 4: this is just as you say. But now, uncomment the first line. All three equ's are now legal; "a" first is assigned <sometxt>, then 4, then 34 (as text, not numbers). If the FIRST equ is textual, subsequently you can RE-assign, using equ, as often as you like (until you run out of memory).

As qword points out this is documented in the reference manual - which, until I saw his quote, I thought was part of my Programmer's guide. The PG does not document this behavior: it agrees with you.

As I say, I hate to contradict; but one other point: actually, my dog doesn't understand any of this at all. Since the computer is not something to eat, he's just not interested. My cat, OTOH, understands all of it, but pretends she doesn't. Same as opening doors - she knows perfectly well how to do it, but plays dumb so I have to do it for her.

Thx for giving me the opportunity to clarify this.

Title: Re: MASM32 constant compilation.
Post by: hutch-- on January 26, 2015, 06:42:33 AM
Well,

You can do this.

    item equ <1234>
    item equ <5678>
    item equ <9012>


But not this.

    mov eax, item       ; this is OK
    ; mov item, eax       ; error A2008: syntax error : integer
    ; item = 5678         ; error A2008: syntax error : integer
    ; item = <5678>         ; error A2008: syntax error : integer


PS: I Like smart cats.  :biggrin:
Title: Re: MASM32 constant compilation.
Post by: rrr314159 on January 26, 2015, 09:58:10 PM
Now we're all on the same page!

BTW I'm ex-Aussie: born in Melbourne ... Box Hill. Came to U.S for education 40+ years ago, never went back.
Should have  ;)
Title: Re: MASM32 constant compilation.
Post by: AssemblyChallenge on January 27, 2015, 02:26:05 AM
Gentlemen. The constants were intended for read-only stuff (defining an array, input parameter). There is no place in my code where I change (or attempt to) modify any of them. The project was working perfectly fine until I added the constant definitions. If my memory is right the error was 0xc5 (invalid access), so, in order to find the cause I set the NOPs as "mark" in my source code and single stepped with Olly after recompiling. Then I found what you all saw, and so it was through serveral compilings until I figured out the Equ thing and came right after that. :bgrin: