Maker Pro
Maker Pro

Assembler question #DEFINE or EQU?

D

Don Bruder

Jan 1, 1970
0
Glenn Ashmore said:
What is the difference? It looks like they do the same thing.

Depends on the dialect the assembler is supposed to be working with, and
the coder's intentions, but IME, "#DEFINE" usually begins the definition
of a macro, which might expand to multiple bytes of object code in the
output file at assembly time, while EQU defines a value, but *NEVER*
produces any object code in the output file.

Usually, #DEFINE (or a similarly functional, but differently named
keyword), can be used to produce the same effect as EQU, but EQU usually
isn't capable of producing the effects of #DEFINE.
 
J

Jonathan Kirwan

Jan 1, 1970
0
What is the difference? It looks like they do the same thing.

I'm not so sure I like Don's way of saying it, though it may be
correct, in part. Since you don't say which system you are working
on, I'll just assume you mean a comparison of a c-style #define and an
assembler style of EQU, when I speak, since that seems more likely to
me. (Sometimes, assemblers will actually support a c-style #define,
too, though I cannot think of a c-compiler that supports an assembler
style EQU.) Also, there is an aspect of #define that does support
parameters, but I'll assume that you are really just talking about
comparing:

#define MYSYM 10
and,
MYSYM EQU 10

rather than,

#define MYSYM(a) 10*(a)
and,
MYSYM EQU 10*(a)

which is a different comparison.

In an assembler like MASM for the PC, which supports an EQU, the EQU
actually creates a symbol (or may, anyway) and an associated value
that is placed into the object file that the linker can examine,
later. THis means that the symbol can be referenced in other source
code files.

In c (and probably any assembler also supporting it), the #define only
creates that symbol in the compiler's temporary internal memory for
the duration of the compilation. In that case, the symbol does NOT
then appear in the object file, at all. It's kind of like entering a
search-and-replace in your editor, that replaces all cases of the
symbol in your text to the indicated value before compilation. The
compiler never even "sees" the symbol. It's just not there, when the
c compiler gets around to parsing the code.

For example,

--- assembler source file #1 ---
SIZE EQU 10
PUBLIC SIZE
D DW SIZE DUP( 1 )
--- end ---

--- assembler source file #2 ---
EXTERN SIZE:ABS
mov cx, SIZE
--- end ---

If you assemble #1, it will not only use the value of SIZE in creating
the list of 10 constant-one's for the D-array, but it will also place
a symbol called SIZE into its object file for use by the linker. When
the assembler assembles #2, it places a reference in its object file
to link up with the value of SIZE to move into the CX register. When
the linker gets around to pasting these two files together, it finds
the value defined in #1 and replaces the reference to it in #2 with
the correct value and then completes the link up, which means that the
value 10 will be correctly placed into CX when the program runs.

In c, there is no equivalent to EQU.

However, in x86 assembler, there is an equivalent to #define. It's
simply the = sign. For example,

MYSYM = 10

In this case, the value in MYSYM only exists for the duration of the
assembly processes and the symbol MYSYM will not be placed into the
object file.

It's one of the many examples where the available semantics to the
assembly writer exceeds the semantics available to the c programmer.

Jon
 
G

Glenn Ashmore

Jan 1, 1970
0
OK, lemme see. If I had a literal in an MPASM source file that was
referenced many times that may need to be adjusted before the final compile,
like say a delay loop count, I would use a #DEFINE so that any other files I
was linking wouldn't be effected but if it were an address I would use EQU?

--
Glenn Ashmore

I'm building a 45' cutter in strip/composite. Watch my progress (or lack
there of) at: http://www.rutuonline.com
Shameless Commercial Division: http://www.spade-anchor-us.com
 
R

Robert Monsen

Jan 1, 1970
0
Glenn said:
What is the difference? It looks like they do the same thing.

I assume you are talking about MPASM.

EQU must resolve to an integer. #define can be any text string.

You apparently *can't* make label's defined by EQU global, which makes
them useless. Yet another thing the microchip guys got wrong in MPASM.

The preprocessor macro language was created as a built-in macro language
for C. It makes it possible to define constants that require no storage,
and which are evaluated at compile time. You can also create simple
macros with it, and conditional areas.

Many assemblers which allow the use of the C preprocessor have this odd
choice of whether to use the built-in facilities or the C syntax.

--
Regards,
Robert Monsen

"Your Highness, I have no need of this hypothesis."
- Pierre Laplace (1749-1827), to Napoleon,
on why his works on celestial mechanics make no mention of God.
 
R

Robert Monsen

Jan 1, 1970
0
Glenn said:
OK, lemme see. If I had a literal in an MPASM source file that was
referenced many times that may need to be adjusted before the final compile,
like say a delay loop count, I would use a #DEFINE so that any other files I
was linking wouldn't be effected but if it were an address I would use EQU?

No, in MPASM, EQU is just a way of creating constants. They have to
resolve to numbers. You can't declare the resulting label as global,
thus, they cannot be resolved by the linker. (I just tried it).

--
Regards,
Robert Monsen

"Your Highness, I have no need of this hypothesis."
- Pierre Laplace (1749-1827), to Napoleon,
on why his works on celestial mechanics make no mention of God.
 
J

Jonathan Kirwan

Jan 1, 1970
0
I assume you are talking about MPASM.

I hadn't known, until Glenn mentioned it in reply to me. Yes, you are
right about that.
EQU must resolve to an integer. #define can be any text string.

You apparently *can't* make label's defined by EQU global, which makes
them useless. Yet another thing the microchip guys got wrong in MPASM.

Too bad. Have you tried to use PUBLIC and EXTERN here to verify this?
(I haven't yet, but will soon.)
The preprocessor macro language was created as a built-in macro language
for C. It makes it possible to define constants that require no storage,
and which are evaluated at compile time. You can also create simple
macros with it, and conditional areas.

Many assemblers which allow the use of the C preprocessor have this odd
choice of whether to use the built-in facilities or the C syntax.

Yes, I've seen that, too.

Jon
 
J

Jamie

Jan 1, 1970
0
Robert said:
No, in MPASM, EQU is just a way of creating constants. They have to
resolve to numbers. You can't declare the resulting label as global,
thus, they cannot be resolved by the linker. (I just tried it).
let me see here.
i do some programming my self, maybe i can shed some light on it.
the compiler in use may not be treating the same way as i am use
to but here goes.
#DEFINE.
a compiler switch, meaning that you can perform conditional compiling
this is good if for example, you want to create 2 different programs
with slightly different operations or access different hardware etc..
so you can create a compiler const ( not code const).
for example
#DEFINE BetaVersion.
and some where in code land
#IFDEF BetaVersion
// do code
#ELSE
// so some other code
#IFEND
something on that line.
---
EQU is like constants i guess,

example.
BASEPORT EQU 0x0200;
some where in code land, you can use BASEPORT instead of 0x0200;

makes it easier to simple change the BASEPORT value and recompile
the whole program with out re'editing the whole program.

..
that is my assessment of it.
maybe i am a little off track here.
 
A

Active8

Jan 1, 1970
0
What is the difference? It looks like they do the same thing.

I use equ when I want a constant literal or constant [usually base]
address. As others said. it has to resolve to a number.

define is used for macros or whatever. it can be tricky because any
reference to the defined symbol is replaced by the value so:

#define str "Blah"

is easy. but you wouldn't do that in assembler because you'd want to
deal with characters and it's better to say:

DB "blah, blah", 0 for a NULL terminated string or better yet

ifdef _SAVE_INFO
_PHONE
dt "Phone: ", 0
dt "555-555-5555 ", 0
endif

That generates

_PHONE
retlw 'P'
retlw 'h'
...
retlw 0

which works great for outputting strings. You just index into the
table at base address _PHONE to get the next character and test to
see if it's the terminating NULL. I think all that is covered in the
uChip docs as well as avoiding pitfalls of table lookup routines.

You have to be careful with defines

#define crap other_symbol + 2

might foul up if you later say

#define more_crap crap*2

because it resolves to

other_symbol + 2*crap

so you want to say

#define not_crap (other_symbol + 2)

then

#define not_more_crap not_crap*2

which resolves to

(other_symbol + 2) * 2

which is what you want.

HTH
 
R

Robert Monsen

Jan 1, 1970
0
Active8 said:
You have to be careful with defines

#define crap other_symbol + 2

might foul up if you later say

#define more_crap crap*2

because it resolves to

other_symbol + 2*crap

so you want to say

#define not_crap (other_symbol + 2)

then

#define not_more_crap not_crap*2

which resolves to

(other_symbol + 2) * 2

which is what you want.

HTH

It's always a good thing to surround any defined computation with parens
for this very reason. It's also good to surround macro args with parens.

#define K(x) (x * 1024)

K(2+5)

doesn't do what you thought it would do.

--
Regards,
Robert Monsen

"Your Highness, I have no need of this hypothesis."
- Pierre Laplace (1749-1827), to Napoleon,
on why his works on celestial mechanics make no mention of God.
 
A

Active8

Jan 1, 1970
0
It's always a good thing to surround any defined computation with parens
for this very reason. It's also good to surround macro args with parens.

#define K(x) (x * 1024)

K(2+5)

doesn't do what you thought it would do.

Why would it not return 7 * 1024 ? Does it return

2 * 1024 + 5

Should it be

#define K(x,y) ( (x+y)*1024 ) ; ??
 
J

Jonathan Kirwan

Jan 1, 1970
0
Why would it not return 7 * 1024 ?

Because it is a simple substitution. So,

K(2+5) = (2+5 * 1024)

And that is NOT 7*1024.
Does it return

2 * 1024 + 5

No, it returns 2+5*1024.

Turns out, K(2+5) isn't equal to K(5+2), too. Bad news.
Should it be

#define K(x,y) ( (x+y)*1024 ) ; ??

More like:

#define K(x) ((x)*1024)

Jon
 
A

Active8

Jan 1, 1970
0
Because it is a simple substitution. So,

K(2+5) = (2+5 * 1024)

And that is NOT 7*1024.


No, it returns 2+5*1024.

Uh, yeah. *That's* what I meant. I better start reprogramming myself
3 times a day.
Turns out, K(2+5) isn't equal to K(5+2), too. Bad news.


More like:

#define K(x) ((x)*1024)

Ah. haven't messed with MPLAB or C++ macros in a while.
 
R

Robert Monsen

Jan 1, 1970
0
Jamie said:
i thought you did that with Macro's

I'm talking about the C preprocessor language in general. I actually
don't know if MPLAB supports this form of preprocessor macro. This is
just a 'beef' of mine. I've been caught by it several times when taking
over other people's code...

--
Regards,
Robert Monsen

"Your Highness, I have no need of this hypothesis."
- Pierre Laplace (1749-1827), to Napoleon,
on why his works on celestial mechanics make no mention of God.
 
J

Jamie

Jan 1, 1970
0
Robert said:
It's always a good thing to surround any defined computation with parens
for this very reason. It's also good to surround macro args with parens.

#define K(x) (x * 1024)

K(2+5)

doesn't do what you thought it would do.
i thought you did that with Macro's
 
Top