News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Macro for determining the operand type.

Started by hutch--, August 27, 2005, 10:57:44 AM

Previous topic - Next topic

hutch--

I looked and I could not find the thread but one of our members posted some useful research that yielded a more useful range of results from the built in masm macro OPATTR which made it possible to distinguish between LOCAL and GLOBAL variable and a number of other useful types.

This is the test macro using this capacity and what I am working on as time allows is enough reusable macro code to be able to routinely build more compex macros that can do more things. What I would be interested with in this macro is if there is anyting else that is worth chasing to add additional return values. I have not for example tested an EXTERNDEF data value.

I used te following code to test for return values with OPATTR


    mov eax, opattr(start)
    print str$(eax)," entry lbl",13,10


This is the test piece


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    operand_type MACRO arg:REQ
      LOCAL result
      result = opattr(arg)
        IF result eq 37         ;; label, either local or global
          EXITM %1
        ELSEIF result eq 42     ;; GLOBAL var
          EXITM %2
        ELSEIF result eq 98     ;; LOCAL  var
          EXITM %3
        ELSEIF result eq 36     ;; immediate operand
          EXITM %4
        ELSEIF result eq 48     ;; register
          EXITM %5
        ELSEIF result eq 36     ;; constant as in an equate
          EXITM %6
        ELSEIF result eq 805    ;; procedure in code
          EXITM %7
        ELSEIF result eq 933    ;; API call
          EXITM %8
        ENDIF
      EXITM %0                  ;; anything else
    ENDM

    .data
      item dd 0

    .code

start:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    call main
    inkey
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

main proc

    LOCAL var   :DWORD

  lbl1:

    mov eax, operand_type(non_operand)
    print str$(eax),13,10

    mov eax, operand_type(lbl1)
    print str$(eax),13,10

    mov eax, operand_type(item)
    print str$(eax),13,10

    mov eax, operand_type(var)
    print str$(eax),13,10

    mov eax, operand_type(edi)
    print str$(eax),13,10

    mov eax, operand_type(WM_COMMAND)
    print str$(eax),13,10

    mov eax, operand_type(main)
    print str$(eax),13,10

    mov eax, operand_type(GetWindowText)
    print str$(eax),13,10

    ret

main endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

      result = opattr(arg)
        IF result eq 37         ;; label, either local or global
          EXITM %1


Now I'm confused.   The documentation says that bit 0 indicates a label.  I've always used

if (opattr(arg)) and 01y ;; if it is a label

and it seems to work.  What am I missing now??

Jeff

and it will work.  the numbers hutch uses will include definition errors (this symbol is also defined) and whatnot.  you wouldnt want to see if a symbol is a label without knowing it exists right?

Jimg

That's good to know.  I always assumed it wouldn't return bit zero on if it was an error, i.e. Masm wouldn't know it was a label if it was an error.
and likewise, it wouldn't know it was a register, etc. if there was an error.

Quote
"If <expression> is not valid or is forward-referenced, OPATTR returns a 0."

So---

     Bit          Set If
     Position     <expression>

     0            References a code label
     1            Is a memory expression or has a relocatable data label
     2            Is an immediate expression
     3            Uses direct memory addressing
     4            Is a register expression
     5            References no undefined symbols and is without error
     6            Is an SS-relative memory expression
     7            References an external label
     8-10         Language type:     (011=STDCALL)


        IF result eq         100101y  ;;37   ;; label, either local or global 
          EXITM %1                               ; label, immediate expression, no error
        ELSEIF result eq     101010y  ;;42   ;; GLOBAL var
          EXITM %2                               ; memory or data label, direct memory addressing, no error
        ELSEIF result eq    1100010y  ;;98   ;; LOCAL  var
          EXITM %3                               ; memory or data label, no error, stack variable
        ELSEIF result eq     100100y  ;;36   ;; immediate operand
          EXITM %4                               ; immediate expression, no error
        ELSEIF result eq     110000y  ;;48   ;; register   
          EXITM %5                               ; register, no error
        ELSEIF result eq     100100y  ;;36   ;; constant as in an equate
          EXITM %6                               ; immediate expression, no error  **** repeat of type 4???????
        ELSEIF result eq 1100100101y  ;;805  ;; procedure in code   STDCALL,
          EXITM %7                               ; label, immediate, no error, STDCALL
        ELSEIF result eq 1110100101y  ;;933  ;; API call
          EXITM %8                               ; label, immediate, no error, external label, STDCALL
        ENDIF
      EXITM %0                  ;; anything else

hutch--

There was an obvious blunder in the first macro, a duplcate of an immediate operand and a constant that ends up te same thing so I removed one of the duplicates. This is the current form. What I am interested in is if there are any other return values I have missed that would be useful for parameter evaluation.


    operand_type MACRO arg:REQ
      LOCAL result
      result = opattr(arg)
        IF result eq 37         ;; label, either local or global
          EXITM %1
        ELSEIF result eq 42     ;; GLOBAL var
          EXITM %2
        ELSEIF result eq 98     ;; LOCAL  var
          EXITM %3
        ELSEIF result eq 36     ;; immediate operand or constant
          EXITM %4
        ELSEIF result eq 48     ;; register
          EXITM %5
        ELSEIF result eq 805    ;; local procedure in code
          EXITM %6
        ELSEIF result eq 933    ;; external procedure or API call
          EXITM %7
        ENDIF
      EXITM %0                  ;; anything else
    ENDM
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

ThoughtCriminal

Hear a quick macro to show you what any type is:
look MACRO i:REQ
local temp
temp TEXTEQU %OPATTR (i)
%ECHO temp
ENDM

you can do things like:

look  [esp-5]

And get all the bits that are set.


Jimg

Hi Hutch-

Just a suggestion, which I tried to hint at unsuccessfully with my previous post-   It's much more obvious what you are doing if you use binary notation for the tests, or at least hex.  Sorry, just a personal preference when working with bits.  Anything to make it easier for someone trying to figure out what's going on.