Connect with us

Assembler question #DEFINE or EQU?

Discussion in 'Electronic Basics' started by Glenn Ashmore, Apr 3, 2005.

Scroll to continue with content
  1. Don Bruder

    Don Bruder Guest

    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.
     
  2. 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
     
  3. 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
     
  4. 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.
     
  5. 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.
     
  6. I hadn't known, until Glenn mentioned it in reply to me. Yes, you are
    right about that.
    Too bad. Have you tried to use PUBLIC and EXTERN here to verify this?
    (I haven't yet, but will soon.)
    Yes, I've seen that, too.

    Jon
     
  7. Jamie

    Jamie Guest

    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.
     
  8. Active8

    Active8 Guest

    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
     
  9. 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.
     
  10. Active8

    Active8 Guest

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

    2 * 1024 + 5

    Should it be

    #define K(x,y) ( (x+y)*1024 ) ; ??
     
  11. 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.

    Turns out, K(2+5) isn't equal to K(5+2), too. Bad news.
    More like:

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

    Jon
     
  12. Active8

    Active8 Guest

    Uh, yeah. *That's* what I meant. I better start reprogramming myself
    3 times a day.
    Ah. haven't messed with MPLAB or C++ macros in a while.
     
  13. 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.
     
  14. Jamie

    Jamie Guest

    i thought you did that with Macro's
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-