NASM - The Netwide Assembler

NASM Forum => Using NASM => Topic started by: JoeCoder on June 09, 2011, 04:29:51 PM

Title: More questions on macros. Alphanumeric test possible?
Post by: JoeCoder on June 09, 2011, 04:29:51 PM
Hello again. I read Section 4.4.4: %if: Testing Arbitrary Numeric Expressions. The subheading seems to imply there is no alphanumeric test at least if you use %if.

Can I do something like:

Code: [Select]
%macro mymacro 2
%if %1 = "cat"
   mov ah,%2
%else
   mov al,%2
%endif
%endmacro

mymacro cat,45

Is there any way to deal with alphanumeric parms?
Title: Re: More questions on macros. Alphanumeric test possible?
Post by: Mathi on June 09, 2011, 05:12:07 PM
Yes, we can do something like

%if  %1='CAT'
      ;;codeblock1
%elif %1='DOG'
      ;;codeblock2
%else
      ;;codeblock3
%endif
Title: Re: More questions on macros. Alphanumeric test possible?
Post by: JoeCoder on June 09, 2011, 05:52:09 PM
Thank you. It's not working exactly like I want. I realize I have to quote the parm to get the macro to work. I wonder if there is a way to do it without quoting the parm when invoking the macro. In other words it works when I use
Code: [Select]
mymacro 'cat',5

but not
Code: [Select]
mymacro cat,5
Title: Re: More questions on macros. Alphanumeric test possible?
Post by: Keith Kanios on June 09, 2011, 07:08:32 PM
A mix between %ifstr (http://www.nasm.us/doc/nasmdoc4.html#section-4.4.6) and %defstr (http://www.nasm.us/doc/nasmdoc4.html#section-4.1.8) should help.

Otherwise, you might want to look at %ifidn (http://www.nasm.us/doc/nasmdoc4.html#section-4.4.5).
Title: Re: More questions on macros. Alphanumeric test possible?
Post by: JoeCoder on June 10, 2011, 08:19:18 AM
Excellent! Thank you.

Code: [Select]
                                 %macro mymacro 2
     2                                  %defstr cat 'cat'
     3                                  
     4                                  %ifstr %1 = cat
     5                                     mov ah,%2
     6                                  %else
     7                                     mov al,%2
     8                                  %endif
     9                                  
    10                                  %endmacro
    11                                  
    12                                  section .text
    13                                   global _start
    14                                  _start:
    15                                   mymacro cat,16
    16                              <1> %defstr cat 'cat'
    17                              <1>
    18                              <1> %ifstr %1 = cat
    19 00000000 B410                <1>  mov ah,%2
    20                              <1> %else
    21                              <1>  mov al,%2
    22                              <1> %endif
    23                              <1>
    24                                  
    25 00000002 90                       nop
    26                                  
    27                                   mymacro dog,32
    28                              <1> %defstr cat 'cat'
    29                              <1>
    30                              <1> %ifstr %1 = cat
    31                              <1>  mov ah,%2
    32                              <1> %else
    33 00000003 B020                <1>  mov al,%2
    34                              <1> %endif
    35                              <1>

%ifidn seems even better for my case because you don't have to define a string to test against. And %ifidni is best of all because it's case insensitive:

Code: [Select]
     1                                  %macro mymacro 2
     2                                 
     3                                  %ifidni %1,cat
     4                                     mov ah,%2
     5                                  %else
     6                                     mov al,%2
     7                                  %endif
     8                                 
     9                                  %endmacro
    10                                 
    11                                  section .text
    12                                  global _start
    13                                  _start:
    14                                  mymacro cat,16
    15                              <1>
    16                              <1> %ifidni %1,cat
    17 00000000 B410                <1>  mov ah,%2
    18                              <1> %else
    19                              <1>  mov al,%2
    20                              <1> %endif
    21                              <1>
    22                                 
    23 00000002 90                      nop
    24                                 
    25                                  mymacro CAT,32
    26                              <1>
    27                              <1> %ifidni %1,cat
    28 00000003 B420                <1>  mov ah,%2
    29                              <1> %else
    30                              <1>  mov al,%2
    31                              <1> %endif
    32                              <1>
    33                                 
    34 00000005 90                      nop
    35                                 
    36                                  mymacro dog,62
    37                              <1>
    38                              <1> %ifidni %1,cat
    39                              <1>  mov ah,%2
    40                              <1> %else
    41 00000006 B03E                <1>  mov al,%2
    42                              <1> %endif
    43                              <1>

It works! Sorry for my trivial example. I actually have a good reason for asking this question but I didn't want to post my real code because I am still working out other details and trying to figure out the best way to do what I am trying to do and am not ready for that discussion yet.