Author Topic: more macro problems - local variables  (Read 16304 times)

mark allyn

  • Guest
more macro problems - local variables
« on: August 15, 2009, 08:37:58 PM »
Hi everyone -

I can't get the call to _gets in the following macro to run:extern _gets
   extern _fflush
   ;extern _getchar
_adder2:
   %push mycontext
   %stacksize flat
   %assign %$localsize 8
   %local locnum:dword
   %local charbuf:dword
   enter %$localsize, 0
   mov dword [locnum], __float32__ (40.20)
   fld dword [locnum]

push charbuf      ;line 156  error - invalid operand type
   call _gets   

add esp, 4
   leave
   ret
   %pop

As you can see, the code fails on the push instruction.  I am pretty new to macros, and I guess I just need a bit of guidance on doing this.  

Thanks to everyone,
Mark Allyn

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: more macro problems - local variables
« Reply #1 on: August 15, 2009, 11:49:28 PM »
Please don't use gets.

The syntax you want is "push dword [charbuf]" ("charbuf" is ebp + ???), but you appear to be using it uninitialized.

But, really, please don't use gets. The accursed "professionals" make enough buffer overruns for the creeps to exploit!

Best,
Frank

mark allyn

  • Guest
Re: more macro problems - local variables
« Reply #2 on: August 16, 2009, 12:07:21 PM »
Hi Frank.

First, thanks for the reply.

I'm still pulling my hair out, however.  I have tried your syntax.  The problem seems to be traceable to the declaration of charbuf as a local variable.  If charbuf is declared outside the text of this subroutine and located in the [section .bss], the version I sent you is assembled fine (it has a different problem).  If charbuf is declared as a local variable, however, the code does not assemble and I get the message you saw.

This brings me to a maybe more fundamental point about local variables.  As you can see, I made charbuf in the code I sent a local dword.  Suppose, however, I wanted to declare charbuf as a buffer of N bytes (as I would and could in a C subroutine, i. e. char charbuf[80] ; ).
How do I do this in NASM subroutine?  In reading the NASM manual, I can't find anything on this subject.  All i can think of is to do some sort of malloc call and grab some heap.  But, you don't have to do that in C and I can'[t see why it should be required in a NASM subroutine.  I must be missing something.....

Now, back to the failure of this subroutine.  Let's forget about the local charbuf version.  If I put charbuf in the .bss section, the code assembles.  BUT, the call to _gets isn't executed...the program just blows right by the call and terminates normally.  So, I can't figure why the _gets instruction is ignored, even though the push charbuf instruction works fine.

I take your point about not using _gets.  I understand the buffer bit.  I was just using _gets as a convenient and fast way to try to learn how to write a subroutine using the macro approach.  If I were doing this "for real" I would go with _fgets or ReadFile.

Final comment:  I actually don't understand your code on the push dword [charbuf].  My understanding is that _fgets is looking for a buffer POINTER to be pushed, not the contents.  That is why I coded it as push charbuf.  

I apologize for consuming so much of your time on this whole business.  You have been very patient.  Thanks for that.

Mark Allyn

mark allyn

  • Guest
Re: more macro problems - local variables
« Reply #3 on: August 16, 2009, 03:49:32 PM »
Hi again, Frank,

OK, so a piece of the macro problem has been solved.  A very big piece, actually.

This code does run:
[section .text]
   extern _gets
   extern _puts

_adder2:
   %push mycontext
   %stacksize flat
   %assign %$localsize 8
   %local locnum:dword
   %local locbuf:dword
   enter %$localsize, 0      ;l 152
   mov dword [locnum], __float32__ (40.20)
   fld dword [locnum]
   xor eax,eax
   lea eax, [locbuf]  ; This is critical!!

push eax
   call _gets
   add esp, 4
   push eax
   call _puts
   add esp, 4

leave
   ret
   %pop

It came down to nothing more than the lea instruction to push the pointer on the stack.  _gets runs as it should, albeit it should, in line with your comments, actually not be the preferred way to get input off stdin.

Now, if you could simply explain how I can get the locbuf local variable to have N bytes reserved for it on the stack, I would be one happy camper.

Regards,
Mark Allyn