News:

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

Challenge for you macro experts

Started by Randall Hyde, August 16, 2006, 04:27:16 PM

Previous topic - Next topic

Randall Hyde

Hi all,
Here's a problem I've been trying to solve for some time now. Given the following macro invocation:


someLabel  someMacro  someParameters


I would like to "capture" the label (someLabel) inside the macro and use it in multiple places.  That is, I'd like to text equate some local symbol to "someLabel" and then use that local symbol in multiple places and have "someLabel" show up.  The closest I've gotten is something like this:


someMacro macro parameters:VARARG
                local lclSymbol
<< code that uses lclSymbol>>
                exitm <textequ lclSymbol>
                endm

The only problem with this is that "someLabel" (when used with this macro invocation) cannot be an external symbol (among some other problems).

Anyone have any suggestions on how to do this?
Thanks,
Randy Hyde

Ratch

Randall Hyde,

     I can't speak for other assemblers, but MASM does not allow a "label" in the same line as the MACRO call.  Is it all right to put the "somelabel" within the parameter fields?  Ratch

Randall Hyde

Quote from: Ratch on August 16, 2006, 06:02:47 PM
Randall Hyde,

     I can't speak for other assemblers, but MASM does not allow a "label" in the same line as the MACRO call.  Is it all right to put the "somelabel" within the parameter fields?  Ratch

Actually, I have used the code given in my original post in MASM v6.14. So I know that works, at least.

I'm really trying to avoid putting someLabel in the parameter list. The reason I want to do this is so I can create some typedefs that do some special things, but I want to maintain the existing variable declaration syntax. E.g., if I declare an "int8" data type, I want to be able to write:


i8Var  int8  0


Note that a MASM typedef won't work here because I need to create several other symbols based onthe "i8Var" name.  The exitm approach *almost* works, but fails if i8Var is an external or public symbol.
Cheers,
Randy Hyde

MazeGen

Hi Randall,

really interesting problem. Could you post some compilable "testing framework" where the error is replicated and we can play with? The someMacro seems to be too academic for me.

Randall Hyde

Quote from: MazeGen on August 17, 2006, 07:30:41 AM
Hi Randall,

really interesting problem. Could you post some compilable "testing framework" where the error is replicated and we can play with? The someMacro seems to be too academic for me.

Well, here's what I want to do:



i8Var  int8  5



where i8Var is a variable I'm declaring, int8 is a macro that constructs an "sbyte" variable out of i8Var, and 5 is the initial value (e.g., just like you'd used an

int8 typedef sbyte

statement, *except* that in addition to declaring i8Var, it also declares something like "i8Var_type textequ <int8>" at the same time.  I need to do this so I can check the declared type of i8Var later on in the code using conditional assembly.

Sure, I can write a macro to allow a declaration like "int8  i8Var:=5" (indeed, see the macro package I've used in the Genesys area), but I'd really like to stick as closely as possible to MASM syntax for this stuff.

Cheers,
Randy Hyde


MazeGen

I think we can never get rid of the space between <i8Var> and <int8> and therefore we can't append anything to <i8Var> to make something like <i8Var_type>. I mean, there is no way how to "capture" the someLabel.

I still didn't get why is it not possible for you to check the type using "IF TYPE (i8Var) EQ TYPE SBYTE" and similar?

MazeGen

OK, I have done something. Don't take it as a final solution. Is it similar to what you are looking for?

.686
.MODEL FLAT, STDCALL

.LISTALL

int8_global = 0

int8 MACRO value
int8_global = int8_global + 1

@CatStr (<int8_>, %int8_global) SBYTE value

EXITM <TEXTEQU @CatStr(<int8_>, %int8_global)>
ENDM

.DATA
i8Var int8 (5)

.CODE
Start:
mov bl, i8Var ; i8Var = <int8_1>
END Start

P1

Seeing macros are locally expanded.  I thought $ would work for this. 

Regards,  P1  :8)

zooba

Possibly MazeGen's suggestion will solve the PUBLIC/EXTERN issues Randy was having earlier, since the internal variables used aren't scoped LOCAL.

Then again, I've got absolutely no idea how the assembler treats macro locals internally, apart from knowing that they're unique.

Cheers,

Zooba :U

telesphore

No expert here. Hell, I haven't even looked at assembler for a few years. But I hate typing the same things over & over again.

The trick I used was to use a symbol in the macro that gets redefined with in the macro. Here I use it to generate a static linked list. The idea will have to be tweaked to your needs.


;=============================================================================
;The assembler is perfectly capable of linking the words into a chain at
;assemble time. Currently, this is all linked into one long chain; I'll have
;to change this if I move to hash tables. As you'll see this is nothing
;more than a LIFO linked list with a tail of 0 & the header is stored in a
;variable. Just look at a word definition macros below to see how HEADER.LINK
;is redefined in each header to get the linking done.
;-----------------------------------------------------------------------------
%define HEADER.LINK 0

;=============================================================================
%macro HEADER 2-3.nolist+ 0
    %strlen HEADER.LEN %1
    section .data
    align 4, db 0
    %2.header:
    istruc header
        at header.link, dd  HEADER.LINK
        at header.code, dd  %2
        at header.size, dw  %2.end - %2
        at header.flag, db  %3
        at header.len,  db  HEADER.LEN
    iend
    db %1 ;header.word
    %define HEADER.LINK %2.header
    %define HEADER.END  %2.end
    section .text
    align 4
    %2:
%endmacro

%define DONE HEADER.END

Randall Hyde

Quote from: MazeGen on August 18, 2006, 03:00:50 AM
OK, I have done something. Don't take it as a final solution. Is it similar to what you are looking for?

.686
.MODEL FLAT, STDCALL

.LISTALL

int8_global = 0

int8 MACRO value
int8_global = int8_global + 1

@CatStr (<int8_>, %int8_global) SBYTE value

EXITM <TEXTEQU @CatStr(<int8_>, %int8_global)>
ENDM

.DATA
i8Var int8 (5)

.CODE
Start:
mov bl, i8Var ; i8Var = <int8_1>
END Start


Actually, what I'm looking for is the converse of this. Rather than equating the symbol to something else and using that "something else", I want to equate the "something else" symbol to the original symbol.

I.e., I want to create a text equate of the form:


int8_1 textequ <i8Var>

Cheers,
Randy Hyde

gfalen

Can't understand exactly what you want but this is what I use...


declare MACRO _TYP, _LST:VARARG
    $SEG catstr @CurSeg
    irp $V, <_LST>
        T instr <$V>, <=>
        if T
            .data
            align type _TYP
            @SubStr(<$V>, 1, T-1) _TYP @SubStr(<$V>, T+1)
        else
            .data?
            align type _TYP
            T instr <$V>, <[>
            if T
                B instr <$V>, <]>
                @SubStr(<$V>, 1, T-1) _TYP @SubStr(<$V>, T+1, B-T-1) dup(?)
            else
                $V label _TYP
                DB type _TYP dup(?)
            endif
        endif
        ifidn $SEG, <_BSS>
            .data?
        elseifidn $SEG, <_DATA>
            .data
        elseifidn $SEG, <_TEXT>
            .code
        endif
    endm
endm

bool     EQU declare sdword,
uint     EQU declare dword,
i8int    EQU declare sbyte,

; now I can say
uint a, b=6, arr[32]
bool b1, b2, b3=5
i8int i81, i82-8...

; Can be used even in .code section.  Declared vars will go into
.data? or .data - original section is restored


Regards

Randall Hyde

Quote from: gfalen on September 11, 2006, 06:32:43 PM
Can't understand exactly what you want but this is what I use...



; now I can say
uint a, b=6, arr[32]
bool b1, b2, b3=5
i8int i81, i82-8...




What I really want to be able to say is:


a uint ?
b uint 6
arr uint 32 dup [?]


and, at the same time, create constants like the following (automatically, from the above three declarations):


$_a textequ <uint>
$_b textequ <uint>
$_c textequ <uint>

where "$_<name>" is synthetically created, and arbitrary, existing only so I can check the type of the name later on using conditional assembly.  What I'm asking for actually allows you to do many more things than this, but this is the main thing I want to do with this technique.
Cheers,
Randy Hyde


gfalen

Hey Randall. 
Well if you're trying to do HLA code I don't know, but for MASM I have to say that my approach is both
convenient and concise.  Plus it allows for convenient conversion from C/C++ code - having similar syntax.

Regards