Thius is a question mainly for BiTRAKE, I have the following macro working but its clunky because it requires an extra comma (,)


ASM MACRO inst1,inst2,inst3
inst1 inst2,inst3
EXITM <inst2>
ENDM

It works OK and can be used with other mnemonics but what I am after is being able to pass TWO parameters to the macro so it can be used with the normal asm syntax.


mov eax, ASM(mov edx, 1)

MOV EAX being parameter one and the second parameter being whatever is required for the instruction.

I forget how to do the parsing of the first parameter so that it seperates the MOV from the EAX component on the basis of the seperating space between them.

Any suggestions that will work here will be appreciated as I want it for a code wizard that I have more or less finished.

Regards,

hutch@movsd.com
Posted on 2002-05-17 07:21:53 by hutch--
Something like this should work:
ASM MACRO val:VARARG

LOCAL a,b,y

% val ;; execute passed instruction

;; pry out the destination parameter
a INSTR 1,<&val>,<! >
IF a EQ 0
;; could assume EAX?
.ERR <burp!>
ELSE
;; trim instruction and space
y TEXTEQU @SubStr(<&val>,a+1,) ;; dest(?,source)

b INSTR a+1,<&val>,<!,>
IF b NE 0
;; trim off source and comma
y TEXTEQU @SubStr(<&val>,a+1,b-a-1) ;; dest
ENDIF
ENDIF
EXITM y ; return destination
ENDM
This allows for instructions of one or more operands.

Edit: Posted on 2002-05-17 08:31:54 by bitRAKE
OK,

I have the following working, its for normal 2 argument instructions and it sems to do what it is supposed to do.


ASM MACRO parameter1,parameter2
LOCAL mnemonic
LOCAL arg1
LOCAL poz

% poz INSTR 1,<parameter1>,< > ;; get the space position
% mnemonic SUBSTR <parameter1>, 1, poz-1 ;; get the mnemonic
% arg1 SUBSTR <parameter1>, poz+1 ;; get the first argument

mnemonic arg1, parameter2

EXITM <arg1>
ENDM

I will have a play with the version you have posted, it looks interesting.

Regards,

hutch@movsd.com
Posted on 2002-05-17 08:44:24 by hutch--
With a slight change my macro could return EAX if instruction is INVOKE. :) This is a very cool idea Hutch-- - thanks for bringing it to attention.

sub ebx, ASM(pop eax)
and ebx, ASM(shld edx,eax,cl)

It's not very good for speed optimization, but I'm hoping that gets fixed in the next version of MASM. ;) Should be able to nest 24 level deep, iirc.
Posted on 2002-05-17 13:03:43 by bitRAKE
I like the idea as well hutch. Its a good one ;)

I noticed bitRake Likes small variable names ;) , So Im posting this as well as extra reference. Its from the Console Window program i E-Mailled you about a while ago. Its was written for Quages to follow, so im sure you should have no problem ;)
; %#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%

; %& THis macro will take an input string like:
; %&
; %& ON Exit THEN Do_Exit
; %&
; %& And produce the code:
; %&
; %& .data
; %& UniqueName db "Exit",0
; %& .code
; %&
; %& invoke StringCompare, addr UniqueName
; %& jz Do_Exit
; %&
; %#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%
ON MACRO CommandString:REQ
LOCAL chop1, chop2, P1, NewName

% P1 equ @InStr(1,<CommandString>,<THEN >) ; Look for the word 'THEN'
IFE P1 eq 0 ; If P1 is NOT zero (IFE)
Chop1 SUBSTR <CommandString>, 1, P1 - 2 ; Get the "text"
Chop2 SUBSTR <CommandString>, P1 + 5 ; Move past "THEN "
.data
; Place this into the data segment:
% NewName db @CatStr( <!">,<&Chop1>,<!">) , 0
.code
% invoke StringCompare, addr NewName
% jz Chop2

ELSE
.err < NO 'THEN' FOUND, CAN'T PROCESS COMMANDS >
ENDIF
ENDM



My only suggestion to your idea is to trim off a letter from "ASM" to keep it as small as possible. From exerience, it gets hard to manage alot of $invoke()'s in one line, mainly cause i run out of line space!! ( You cant break them up into multiple lines ).

My sugestion would be something like this:


[b]$$[/b] MACRO parameter1,parameter2
LOCAL mnemonic
LOCAL arg1
LOCAL poz

% poz INSTR 1,<parameter1>,< > ;; get the space position
% mnemonic SUBSTR <parameter1>, 1, poz-1 ;; get the mnemonic
% arg1 SUBSTR <parameter1>, poz+1 ;; get the first argument

mnemonic arg1, parameter2

EXITM <arg1>
ENDM


And :


$I MACRO args:VARARG
invoke args
EXITM <eax>
ENDM


This way its quick to type $$() is easy, since ASM could get fumbled itno AMS and overlooked (i do stuff like this alot). As well its Quite short, so you can fill your string space with more important information, like long API names ;) . As well using $I() is just as simple and will perform the invoke, with out needing to have the word "invoke" as a mnemonic (which wastes space).

Just my 2 Cents ;) (I know you asked bitRake first)
:NaN:
Posted on 2002-05-17 14:20:10 by NaN
NaN, I'm sure Hutch-- and I both appreciate your input. Yeah, I use short names on local labels - makes changes easier, and forces me to document where needed.

Please, note I've fixed and tested the macro above, now that I'm home. When there are a small number of them, I can keep them all in my head and find outlining control flow more important. I wasn't too far off: one error in logic, one error in syntax.

Try this:
push ASM(sub eax, ASM(and ebx, ASM(shld edx,eax,cl)))
Posted on 2002-05-17 19:31:38 by bitRAKE
Nan,

Your contribution is more than welcome, the problem is with me is that I usually do my parsing in a very grunty dialect of basic and to come back to the format of MASM macros takes a bit of adjustment to get it to work again. :)

I already "borrowed" your $invoke macro because it was more efficient than the form I had written, renamed it FUNC to be consistent with the macro naming I have with the code wizards and I wanted ASM to be consistent with the existing naming.


invoke DialogBoxParam,ASM(mov hInstance,FUNC(GetModuleHandle, NULL)),100,0,
ASM(mov eax,offset WndProc0),0


About the only limitation I can find is that the macros don't like being split across lines and the "\" line join operator does not work with it. Maybe I am doing something wrong but I have not found a way around it yet.

I have to work out if I can use Ricky's macro as I had in mind being able to use it like a function with 2 argument instructions where the destination being the result is placed in the context where it occurs.

Regards,

hutch@movsd.com
Posted on 2002-05-17 23:02:02 by hutch--
Originally posted by hutch--
About the only limitation I can find is that the macros don't like being split across lines and the "\" line join operator does not work with it. Maybe I am doing something wrong but I have not found a way around it yet.


Not at all, this is a limitation i discovered a while ago. Its a little disapointing, as due to API name lengths, you can run out of room (visually) quite quickly and not be able to "nest" deeper with these macros. This is back to my point of keeping their names as small as possible.

But i also realize it is *more* cryptic here :grin:

:alright:
NaN
Posted on 2002-05-18 00:28:12 by NaN