forked from netwide-assembler/nasm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreproc.src
More file actions
2752 lines (1998 loc) · 92.5 KB
/
Copy pathpreproc.src
File metadata and controls
2752 lines (1998 loc) · 92.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\C{preproc} The NASM \i{Preprocessor}
NASM contains a powerful \i{macro processor}, which supports
conditional assembly, multi-level file inclusion, two forms of macro
(single-line and multi-line), and a `context stack' mechanism for
extra macro power. Preprocessor directives all begin with a \c{%}
sign. As a result, some care needs to be taken when using the \c{%}
arithmetic operator to avoid it being confused with a preprocessor
directive; it is recommended that it always be surrounded by
whitespace.
The NASM preprocessor borrows concepts from both the C preprocessor
and the macro facilities of many other assemblers.
\H{pcsteps} \i{Preprocessor Expansions}
The input to the preprocessor is expanded in the following ways in the
order specified here.
\S{pcbackslash} \i{Continuation} Line Collapsing
The preprocessor first collapses all lines which end with a backslash
(\c{\\}) character into a single line. Thus:
\c %define THIS_VERY_LONG_MACRO_NAME_IS_DEFINED_TO \\
\c THIS_VALUE
will work like a single-line macro without the backslash-newline
sequence.
\IR{comment removal} comment, removal
\IR{comment removal} preprocessor, comment removal
\S{pccomment} \i{Comment Removal}
After concatenation, comments are removed.
\I{comment, syntax}\i{Comments}
begin with the character \c{;} unless contained
inside a quoted string or a handful of other special contexts.
\I{ccomment}Note that this is applied \e{after} \i{continuation} lines
are collapsed. This means that
\c add al,'\\' ; Add the ASCII code for \\
\c mov [ecx],al ; Save the character
will probably not do what you expect, as the second line will be
considered part of the preceeding comment. Although this behavior is
sometimes confusing, it is both the behavior of NASM since the very
first version as well as the behavior of the C preprocessor.
\S{pcline}\i\c{%line} directives
In this step, \i\c{%line} directives are processed. See \k{line}.
\S{pccond}\I{preprocessor conditionals}\I{preprocessor loops}
Conditionals, Loops and \i{Multi-Line Macro} Definitions
In this step, the following \i{preprocessor directives} are processed:
\b \i{Multi-line macro} definitions, specified by the \i\c{%macro} and
\i\c{%imacro} directives. The body of a multi-line macro is stored and
is not further expanded at this time. See \k{mlmacro}.
\b \i{Conditional assembly}, specified by the \i\c{%if} family of preprocessor
directives. Disabled part of the source code are discarded and are not
futher expanded. See \k{condasm}.
\b \i{Preprocessor loops}, specified by the \i\c{%rep} preprocessor
directive. A preprocessor loop is very similar to a multi-line macro
and as such the body is stored and is not futher expanded at this
time. See \k{rep}.
These constructs are required to be balanced, so that the ending of a
block can be detected, but no further processing is done at this time;
stored blocks will be inserted at this step when they are expanded
(see below.)
It is specific to each directive to what extent \i{inline expansions}
and \i{detokenization} are performed for the arguments of the
directives.
\S{pcdirect} \i{Directives} processing
Remaining preprocessor \i{directives} are processed. It is specific
to each directive to what extend the above expansions or the ones
specified in \k{pcfinal} are performed on their arguments.
It is specific to each directive to what extent \i{inline expansions}
and \i{detokenization} are performed for the arguments of the
directives.
\S{pcsmacro} \i{Inline expansions} and other \I{preprocessor directives}directives
In this step, the following expansions are performed on each line:
\b \i{Single-line macros} are expanded. See \k{slmacro}.
\b \i{Preprocessor functions} are expanded. See \k{ppfunc}.
\b If this line is the result of \i{multi-line macro} expansions (see
below), the parameters to that macro are expanded at this time. See
\k{mlmacro}.
\b \i{Macro indirection}, using the \i\c{%[}...\c{]} construct, is
expanded. See \k{indmacro}.
\b Token \i{concatenation} using either the \i\c{%+} operator (see
\k{concat%+}) or implicitly (see \k{indmacro} and \k{concat}.)
\b \i{Macro-local labels} are converted into unique strings, see
\k{maclocal}.
\S{pcmmacro} \i{Multi-Line Macro Expansion}
In this step, \i{multi-line macros} are expanded into new lines of
source, like the typical macro feature of many other assemblers. See
\k{mlmacro}.
After expansion, the newly injected lines of source are processed
starting with the step defined in \k{pccond}.
\S{pcfinal} \i{Detokenization}
In this step, the final line of source code is produced. It performs
the following operations:
\b Environment variables specified using the \i\c{%!} construct are
expanded. See \k{ctxlocal}.
\b \i{Context-local labels} are expanded into unique strings. See
\k{ctxlocal}.
\b All tokens are converted to their text representation. Unlike the C
preprocessor, the NASM preprocessor does not insert whitespace between
adjacent tokens unless present in the source code. See \k{concat}.
The resulting line of text either is sent to the assembler, or, if
running in preprocessor-only mode, to the output file (see \k{opt-E});
if necessary prefixed by a newly inserted \i\c{%line} directive.
\H{slmacro} \i{Single-Line Macros}
Single-line macros are expanded inline, much like macros in the C
preprocessor.
\S{define} The Normal Way: \I\c{%idefine}\i\c{%define}
Single-line macros are defined using the \c{%define} preprocessor
directive. The definitions work in a similar way to C; so you can do
things like
\c %define ctrl 0x1F &
\c %define param(a,b) ((a)+(a)*(b))
\c
\c mov byte [param(2,ebx)], ctrl 'D'
which will expand to
\c mov byte [(2)+(2)*(ebx)], 0x1F & 'D'
When the expansion of a single-line macro contains tokens which
invoke another macro, the expansion is performed at invocation time,
not at definition time. Thus the code
\c %define a(x) 1+b(x)
\c %define b(x) 2*x
\c
\c mov ax,a(8)
will evaluate in the expected way to \c{mov ax,1+2*8}, even though
the macro \c{b} wasn't defined at the time of definition of \c{a}.
Note that single-line macro argument list cannot be preceded by whitespace.
Otherwise it will be treated as an expansion. For example:
\c %define foo (a,b) ; no arguments, (a,b) is the expansion
\c %define bar(a,b) ; two arguments, empty expansion
Macros defined with \c{%define} are \i{case sensitive}: after
\c{%define foo bar}, only \c{foo} will expand to \c{bar}: \c{Foo} or
\c{FOO} will not. By using \c{%idefine} instead of \c{%define} (the
`i' stands for `insensitive') you can define all the case variants
of a macro at once, so that \c{%idefine foo bar} would cause
\c{foo}, \c{Foo}, \c{FOO}, \c{fOO} and so on all to expand to
\c{bar}.
There is a mechanism which detects when a macro call has occurred as
a result of a previous expansion of the same macro, to guard against
\i{circular references} and infinite loops. If this happens, the
preprocessor will only expand the first occurrence of the macro.
Hence, if you code
\c %define a(x) 1+a(x)
\c
\c mov ax,a(3)
the macro \c{a(3)} will expand once, becoming \c{1+a(3)}, and will
then expand no further. This behaviour can be useful: see \k{32c}
for an example of its use.
You can \I{overloading, single-line macros}overload single-line
macros: if you write
\c %define foo(x) 1+x
\c %define foo(x,y) 1+x*y
the preprocessor will be able to handle both types of macro call,
by counting the parameters you pass; so \c{foo(3)} will become
\c{1+3} whereas \c{foo(ebx,2)} will become \c{1+ebx*2}. However, if
you define
\c %define foo bar
then no other definition of \c{foo} will be accepted: a macro with
no parameters prohibits the definition of the same name as a macro
\e{with} parameters, and vice versa.
This doesn't prevent single-line macros being \e{redefined}: you can
perfectly well define a macro with
\c %define foo bar
and then re-define it later in the same source file with
\c %define foo baz
Then everywhere the macro \c{foo} is invoked, it will be expanded
according to the most recent definition. This is particularly useful
when defining single-line macros with \c{%assign} (see \k{assign}).
The following additional features were added in NASM 2.15:
It is possible to define an empty string instead of an argument name
if the argument is never used. For example:
\c %define ereg(foo,) e %+ foo
\c mov eax,ereg(dx,cx)
A single pair of parentheses is a subcase of a single, unused argument:
\c %define myreg() eax
\c mov edx,myreg()
This is similar to the behavior of the C preprocessor.
\b If declared with an \c{=}, NASM will expand the argument and then
evaluate it as a numeric expression. The name of the argument may
optionally be followed by \c{/} followed by a numeric radix character
(\c{b}, \c{y}, \c{o}, \c{q}, \c{d}, \c{t}, \c{h} or \c{x}) and/or the
letters \c{u} (unsigned) or \c{s} (signed), in which the number is
formatted accordingly, with a radix prefix if a radix letter is
specified. For the case of hexadecimal, if the radix letter is in
upper case, alphabetic hex digits will be in upper case.
\b If declared with an \c{&}, NASM will expand the argument and then
turn into a quoted string; if the argument already \e{is} a quoted
string, it will be quoted again.
\b If declared with \c{&&}, NASM will expand the argument and then
turn it into a quoted string, but if the argument already is a quoted
string, it will \e{not} be re-quoted.
\b If declared with a \c{+}, it is a greedy or variadic parameter; it
will include any subsequent commas and parameters.
\b If declared with an \c{!}, NASM will not strip whitespace and
braces (potentially useful in conjunction with \c{&} or \c{&&}.)
For example:
\c %define xyzzy(=expr,&val,=hex/x) expr, str, hex
\c %define plugh(x) xyzzy(x,x,x)
\c db plugh(13+5), `\0` ; Expands to: db 18, "13+5", 0x12, `\0`
You can \i{pre-define} single-line macros using the `-d' option on
the NASM command line: see \k{opt-d}.
\S{xdefine} Resolving \c{%define}: \I\c{%ixdefine}\i\c{%xdefine}
To have a reference to an embedded single-line macro resolved at the
time that the embedding macro is \e{defined}, as opposed to when the
embedding macro is \e{expanded}, you need a different mechanism to the
one offered by \c{%define}. The solution is to use \c{%xdefine}, or
it's \I{case sensitive}case-insensitive counterpart \c{%ixdefine}.
Suppose you have the following code:
\c %define isTrue 1
\c %define isFalse isTrue
\c %define isTrue 0
\c
\c val1: db isFalse
\c
\c %define isTrue 1
\c
\c val2: db isFalse
In this case, \c{val1} is equal to 0, and \c{val2} is equal to 1.
This is because, when a single-line macro is defined using
\c{%define}, it is expanded only when it is called. As \c{isFalse}
expands to \c{isTrue}, the expansion will be the current value of
\c{isTrue}. The first time it is called that is 0, and the second
time it is 1.
If you wanted \c{isFalse} to expand to the value assigned to the
embedded macro \c{isTrue} at the time that \c{isFalse} was defined,
you need to change the above code to use \c{%xdefine}.
\c %xdefine isTrue 1
\c %xdefine isFalse isTrue
\c %xdefine isTrue 0
\c
\c val1: db isFalse
\c
\c %xdefine isTrue 1
\c
\c val2: db isFalse
Now, each time that \c{isFalse} is called, it expands to 1,
as that is what the embedded macro \c{isTrue} expanded to at
the time that \c{isFalse} was defined.
\c{%xdefine} and \c{%ixdefine} supports argument expansion exactly the
same way that \c{%define} and \c{%idefine} does.
\S{indmacro} \i{Macro Indirection}: \i\c{%[}...\c{]}
The \c{%[...]} construct can be used to expand macros in contexts
where macro expansion would otherwise not occur, including in the
names other macros. For example, if you have a set of macros named
\c{Foo16}, \c{Foo32} and \c{Foo64}, you could write:
\c mov ax,Foo%[__?BITS?__] ; The Foo value
to use the builtin macro \c{__?BITS?__} (see \k{bitsm}) to automatically
select between them. Similarly, the two statements:
\c %xdefine Bar Quux ; Expands due to %xdefine
\c %define Bar %[Quux] ; Expands due to %[...]
have, in fact, exactly the same effect.
\c{%[...]} concatenates to adjacent tokens in the same way that
multi-line macro parameters do, see \k{concat} for details.
\S{concat%+} Concatenating Single Line Macro Tokens: \i\c{%+}
Individual tokens in single line macros can be concatenated, to produce
longer tokens for later processing. This can be useful if there are
several similar macros that perform similar functions.
Please note that a space is required after \c{%+}, in order to
disambiguate it from the syntax \c{%+1} used in multiline macros.
As an example, consider the following:
\c %define BDASTART 400h ; Start of BIOS data area
\c struc tBIOSDA ; its structure
\c .COM1addr RESW 1
\c .COM2addr RESW 1
\c ; ..and so on
\c endstruc
Now, if we need to access the elements of tBIOSDA in different places,
we can end up with:
\c mov ax,BDASTART + tBIOSDA.COM1addr
\c mov bx,BDASTART + tBIOSDA.COM2addr
This will become pretty ugly (and tedious) if used in many places, and
can be reduced in size significantly by using the following macro:
\c ; Macro to access BIOS variables by their names (from tBDA):
\c %define BDA(x) BDASTART + tBIOSDA. %+ x
Now the above code can be written as:
\c mov ax,BDA(COM1addr)
\c mov bx,BDA(COM2addr)
Using this feature, we can simplify references to a lot of macros (and,
in turn, reduce typing errors).
\S{selfref%?} The Macro Name Itself: \i\c{%?} and \c{%??}
The special symbols \c{%?} and \c{%??} can be used to reference the
macro name itself inside a macro expansion, this is supported for both
single-and multi-line macros. \c{%?} refers to the macro name as
\e{invoked}, whereas \c{%??} refers to the macro name as
\e{declared}. The two are always the same for case-sensitive
macros, but for case-insensitive macros, they can differ.
For example:
\c %imacro Foo 0
\c mov %?,%??
\c %endmacro
\c
\c foo
\c FOO
will expand to:
\c mov foo,Foo
\c mov FOO,Foo
These tokens can be used for single-line macros \e{if defined outside
any multi-line macros.} See below.
\S{selfref%*?} The Single-Line Macro Name: \i\c{%*?} and \c{%*??}
If the tokens \c{%?} and \c{%??} are used inside a multi-line macro,
they are expanded before any directives are processed. As a result,
\c %imacro Foo 0
\c %idefine Bar _%?
\c mov BAR,bAr
\c %endmacro
\c
\c foo
\c mov eax,bar
will expand to:
\c mov _foo,_foo
\c mov eax,_foo
which may or may not be what you expected. The tokens \c{%*?} and
\c{%*??} behave like \c{%?} and \c{%??} but are only expanded inside
single-line macros. Thus:
\c %imacro Foo 0
\c %idefine Bar _%*?
\c mov BAR,bAr
\c %endmacro
\c
\c foo
\c mov eax,bar
will expand to:
\c mov _BAR,_bAr
\c mov eax,_bar
The \c{%*?} can be used to make a keyword "disappear", for example in
case a new instruction has been used as a label in older code. For
example:
\c %idefine pause $%*? ; Hide the PAUSE instruction
\c{%*?} and \c{%*??} were introduced in NASM 2.15.04.
\S{undef} Undefining Single-Line Macros: \i\c{%undef}
Single-line macros can be removed with the \c{%undef} directive. For
example, the following sequence:
\c %define foo bar
\c %undef foo
\c
\c mov eax, foo
will expand to the instruction \c{mov eax, foo}, since after
\c{%undef} the macro \c{foo} is no longer defined.
Macros that would otherwise be pre-defined can be undefined on the
command-line using the `-u' option on the NASM command line: see
\k{opt-u}.
\S{assign} \i{Preprocessor Variables}: \i\c{%assign}
An alternative way to define single-line macros is by means of the
\c{%assign} command (and its \I{case sensitive}case-insensitive
counterpart \i\c{%iassign}, which differs from \c{%assign} in
exactly the same way that \c{%idefine} differs from \c{%define}).
\c{%assign} is used to define single-line macros which take no
parameters and have a numeric value. This value can be specified in
the form of an expression, and it will be evaluated once, when the
\c{%assign} directive is processed.
Like \c{%define}, macros defined using \c{%assign} can be re-defined
later, so you can do things like
\c %assign i i+1
to increment the numeric value of a macro.
\c{%assign} is useful for controlling the termination of \c{%rep}
preprocessor loops: see \k{rep} for an example of this. Another
use for \c{%assign} is given in \k{16c} and \k{32c}.
The expression passed to \c{%assign} is a \i{critical expression}
(see \k{crit}), and must also evaluate to a pure number (rather than
a relocatable reference such as a code or data address, or anything
involving a register).
See also the \i\c{%eval()} preprocessor function, \k{f_eval}.
\S{defstr} Defining Strings: \I\c{%idefstr}\i\c{%defstr}
\c{%defstr}, and its case-insensitive counterpart \c{%idefstr}, define
or redefine a single-line macro without parameters but converts the
entire right-hand side, after macro expansion, to a quoted string
before definition.
For example:
\c %defstr test TEST
is equivalent to
\c %define test 'TEST'
This can be used, for example, with the \c{%!} construct (see
\k{getenv}):
\c %defstr PATH %!PATH ; The operating system PATH variable
See also the \i\c{%str()} preprocessor function, \k{f_str}.
\S{deftok} Defining Tokens: \I\c{%ideftok}\i\c{%deftok}
\c{%deftok}, and its case-insensitive counterpart \c{%ideftok}, define
or redefine a single-line macro without parameters but converts the
second parameter, after string conversion, to a sequence of tokens.
For example:
\c %deftok test 'TEST'
is equivalent to
\c %define test TEST
See also the \i\c{%tok()} preprocessor function, \k{f_tok}.
\S{defalias} Defining Aliases: \I\c{%idefalias}\i\c{%defalias}
\c{%defalias}, and its case-insensitive counterpart \c{%idefalias}, define an
alias to a macro, i.e. equivalent of a symbolic link.
When used with various macro defining and undefining directives, it
affects the aliased macro. This functionality is intended for being
able to rename macros while retaining the legacy names.
When an alias is defined, but the aliased macro is then undefined, the
aliases can legitimately point to nonexistent macros.
The alias can be undefined using the \c{%undefalias} directive. \e{All}
aliases can be undefined using the \c{%clear defalias} directive. This
includes backwards compatibility aliases defined by NASM itself.
To disable aliases without undefining them, use the \c{%aliases off}
directive.
To check whether an alias is defined, regardless of the existence of
the aliased macro, use \i\c{%ifdefalias}.
For example:
\c %defalias OLD NEW
\c ; OLD and NEW both undefined
\c %define NEW 123
\c ; OLD and NEW both 123
\c %undef OLD
\c ; OLD and NEW both undefined
\c %define OLD 456
\c ; OLD and NEW both 456
\c %undefalias OLD
\c ; OLD undefined, NEW defined to 456
\S{cond-comma} \i{Conditional Comma Operator}: \i\c{%,}
As of version 2.15, NASM has a conditional comma operator \c{%,} that
expands to a comma \e{unless} followed by a null expansion, which
allows suppressing the comma before an empty argument. This is
especially useful with greedy single-line macros.
For example, all the expressions below are valid:
\c %define greedy(a,b,c+) a + 66 %, b * 3 %, c
\c
\c db greedy(1,2) ; db 1 + 66, 2 * 3
\c db greedy(1,2,3) ; db 1 + 66, 2 * 3, 3
\c db greedy(1,2,3,4) ; db 1 + 66, 2 * 3, 3, 4
\c db greedy(1,2,3,4,5) ; db 1 + 66, 2 * 3, 3, 4, 5
\H{strlen} \i{String Manipulation in Macros}
It's often useful to be able to handle strings in macros. NASM
supports a few simple string handling macro operators from which
more complex operations can be constructed.
All the string operators define or redefine a single-line macro to some
value (either a string or a numeric value). When producing a string
value, it may change the style of quoting of the input string or
strings, and possibly use \c{\\}-escapes inside \c{`}-quoted strings.
These directives are also available as \i{preprocessor functions}, see
\k{ppfunc}.
\S{strcat} \i{Concatenating Strings}: \i\c{%strcat}
The \c{%strcat} operator concatenates quoted strings and assign them to
a single-line macro.
For example:
\c %strcat alpha "Alpha: ", '12" screen'
... would assign the value \c{'Alpha: 12" screen'} to \c{alpha}.
Similarly:
\c %strcat beta '"foo"\', "'bar'"
... would assign the value \c{`"foo"\\\\'bar'`} to \c{beta}.
The use of commas to separate strings is permitted but optional.
The corresponding preprocessor function is \c{%strcat()}, see
\k{f_strcat}.
\S{strlen} \i{String Length}: \i\c{%strlen}
The \c{%strlen} operator assigns the length of a string to a macro.
For example:
\c %strlen charcnt 'my string'
In this example, \c{charcnt} would receive the value 9, just as
if an \c{%assign} had been used. In this example, \c{'my string'}
was a literal string but it could also have been a single-line
macro that expands to a string, as in the following example:
\c %define sometext 'my string'
\c %strlen charcnt sometext
As in the first case, this would result in \c{charcnt} being
assigned the value of 9.
The corresponding preprocessor function is \c{%strlen()}, see
\k{f_strlen}.
\S{substr} \i{Extracting Substrings}: \i\c{%substr}
Individual letters or substrings in strings can be extracted using the
\c{%substr} operator. An example of its use is probably more useful
than the description:
\c %substr mychar 'xyzw' 1 ; equivalent to %define mychar 'x'
\c %substr mychar 'xyzw' 2 ; equivalent to %define mychar 'y'
\c %substr mychar 'xyzw' 3 ; equivalent to %define mychar 'z'
\c %substr mychar 'xyzw' 2,2 ; equivalent to %define mychar 'yz'
\c %substr mychar 'xyzw' 2,-1 ; equivalent to %define mychar 'yzw'
\c %substr mychar 'xyzw' 2,-2 ; equivalent to %define mychar 'yz'
As with \c{%strlen} (see \k{strlen}), the first parameter is the
single-line macro to be created and the second is the string. The
third parameter specifies the first character to be selected, and the
optional fourth parameter (preceded by comma) is the length. Note
that the first index is 1, not 0 and the last index is equal to the
value that \c{%strlen} would assign given the same string. Index
values out of range result in an empty string. A negative length
means "until N-1 characters before the end of string", i.e. \c{-1}
means until end of string, \c{-2} until one character before, etc.
The corresponding preprocessor function is \c{%substr()}, see
\k{f_substr}, however please note that the default value for the
length parameter, if omitted, is \c{-1} rather than \c{1} for
\c{%substr()}.
\H{ppfunc} \i{Preprocessor Functions}
Preprocessor functions are, fundamentally, a kind of built-in
single-line macros. They expand to a string depending on its
arguments, and can be used in any context where single-line macro
expansion would be performed. Preprocessor functions were introduced
in NASM 2.16.
Starting with NASM 3.00, the \i\c{%ifdef} directive or \i\c{%isdef()}
function can also test for the availability of preprocessor
functions. They cannot, however, be undefined, aliased or redefined.
\S{f_abs} \i\c{%abs()} Function
The \c{%abs()} function evaluates its first argument as an expression,
and then emits the absolute value. This will always be emitted as a
single token containing a decimal number; no minus sign will be
emitted even if the input value is the maximum negative number.
\S{f_b2hs} \i\c{%b2hs()} Function
The \c{%b2hs()} functin takes a quoted string and an optional
separator string, and expands to a quoted string containing a packed
hexadecimal form of the bytes of the first string, separated by the
separator string if applicable. This is the inverse of the \c{%hs2b()}
function, see \k{f_hs2b}.
\S{f_chr} \i\c{%chr()} Function
The \c{%chr()} function evaluates its arguments as integers, then
creates a quoted string out of these integers (mod 256) as bytes.
\S{f_cond} \i\c{%cond()} Function
The \c{%cond()} function evaluates its first argument as an
expression, then expands to its second argument if true (nonzero), and
the third, if present, if false (zero). This is in effect a specialized
version of the \i\c{%sel()} function; \c{%cond(x,y,z)} is equivalent
to \c{%sel(1+!(x),y,z)}.
\c %define a 1
\c %xdefine astr %cond(a,"true","false") ; %define astr "true"
The argument not selected is never expanded.
\S{f_count} \i\c{%count()} Function
The \c{%count()} function expands to the number of argments passed to
the macro. Note that just as for single-line macros, \c{%count()}
treats an empty argument list as a single empty argument.
\c %xdefine empty %count() ; %define empty 1
\c %xdefine one %count(1) ; %define one 1
\c %xdefine two %count(5,q) ; %define two 2
\c %define list a,b,46
\c %xdefine lc1 %count(list) ; %define lc 1 (just one argument)
\c %xdefine lc2 %count(%[list]) ; %define lc 3 (indirection expands)
\S{f_depend} \i\c\{%depend()} Function
he \c{%depend()} function takes a quoted string as argument, adds it
to the output dependency list generated by the \c{-M} options (see
\k{opt-M}), and evaluates to the unchanged string.
This is the function equivalent of the \c{%depend} directive, see
\k{depend}.
See also the \c{%pathsearch()} function (\k{f_pathsearch}).
\S{f_eval} \i\c{%eval()} Function
The \c{%eval()} function evaluates its argument as a numeric
expression and expands to the result as an integer constant in much
the same way the \i\c{%assign} directive would, see \k{assign}. Unlike
\c{%assign}, \c{%eval()} supports more than one argument; if more than
one argument is specified, it is expanded to a comma-separated list of
values.
\c %assign a 2
\c %assign b 3
\c %defstr what %eval(a+b,a*b) ; equivalent to %define what "5,6"
The expressions passed to \c{%eval()} are \i{critical expressions},
see \k{crit}.
\S{f_find} \i\c{%find()} and \i\c{%findi()} Functions
The \c{%find()} and \c{%findi()} functions take an argument followed
by an optional list. These are turned into quoted strings if
necessary, and then compared as if by the \i\c{%isidn()} or
\i\c{%isidni()} functions, respectively (see \k{ifidn}) \- the
\c{%find()} function compares case sensitively, and \c{%findi()} case
insensitively.
The functions then expand to \c{0} if none of the strings in the list
match the first string, or the position in the list where the first
string was found, where \c{1} is the first argument in the list,
i.e. not including the first argument to the function.
Once a matching argument has been found, no further arguments are expanded.
For example:
\c db %find(a,b,c,d) ; 0
\c db %find(a,b,a,c) ; 2
\c db %find(a) ; 0 (empty list)
\S{f_hex} \i\c{%hex()} Function
Equivalent to \i\c\{%eval()}, except that the results generated are
given as unsigned hexadecimal, with a \c{0x} prefix.
\S{f_hs2b} \i\c\{%hs2b()} Function
The \c{%hs2b()} function takes one or more quoted strings containing
hexadecimal numbers and optional separators (any character that is not
a valid hexadecimal digit is considered a separator) and expands to a
quoted string containing the bytes encoded in the hexadecimal
string. Every pair of hexadecimal digits encodes a byte, but a
separator will always terminate the encoding of a byte. Thus, these
two statements will produce the same output:
\c db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
\c db %hs2b("00010203 4 0506 07 8","9")
This can be used to compactly encode long strings of binary data in
source code.
\S{f_is} \i\c{%is()}\I\c{%isn()} Family Functions
Each \c{%if} conditional assembly family directive (see \k{condasm})
has an equivalent \c{%is()} family function, that expands to \c{1} if
the equivalent \c{%if} directive would process as true, and \c{0} if
the equivalent \c{%if} directive would process as false.
This includes the \c{%ifn} forms of these directives, which become
\c{%isn()}.
\c ; Instead of !%isidn() could have used %isnidn()
\c %if %isdef(foo) && !%isidn(foo,bar)
\c db "foo is defined, but not as 'bar'"
\c %endif
Note that, being functions, the arguments (before expansion) will
always need to have balanced parentheses so that the end of the
argument list can be defined. This means that the syntax of
e.g. \c{%istoken()} and \c{%isidn()} is somewhat stricter than their
corresponding \c{%if} directives; it may be necessary to escape the
argument to the conditional using \c{\{\}}:
\c ; Instead of !%isidn() could have used %isnidn()
\c %if %isdef(foo) && !%isidn({foo,)})
\c db "foo is defined, but not as ')'"
\c %endif
Unlike the C \c{defined()} preprocessor construct, these functions are
valid anywhere in the source code, not just in \c{%if} expressions.
\S{f_map} \i\c{%map()} Function
The \c{%map()} function takes as its first parameter the name of a
single-line macro, followed by up to two optional colon-separated
subparameters:
\b The first subparameter, if present, should be a list of macro
parameters enclosed in parentheses. Note that \c{()} represents a
one-argument list containing an empty parameter; omit the parentheses
to specify no parameters.
\b The second subparameter, if present, represent the number of
group size for additional parameters to the macro (default 1).
Further parameters, if any, are then passed as additional parameters to the
given macro for expansion, in sets given by the specified group size,
and the results turned into a comma-separated list. If no additional
parameters are given, \c{%map()} expands to nothing.
For example:
\c %define alpha(&x) x
\c %define alpha(&x,y) y dup (x)
\c %define alpha(s,&x,y) y dup (x,s)
\c ; 0 fixed + 1 grouped parameters per call, calls alpha(&x)
\c db %map(alpha,foo,bar,baz,quux)
\c ; 0 fixed + 2 grouped parameters per call, calls alpha(&x,y)
\c db %map(alpha::2,foo,bar,baz,quux)
\c ; 1 fixed + 2 grouped parameters per call, calls alpha(s,&x,y)
\c db %map(alpha:("!"):2,foo,bar,baz,quux)
... expands to:
\c db 'foo','bar','baz','quux'
\c db bar dup ('foo'),quux dup ('baz')
\c db bar dup ('foo',"!"),quux dup ('baz',"!")
As a more complex example, a macro that joins quoted strings together
with a user-specified delimiter string:
\c %define join(sep) '' ; handle the case of zero strings
\c %define _join(sep,str) sep,str ; helper macro
\c %define join(sep,s1,sn+) %strcat(s1, %map(_join:(sep) %, sn))
\c
\c db join(':')
\c db join(':','a')
\c db join(':','a','b')
\c db join(':','a','b','c')
\c db join(':','a','b','c','d')
... expands to:
\c db ''
\c db 'a'
\c db 'a:b'
\c db 'a:b:c'
\c db 'a:b:c:d'
\S{f_null} \i\c{%null()} Function
The \c{%null()} function ignores its arguments without expanding them,
and expands to nothing.
\S{f_num} \i\c{%num()} Function
The \c{%num()} function evaluates its arguments as expressions, and
then produces a quoted string encoding the first argument as an
\e{unsigned} 64-bit integer.
The second argument is the desired number of digits (max 255, default
-1).
The third argument is the encoding base (from 2 to 64, default 10); if
the base is given as -2, -8, -10, or -16, then \c{0b}, \c{0q}, \c{0d}
or \c{0x} is prepended, respectively; all other negative values are
disallowed.
Only the first argument is required.
If the number of digits is negative, NASM will add additional digits
if needed; if positive the string is truncated to the number of digits
specified. 0 is treated as -1, except that the input number 0
always generates an empty string (thus, the first digit will never be
zero), even if the base given is negative.
The full 64-symbol set used is, in order:
\c 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_
If a \e{signed} number needs to be converted to a string, use
\c{%abs()}, \c{%cond()}, and \c{%strcat()} to format the signed number
string to your specific output requirements.
\S{f_ord} \i\c{%ord()} Function
The \c{%ord()} function takes a quoted string, and (like
\c{%substr()}, see \k{f_substr}) an optional starting index and
length, and expands to a comma-separated list of integers
corresponding to the bytes of the quoted string. Note that unlike
\c{%substr()} the length argument defaults to \c{1}, so if it is not
given only a single byte value is expanded.
\S{f_pathsearch} \i\c\{%pathsearch()} Function
The \c{%pathsearch()} function takes a quoted string as argument, and
searches for a file with that name in the include path, then expands
to the pathname located, if found, otherwise to the unmodified string.
This is the function equivalent of the \c{%pathsearch} directive, see
\k{pathsearch}.
See also the \c{%depend()} function (\k{f_depend}).
\S{f_realpath} \i\c{%realpath()} Function
The \c{%realpath()} function takes a quoted string as argument, and
attempts to convert it to a fully qualified absolute path name if
supported by the underlying host operating system.
If successful, it expands to a quoted string with the resulting
path name, otherwise to the unmodified string.
The include path is \e{not} searched; to search for the file using the
include path, use the \c{%pathsearch()} function in conjunction with
this function, for example:
\c %define SOMEREALPATH %realpath(%pathsearch("somefile.asm"))
\S{f_sel} \i\c{%sel()} Function