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
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
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
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.
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
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?
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
Seeing macros are locally expanded. I thought $ would work for this.
Regards, P1 :8)
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
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
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
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
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
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