Hi all
I have tried to things with macros that rely on forward referencing. I have been playing around for a few weeks, on and off and have been biting my teeth out over this. I started with the docs:
When the expansion of a single-line macro contains tokens which invoke another macro, the expansion is performed at invocation time, not at definition time. Thus the code
%define a(x)    1+b(x)
%define b(x)    2*x

        mov    ax,a(8)
will evaluate in the expected way to mov ax,1+2*8, even though the macro b wasn't defined at the time of definition of a.
In a similar fashion:
To have a reference to an embedded single-line macro resolved at the time that the embedding macro is defined, as opposed to when the embedding macro is expanded, you need a different mechanism to the one offered by %define. The solution is to use %xdefine.
So far all pretty straight forward. As soon as I started to code, it became obvious that I lack some fundamental knowledge of the Nasm preprocessor. Example from the doc's:
%macro  writefile 2+

        jmp    %%endstr
  %%str:        db      %2
  %%endstr:
        mov    dx,%%str
        mov    cx,%%endstr-%%str
        mov    bx,%1
        mov    ah,0x40
        int    0x21

%endmacro
With an unconditional jump at the beginning of the macro, %%str: db %2 should never execute??
I  found it next to impossible to track intermediate results of the preprocessor stage. Also there seems to be no difference between the number of passes selected with -O option (1-x)

The code example is a stripped down version of  a proc and invoke macro pair (to reduce the length of  the post). The intention was to create a proc (OutMessage) and define it as %define %{1} PROC_ %+ %{1} %+ _Local. In the invk macro I try to check for %ifdef PROC_%{1}_Local. If true make a local call and if it isn't, declare it as EXTERN %{1}.

%define DefLocal(x)    ProcDef (x) %+ _Local 

%imacro PROC 1-*
%warning inside Proc ,Name of proc: %{1}
%push _PROC
GLOBAL  %1
%1:
%ifndef PROC_%{1}_Local
;%xdefine %{1} PROC_ %+ %{1} %+ _Local  ;seems to produce same results as DefLocal(%{1})
DefLocal(%{1})
%warning inside Proc  ifndef loop %{1}
%endif
%endmacro

%macro ENDP 0-1
.@End_of_Proc:
ret
%pop
%endmacro


%MACRO invk 1-*
%warning in invoke %1
%ifdef PROC_%{1}_Local
;%ifid  %{1}
%warning In invk proc:  %{1} defined as label

%elifndef %1              ;PROC_%{1}_Local
%warning In invk proc:  %{1} is defiend Extern
;EXTERN %{1}
%endif
call %1

%endmacro

%define ProcDef(x)    PROC_ %+ x

SECTION .data

message  DB  'Trying Nasm Preprocessr',13,10,\
'An atempt on forward referencing',0

buffer    TIMES 1024 db 0
caption db 'Testing',0
SECTION .text


Global  start
start: 
      invk OutMessage
      invk OutMessage
      push 0
      invk ExitProcess
 
PROC OutMessage
  push 0
      push caption
      push message
      push 0
      invk MessageBoxA
ENDP 

;Radasm IDE 3,O,$B\NASM -Ox -fwin32 ,2
;5,O,$B\GOLINK @$B\GFL.txt,3


As far as I can see the problem seems to be that invoke is expanded before proc. Therefore Outmessage will be (invk:7) In invk proc: OutMessage is defined Extern. For the same reason %elifid %1 does not seem to work.
I have also tried :%define %${1} PROC_ %+ %{1} %+ _Local
This seems to work for local calls but fails when an api call is made.
Is there a way to make this work (Nasm being a multipass assembler?) Second, what help tools are there available to make Nasm more verbose in its preprocessor out put?

Thanks Klod
Posted on 2009-11-08 17:15:24 by Klod

I  found it next to impossible to track intermediate results of the preprocessor stage. Also there seems to be no difference between the number of passes selected with -O option (1-x)
...
Is there a way to make this work (Nasm being a multipass assembler?)


NASM is a multi-pass assembler, but you can ultimately think of the preprocessor as a single stage. Optimization only affects code generation.

A solution to your problem is to do what other languages do, declaration and definition. An advantage of said solution is the reduction of code ambiguity.


Second, what help tools are there available to make Nasm more verbose in its preprocessor out put?


Have you tried NASM with the listfile (-l) option?
Posted on 2009-11-09 01:48:27 by SpooK
Thanks for your reply SpooK

Yes and now. no on larger projects, I find it very difficult to sift through several thousand declared symbols. Yes for small tests like this one.
Nasm terminates if it encounters an error leaving very few clues.

English is not my first language. There is always a chance for misinterpreting something.  If I read a statement and its meaning comes out the same in my original language then I conclude that I understand the text. However this is not synonymous with full comprehension of the subject described. If I can transform the information conveyed into a working code snippet, then I conclude that I understand and comprehend.

%define a(x)    1+b(x)
%define b(x)    2*x  

This suggests that some limited forward referencing is possible, also

%define and %xdefine. expansion performed at invocation time vs. definition time suggests there is a mechanism to influence "when" a given macro is expanded. Hierarchy?

looking forward to your reply
Klod

Posted on 2009-11-12 22:15:25 by Klod

Thanks for your reply SpooK

Yes and now. no on larger projects, I find it very difficult to sift through several thousand declared symbols. Yes for small tests like this one.
Nasm terminates if it encounters an error leaving very few clues.

English is not my first language. There is always a chance for misinterpreting something.  If I read a statement and its meaning comes out the same in my original language then I conclude that I understand the text. However this is not synonymous with full comprehension of the subject described. If I can transform the information conveyed into a working code snippet, then I conclude that I understand and comprehend.

%define a(x)    1+b(x)
%define b(x)    2*x  

This suggests that some limited forward referencing is possible, also


In that order, a(x) and b(x) are both defined before they are ever referenced/expanded.


%define and %xdefine. expansion performed at invocation time vs. definition time suggests there is a mechanism to influence "when" a given macro is expanded. Hierarchy?

looking forward to your reply
Klod


Akin to the above statement, a %define is only processed/expanded when it is referenced. %xdefine is processed/expanded immediately, instead of waiting for an initial reference.

However, the %define and %xdefine directives are the means to influence the macro expansion, in this context. The source code portions that process these directives do the rest behind the scenes.
Posted on 2009-11-13 10:54:04 by SpooK