Author Topic: Global defined variables vs procedure arguments  (Read 18772 times)

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Global defined variables vs procedure arguments
« on: January 14, 2014, 10:33:24 AM »
Hello!

Used NASM 2.10.09.

Win64 DEMO1, this is not working, but it should.
Problem is, that macro expands it's arguments, so, instead of receiving hWnd, it expands and receives 0xFEEDABEEF.
Hey, it's actually pretty funny.
Code: [Select]
        ...

        %define hWnd 0xFEEDABEEF

        ...

        proc   my_p, ptrdiff_t hWnd, ptrdiff_t sz_Content, ptrdiff_t sz_Title
        locals none

; This produces an error
                ; DEMO1.asm:25: error: symbol `my_p.hWnd' undefined
    invoke    MessageBox, ptrdiff_t [argv(.hWnd)], ptrdiff_t [argv(.sz_Content)], ptrdiff_t [argv(.sz_Title)], MB_OK

; This is ok
invoke    MessageBox, ptrdiff_t [argv(.0xFEEDABEEF)], ptrdiff_t [argv(.sz_Content)], ptrdiff_t [argv(.sz_Title)], MB_OK

        endproc

        ...

NASM: There is a need for a "macro definition", that doesn't expands it's arguments upon receival::)

This is how it should be:
Code: [Select]
        %define hWnd 0xFEEDABEEF

        %macro mymacro 1
                %warning %1        ; Should output hWnd
                %warning %[%1]   ; Should output 0xFEEDABEEF
        %endmacro

        mymacro hWnd
But it doesn't, it output's 0xFEEDABEEF, 0xFEEDABEEF.

Bye.
Encryptor256's Investigation \ Research Department.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Global defined variables vs procedure arguments
« Reply #1 on: January 15, 2014, 01:10:53 AM »
The macro isn't what's causing the error. When you set hWnd to 0xFEEDABEEF the PROC line changes from:

Code: [Select]
        proc   my_p, ptrdiff_t hWnd, ptrdiff_t sz_Content, ptrdiff_t sz_Title
to something like this:

Code: [Select]
        proc   my_p, ptrdiff_t 0xFEEDABEEF, ptrdiff_t sz_Content, ptrdiff_t sz_Title
As you see, the macro isn't expanding the argument, the argument is changed before it reaches the macro. That in itself, isn't an error. It's supposed to work that way.

About Bryant Keller
bkeller@about.me

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
Re: Global defined variables vs procedure arguments
« Reply #2 on: January 15, 2014, 02:18:45 AM »
FEEDABEEF....hehe...sort of reminds me of the Java bytecode signature CAFEBABE.  ;D

What's interesting here is that, by default for Win64, the procedure's argument stack space is pre-filled with argument data.  Reference this NASMX thread for further information regarding FASTCALL_STACK_PRELOAD.

Thus what the demo is attempting to do is obtain the value contained at the defined my_p.hWnd stack offset.  The dot notation is used within the procedure in order to permit multiple procedures within the same file to use the same parameter names regardless of the position of the argument within the parameter list without forcing the developer to use some crazy define/undefine scheme.  It was designed that way to help prevent developers from shooting themselves in the foot.  See the official Nasm documentation for further information regarding label names to better understand what NASMX is doing under the covers with that notation.

The fact that you've used ptrdiff_t [argv(.FEEDABEEF)] as a parameter name reference within the procedure is certainly not correct as there exists no my_p.FEEDABEEF label defined during assembly.  When you say that the program works I'm assuming that you mean it assembles since obviously the referenced stack address supplied would/should cause the resultant program to crash.

Of course, knowing the x64 calling convention for Win64 you most certainly could use the rcx, rdx, r8, r9 registers directly for such a simply function.  However, it's when your functions begin to grow in size and complexity that you'll start to appreciate what NASMX does for you.  The fact that NASMX hides a lot of repetitive calling convention framework gunk also makes it great for students new to assembly programming.

The demos simply showcase the syntax.  Think of them as documentation.  However, there is a slight learning curve.  Try experimenting with the macros IF, WHILE, & BREAK to see what I mean regarding handling code complexity, structure, and speed of development.  Some of the work Mathi did with the OpenGL and graphics demos shows some of what can be done.

Hope that helped!




Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Global defined variables vs procedure arguments
« Reply #3 on: January 15, 2014, 07:45:43 AM »
Thanks for the answers, it helped and clarified my thinking.

Encryptor256's Investigation \ Research Department.