News:

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

Main Menu

MASM32 constant compilation.

Started by AssemblyChallenge, January 22, 2015, 03:59:06 AM

Previous topic - Next topic

rrr314159

@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:
I am NaN ;)

dedndave

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

jj2007

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

rrr314159

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?
I am NaN ;)

sinsi

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:
🍺🍺🍺

qWord

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.
MREAL macros - when you need floating point arithmetic while assembling!

rrr314159

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.
:
I am NaN ;)

hutch--

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

rrr314159

#23
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.

I am NaN ;)

hutch--

#24
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:

rrr314159

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  ;)
I am NaN ;)

AssemblyChallenge

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: