pts
pts

Reputation: 87291

Emulating %defstr in earlier versions of NASM

Is there a way to emulate %defstr in NASM versions earlier than 2.03, preferably 0.99.06? More particularly, I want this macro to work:

%macro name 1
%defstr __namestr__ %1
%1: db __namestr__, 0
%endmacro

so that name hello would be equivalent to hello: db 'hello', 0. It already works in NASM 2.03 and later. I need it in a portable NASM include file, and requiring the user to upgrade NASM is not an option.

This doesn't work, it emits a literal %1 (2 bytes) + NUL.

%macro name 1
%1: db '%1', 0
%endif

NASM 0.99.06 .. NASM 2.02 documentation says that a workaround can be created using a multi-line macro (for converting tokens to a string literal), but it doesn't specify how. The full excerpt:

   The `%!<env>' directive makes it possible to read the value of an
   environment variable at assembly time. This could, for example, be
   used to store the contents of an environment variable into a string,
   which could be used at some other point in your code.

   For example, suppose that you have an environment variable `FOO',
   and you want the contents of `FOO' to be embedded in your program.
   You could do that as follows:

   %define FOO    %!FOO 
   %define quote   ' 

   tmpstr  db      quote FOO quote

   At the time of writing, this will generate an "unterminated string"
   warning at the time of defining "quote", and it will add a space
   before and after the string that is read in. I was unable to find a
   simple workaround (although a workaround can be created using a
   multi-line macro), so I believe that you will need to either learn
   how to create more complex macros, or allow for the extra spaces if
   you make use of this feature in that way.

Upvotes: 1

Views: 98

Answers (2)

pts
pts

Reputation: 87291

If the set of possible namestr values is small, then they can be predefined:

%define NAME_foo 'foo'
%define NAME_bar 'bar'
%define NAME_foobar 'foobar'

%macro name 1
%1: db NAME_%1, 0
%endmacro

Upvotes: 1

Kai Burghardt
Kai Burghardt

Reputation: 1566

  • The preprocessor macro %defstr is “smart” enough and escapes, for instance, any occurrence of string delimiter characters. Therefore it’s different from a %define simply surrounding the argument with quotes.
  • However, in your specific case, since the first and only parameter to the name macro must also be suitable label, you do not have to worry about problematic characters. Taking the excerpt from the documentation as inspiration and after having verified that %+ was already documented in 0.98.x, you can write something like:
    %define quote '
    
    %macro name 1
      %1: db quote %+%1%+ quote, 0
    %endmacro
    
    I did only check this with NASM version 2.15.05, so no guarantee that this indeed works with 0.99.06.

Upvotes: 2

Related Questions