News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Macro Magic: __func__ in MASM?

Started by dawnraider, October 15, 2016, 02:09:30 PM

Previous topic - Next topic

dawnraider

Hi all,

Much head scratching and experimentation have been expended and yet there does not seem to be a solution.

Is there any trick or loop-hole in MASM where you can discover the name of the currently assembling PROC?
(equivalent to the C __FUNC__ preprocessor variable).

Thanks in advance,

hutch--

You could always add an extra parameter to your macro that contains the procedure name.

MyMacro "procname",args:VARARG
  ; your macro code
ENDM

jj2007

include \Masm32\MasmBasic\Res\JBasic.inc      ; ## builds in 32- or 64-bit mode with ML, AsmC, JWasm, HJWasm ##
.code
MyTest proc <cb> sometext:SIZE_P
  Print sometext
  % PrintLine "&jbProc$"      ; yep, this requires MasmBasic ;-)
  ret
MyTest endp
Init
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
  jinvoke MyTest, Chr$("** We are now in a proc called ")
  Inkey "That was simple, right? And it does not require any additional libraries, just MasmBasic..."
EndOfCode


Output:
This code was assembled with ml64 in 64-bit format
** We are now in a proc called MyTest
That was simple, right? And it does not require any additional libraries, just MasmBasic...

hutch--

The simplest way is like this.

Put this in your Wndproc. Same for any other proc but with the correct proc name.

    % echo WndProc

jj2007

Yes indeed, to see what you are assembling the solution proposed by Hutch is the right one:
MyTest proc
  tmp$ CATSTR <Currently assembling MyTest in line >, %@Line
  % echo tmp$
  .err


The .err prevents the assembly to succeed. This can be useful for testing if you don't want the link & run phases. You can put the .err also right before "end start".

What is the background of your request? What do you want to achieve?

dawnraider

#5
Thanks for the suggestions.

Actually, the suggestions about passing the PROC name as a macro argument gave me an idea as I was doing that anyway, and I soon came up with a solution that worked.

I've outlined the problem below. If anybody is interested in how I fixed it, or has their own ideas about how to fix it, then please show your interest by dropping a reply on this thread.

Cheers.




The objective was to check that when I used one of my special debugging macros within a PROC, that the PROC in question was the one I was expecting.

I have a set of tools whereby if I have a PROC like this (for example):


MyTestFunc PROC param1:PTR, param2:DWORD


I can enable it for debugging with my own debugging framework by adding a custom directive to the prototype, like so:


DEBUG MyTestFunc PROC param1:PTR, param2:DWORD


After this one addition to the prototype, I can use various custom "instructions" inside the function that pass data to the caller (in C) for outside analysis.
For example, my register state capture instruction regsave :


        movdqa      xmm5,   xmmword ptr [edi + ecx] ; load next four pixels from destination (P3D,P2D,P1D,P0D).
        pmovzxbw    xmm1,   xmm5                    ; expand bytes 7:0 (P1D,P0D) into 16-bit words.
        psrldq      xmm5,   8                       ; (P3D,P2D) >>= 64
        pmovzxbw    xmm5,   xmm5                    ; expand bytes 7:0 (P3D,P2D) into 16-bit words.

        regsave     gx                              ; capture GP and XMM registers (<<< this is my own debugging "instruction")

        pmullw      xmm1,   xmm2                    ; (P1D,P0D) *= (P1X,P0X) : srce + (dest * (1.0 - srce.alpha))
        pmullw      xmm5,   xmm6                    ; (P3D,P2D) *= (P3X,P2X)
        pcmpeqw     xmm2,   xmm2
        psrlw       xmm2,   15                      ; => [0x0001|0x0001|0x0001|0x0001|0x0001|0x0001|0x0001|0x0001]
        mov         eax,    002020202h
        movd        xmm6,   eax
        pshufd      xmm6,   xmm6,   0               ; => [0x0202|0x0202|0x0202|0x0202|0x0202|0x0202|0x0202|0x0202]

        regsave     gx                              ; capture GP and XMM registers (<<< this is my own debugging "instruction")


A situation arose that if I have the DEBUG setup on one PROC, and the special instruction placed in another, like this:


DEBUG MyTestFunc PROC param1:PTR, param2:DWORD
...
MyTestFunc ENDP

MyOtherFunc PROC param1:DWORD, param2:PTR
...
        regsave     gx
...
MyOtherFunc ENDP


then how do I raise an error on the regsave saying that the PROC MyOtherFunc is not "debug enabled"?

The problem is that the name of any symbol defined inside a macro has to be stored in a global somewhere otherwise it becomes invisible outside the macro that defines it.
However, such global macros do not go out of scope when the scope of the current PROC ends, because macros have no notion of a "PROC". Hence, in the
example above, my custom regsave instruction in PROC MyOtherFunc gets confused because it is seeing the variables set up by the completely different PROC MyTestFunc.

This is why I thought I needed __FUNC__.