Author Topic: call [TestProcwithlongname]  (Read 16543 times)

Klod

  • Guest
call [TestProcwithlongname]
« on: February 07, 2010, 06:02:29 AM »
For the last several weeks I have been racking my brain to find a solution for a problem with forward referencing that can't be done in Nasm. I'm including a stripped down version of the macros.

Code: [Select]
[code]; assemble     \nasm\bin\NASM -f win32
;link \nasm\bin\golink   /console  @\nasm\bin\GFL.txt <--- name of DLL's

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Console program with no import files and def's
; Klod
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%imacro PROC 0-*
%push PROC
%if %0 =0
%assign %$params 0
%assign %$i 0
%assign %$params 0
%assign %$i 0 ;No Args or Params, so no stack frame
%elif %0 >= 1
push ebp
mov ebp,esp
%assign %$i 8
%rep %0
%rotate 1
%xdefine @%1 ebp+%$i
%assign %$i %$i+4
%endrep
%assign %$i 0
%assign %$params %0-1
%endif
%endmacro

%imacro ENDP 0-1
.@End_of_Proc:
%ifctx PROC
%if %$params =0
ret
%else
mov esp,ebp
pop ebp
%assign %$params %$params*4
ret %$params
%endif
%pop
%else
%error "PROC must be used before ENDPROC"
%endif
%endmacro

%macro invke 1-*.nolist
%rep %0-1
%rotate -1
push dword %1
%endrep
%rotate -1
%ifnid %1
%warning %1 'is a label'
%defstr temp, %1 ;remove the square brakets
%substr temp1 temp 4,-2
%deftok _funcname temp1
%warning _funcname 'is a label'
call _funcname
%else
extern %1
%warning defined extern
call %1
%endif

%endmacro


section .data
msg DB 'Press any key to continue...',13,10
DB 'This is the second line'
.len
message db "just a line to output",0
NewLine db 13,10,0
section .bss
hStdIn RESD 1
hStdOut RESD 1
hBuffer RESD 1
hNum RESD 1
hMode RESD 1
;*****************************************************************************************************************************
section .text
start:

invke GetStdHandle, -11 ;STD_OUTPUT_HANDLE
mov dword[hStdOut],eax
invke [Test1],hStdIn,msg
invke StdOut,NewLine
invke StdOut,NewLine
invke [TestProcwithlongname]
invke WriteFile, [hStdOut], DWORD msg, DWORD msg.len-msg, DWORD hNum, DWORD 0
invke GetStdHandle, -10 ;STD_INPUT_HANDLE
mov DWORD[hStdIn], eax
invke GetConsoleMode, eax, DWORD hMode
mov eax, DWORD[hMode]
and al, 1
invke SetConsoleMode, DWORD[hStdIn], eax
invke  WaitForSingleObject, DWORD[hStdIn], DWORD 0xFFFFFFFF
invke ReadFile, DWORD[hStdIn], DWORD hBuffer, DWORD 1, DWORD hNum, DWORD 0
invke ExitProcess, DWORD 0

;****************************************************************************************************************************
Test1: Proc con,tre
invke WriteFile, dword[hStdOut], message, 22, DWORD hNum, DWORD 0
ENDP

TestProcwithlongname: Proc
invke WriteFile, dword[hStdOut], message, 22, DWORD hNum, DWORD 0
ENDP
[/code]

There is a small problem I have not been able to find an answer:
if I do:
call TestProcwithlongname works as expected
invke TestProcwithlongname ---> ERROR TestProcwithlongname redefined
invke [TestProcwithlongname]  compiles but hangs

I have to remove the [] in the macro to make it work.

Anybody any Idea why?

Regards Klod

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: call [TestProcwithlongname]
« Reply #1 on: February 07, 2010, 09:39:53 PM »
%ifnid is skipping past TestProcwithlongname as it is an identifier, causing your %else to extern it and cause a redefinition error.

Klod

  • Guest
Re: call [TestProcwithlongname]
« Reply #2 on: February 07, 2010, 10:21:50 PM »
Thanks Keith Kanios for your quick reply.
I'm not 100% sure if I understood your answer but interpret it as this to be a trait of Nasm and not a bug.
The answer may be in the interpretation of "identifier". I read it as a label to be an identifier too.
I was surprised by %ifnid %1 to "work". I expected  %ifid %1.
I have rechecked my code and I have 2 errors when I invke without the []:
C:\NasmEd\Project\MAcroProtoType\MAcroProtoType.asm:105: error: symbol `TestProcwithlongname' redefined
C:\NasmEd\Project\MAcroProtoType\MAcroProtoType.asm:109: error: symbol `.@End_of_Proc' redefined and your right with the error assessment.

Although the use of the square brackets seems to work I' m not quite happy with this "solution" because it is not consistent with the regular addressing of memory that I like about Nasm.

Klod

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
Re: call [TestProcwithlongname]
« Reply #3 on: February 08, 2010, 04:06:17 AM »
The short version is that identifiers are anything but other alpha-numeric sequences such as operators, numbers, strings, instructions, etc. NASM Doc Chapter 3 illustrates what a valid identifier is.

As for your code, the label reference is an identifier, you are using %ifnid (if not an identifier) so it yields to the paired %else, in turn making an extern out of the forward label reference.

Take a look at nasmx.inc (and preferably one demo/example) from the NASMX package to get an idea of how it uses PROC/IMPORT & INVOKE.

Klod

  • Guest
Re: call [TestProcwithlongname]
« Reply #4 on: February 08, 2010, 04:32:48 AM »
Thanks for your reply
I have played around for the best part of the afternoon with trying to come up with better solutions for testing various tokens and checking how Nasm interprets them.
I have attached a small program that should demonstrate my confusion on the matter. I have stripped my macros down some more to avoid the redeclaration of the symbols by extern, or at least so I think. I have then calling a macro (invke) with different kind of things and tryed to figure out how it works. I have come to the same conclusion as you have suggested. With the exception of strings and numbers, everything seems to be treated as identifier/label. Anything in [] is interpreted as single line macro.
%elifmacro %1 %0      ; should trap proct  4.4.2 %ifmacro: Testing Multi-Line Macro Existence
%ifmacro proct 1 will treat everything as multiline macro,  is the opposite of what I intended to test, just as the %ifnid %1 in my original post.

As I said, I was playing around :P