?? preproc.html
字號:
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css">
<title>FASM Preprocessor Tutorial by vid</title>
</head>
<body>
<center><b>FASM PREPROCESSOR GUIDE</b></center><br><br>
<b>Table of contents:</b><br>
<ul>
<a href=#about><li>0. About this document</a>
<a href=#what_is><li>1. What is preprocessor</a>
<a href=#basic><li>2. Basic preprocessing</a>
<ul type=square>
<a class="light" href=#comment><li>2.1. Comment ";"</a>
<a class="light" href=#line_br><li>2.2. Line Break "\"</a>
<a class="light" href=#include><li>2.3. Directive "include"</a>
<a class="light" href=#strings><li>2.4. Strings preprocessing</a>
</ul>
<a href=#equates><li>3. Equates</a>
<ul type=square>
<a class="light" href=#equ><li>3.1. Directive "equ"</a>
<a class="light" href=#restore><li>3.2. Directive "restore"</a>
</ul>
<a href=#simple_mac><li>4. Simple macros without aruments</a>
<ul type=square>
<a class="light" href=#simple_def><li>4.1. Simple macro definition</a>
<a class="light" href=#nested><li>4.2. Nested macros</a>
<a class="light" href=#purge><li>4.3. Directive "purge" (macro undefinition)</a>
<a class="light" href=#behave><li>4.4. Macros behavior</a>
</ul>
<a href=#fixed_mac><li>5. Macros with fixed number of arguments</a>
<ul type=square>
<a class="light" href=#one_arg><li>5.1. Macro with one argument</a>
<a class="light" href=#more_arg><li>5.2. Macros with more arguments</a>
<a class="light" href=#local><li>5.3. Directive "local"</a>
<a class="light" href=#concat><li>5.4. Operator "#" (symbol concatenation)</a>
<a class="light" href=#to_string><li>5.5. Operator "`"</a>
</ul>
<a href=#group_mac><li>6. Macros with group argument</a>
<ul type=square>
<a class="light" href=#group_arg><li>6.1. Declaring macro with group argument</a>
<a class="light" href=#common><li>6.2. Directive "common"</a>
<a class="light" href=#forward><li>6.3. Directive "forward"</a>
<a class="light" href=#reverse><li>6.4. Directive "reverse"</a>
<a class="light" href=#combine><li>6.5. Combining group control directives</a>
<a class="light" href=#localgrp><li>6.6. Behavior of directive "local" inside macro with group argument</a>
<a class="light" href=#multiple><li>6.7. Macro with multiple group arguments</a>
</ul>
<a href=#cond><li>7. Preprocessor conditionals</a>
<ul type=square>
<a class="light" href=#eq><li>7.1. Operator "eq"</a>
<a class="light" href=#eqtype><li>7.2. Operator "eqtype"</a>
<a class="light" href=#in><li>7.3. Operator "in"</a>
</ul>
<a href=#struc><li>8. Structures</a>
<a href=#fix><li>9. Fixes</a>
<ul type=square>
<a class="light" href=#fix_expl><li>9.1. Explaination of fixes</a>
<a class="light" href=#fix_nest><li>9.2. Using fixes for nested macro declaration</a>
<a class="light" href=#fix_move><li>9.3. Using fixes for moving part of code</a>
</ul>
</ul>
<a name="about"></a>
<b>0. About this document</b><br>
I wrote this doc because i saw many people are asking many questions on FASM
board because not understanding idea or some particular feature of
preprocessor. (I dont discourage you to ask anything on forum, not
understanding something is not shame and if your question isn't too hard
someone will surely reply it).
<br><br>
Please if you can't understand something from tutorial tell me about it on
<a href="http://board.flatassembler.net/viewtopic.php?t=1178">my tutorial's
thread on FASM board</a> or with <a href="mailto:vid@InMail.sk">email</a> if you like.<br>
<br><br><br>
<a name="what_is"></a>
<b>1. What is preprocessor</b>
<br>
Preprocessor is program (or usualy part of compiler), which modifies your
source code before it is compiled. For example, if you use some piece of
code very often, you can give it some name, and tell preprocessor to replace
name with the piece of code each time.
<br><br>
Another example is, when you want to simulate some instruction which doesn't
exist, you can replace it with set of instructions with same effect
automatically using preprocessor.
<br><br>
Preprocessor scans source and replaces some things with other. But how you
tell it what should it preprocess? For this "preprocessor directives" are
used. We will discuss them now.
<br><br>
Preprocessor doesn't know anything about instructions, compiler directives
etc., it has it's own set of directives and just ignores parts of source not
meant for it.
<br><br><br>
<a name="basic"></a>
<b>2. Basic</b><br>
First I describe basic preprocesing, which is done on file before any other
preprocessing.
<br><br><br>
<a name="comment"></a>
<b>2.1. Comment <code>;</code></b><br>
Like in most assemblers, comments in FASM start with semicolon (<code>;</code>).
Everything up to end of line is ignored and removed from the source.
<br><br>
For example source
<blockquote class="code"><pre>
<font color=#777777>;fill 100h bytes at EDI with zeros</font>
xor eax<font color=#333399>,</font>eax <font color=#777777>;zero value in eax</font>
mov ecx<font color=#333399>,</font><font color=#339933>100h/4</font>
rep stosd
</pre></blockquote>
will after preprocessing become
<blockquote class="code"><pre>
xor eax<font color=#333399>,</font>eax
mov ecx<font color=#333399>,</font><font color=#339933>100h/4</font>
rep stosd
</pre></blockquote>
<br>
<b>NOTE:</b> <code>;</code> can be also comprehended as preprocessor operator
which deletes text behind it up to end of line.<br><br>
<b>NOTE:</b> line that contains only comment won't be deleted, like in my
example. It will become empty line. I skipped empty line because of text
structure. This will be important in next chapter.
<br><br><br>
<a name="line_br"></a>
<b>2.2. Line Break <code>\</code></b><br>
If line seems to be too long for you, you can "break" it with <code>\</code> symbol
(or preprocessor operator). If line ends with <code>\</code> symbol then next line
will be appended to current line.<br><br>
Example:
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font><font color=#333399>,\</font>
<font color=#339933>4</font><font color=#333399>,</font><font color=#339933>5</font><font color=#333399>,</font><font color=#339933>6</font><font color=#333399>,\</font>
<font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
will be preprocessed to
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font><font color=#333399>,</font><font color=#339933>4</font><font color=#333399>,</font><font color=#339933>5</font><font color=#333399>,</font><font color=#339933>6</font><font color=#333399>,</font><font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
<br>
Of course <code>\</code> inside strings or inside comments doesn't concatenate lines,
inside string it is taken as string character (like everything except
ending quote) and comments are deleted up to the end of line without
inspecting what's inside them.
<br><br>
There can't be anything behind <code>\</code> in line, except for blank space and
comment.
<br><br>
In previous chapter i mentioned that line which contains only comment
won't be deleted, it will just become empty line. That means, that code
like this:
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font><font color=#333399>,\</font>
<font color=#777777>; 4,5,6,\ - commented</font>
<font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
will after preprocessing become
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font>
<font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
and so it will cause error. To solve situation like this, you must put
line break before comment:
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font><font color=#333399>,\</font>
<font color=#333399>\<font color=#777777>; 4,5,6 - validly commented</font></font>
<font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
which will become
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font><font color=#333399>,</font><font color=#339933>7</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
like we wanted.
<br><br><br>
<a name="include"></a>
<b>2.3. Directive <code>include</code></b><br>
It's syntax:
<blockquote class="code"><pre>
include <font color=#333399><</font>quoted string <font color=#333399>-</font> file name<font color=#333399>></font>
</pre></blockquote>
It will insert text file into sources. It allows you to break source into
more files. Of course inserted text will be preprocessed too. File path and
name should be quoted (enclosed in <code>'</code>,<code>'</code> or <code>"</code>,<code>"</code>).<br><br>
Examples:
<blockquote class="code"><pre>
include <font color=#bb0000>'file.asm'</font>
include <font color=#bb0000>'HEADERS\data.inc'</font>
include <font color=#bb0000>'..\lib\strings.asm'</font>
include <font color=#bb0000>'C:\config.sys'</font>
</pre></blockquote>
<br>
You can also access environment variables enclosed in <code>%</code>,<code>%</code>:
<blockquote class="code"><pre>
include <font color=#bb0000>'%FASMINC%\win32a.inc'</font>
include <font color=#bb0000>'%SYSTEMROOT%\somefile.inc'</font>
include <font color=#bb0000>'%myproject%\headers\something.inc'</font>
include <font color=#bb0000>'C:\%myprojectdir%\headers\something.inc'</font>
</pre></blockquote>
<br>
<b>TODO:</b> 1.52 paths system (someone could describe it for me...)
<br><br><br>
<a name="strings"></a>
<b>2.4. Strings preprocessing</b><br>
You may have problem to include <code>'</code> in string declared using <code>'</code>s
or <code>"</code> in string declared using <code>"</code>s. For this reason you must place
the character twice into string, in that case it won't end string and begin next as you
may think, but it will include character into string literaly.
<br><br>
For example:
<blockquote class="code"><pre>
db <font color=#bb0000>'It''s okay'</font>
</pre></blockquote>
will generate binary containing string <code>It's okay</code>.
<br><br>
It's same for <code>"</code>.
<br><br>
<a name="equates"></a>
<b>3. Equates</b>
<br><br>
<a name="equ"></a>
<b>3.1. Directive "equ"</b><br>
Simplest preprocessor command. It's syntax
<blockquote class="code"><pre>
<font color=#333399><</font>name1<font color=#333399>></font> equ <font color=#333399><</font>name2<font color=#333399>></font>
</pre></blockquote>
This command tells preprocessor to replace every following <name1> with
<name2>.
<br><br>
Example: source
<blockquote class="code"><pre>
count equ <font color=#339933>10</font> <font color=#777777>;this is preprocessor command</font>
mov ecx<font color=#333399>,</font>count
</pre></blockquote>.
is preprocessed to
<blockquote class="code"><pre>
mov ecx<font color=#333399>,</font><font color=#339933>10</font>
</pre></blockquote>
<br>
Example:
<blockquote class="code"><pre>
mov eax<font color=#333399>,</font>count
count equ <font color=#339933>10</font>
mov ecx<font color=#333399>,</font>count
</pre></blockquote>
is preprocessed to
<blockquote class="code"><pre>
mov eax<font color=#333399>,</font>count
mov ecx<font color=#333399>,</font><font color=#339933>10</font>
</pre></blockquote>
because preprocessor only replaces <code>count</code> behind <code>equ</code> directive.
<br><br>
Even this works:
<blockquote class="code"><pre>
<font color=#339933>10</font> equ <font color=#339933>11</font>
mov ecx<font color=#333399>,</font><font color=#339933>10</font>
</pre></blockquote>
preprocessed to
<blockquote class="code"><pre>
mov ecx<font color=#333399>,</font><font color=#339933>11</font>
</pre></blockquote>
also note that <code>name1</code> can be any symbol. Symbol is just set of
chars, terminated by blank character (space, tab, end of line) or comment
(<code>;</code>) or line-break (<code>\</code>) or operator (including assembly
time operators, not only preprocessor's operators). It can't be operator or
special symbol (like <code>,</code> or <code>}</code> etc.)
<br><br>
<code>name2</code> can be anything, not only one symbol, everything up to end
of line is taken. It can be even empty, then <name1> is replaced by blank
space.<br><br>
Example:
<blockquote class="code"><pre>
<font color=#339933>10</font> equ <font color=#339933>11</font><font color=#333399>,</font><font color=#339933>12</font><font color=#333399>,</font><font color=#339933>13</font>
db <font color=#339933>10</font>
</pre></blockquote>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -