⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 preproc.html

📁 vid写的FASM向导
💻 HTML
📖 第 1 页 / 共 5 页
字号:

<br><br>
You can also overload assembly-time directive:

<blockquote class="code"><pre>
macro use32
<font color=#333399>{</font>
  align <font color=#339933>4</font>
  use32
<font color=#333399>}</font>
macro use16
<font color=#333399>{</font>
  align <font color=#339933>2</font>
  use16
<font color=#333399>}</font>
</pre></blockquote>


<br><br>
<a name="fixed_mac"></a>
<b>5. Macros with fixed number of arguments</b>

<br><br><br>
<a name="one_arg"></a>
<b>5.1. Macro with one argument</b><br>
You can also define macro argument. This argument is represented by some
symbol, which will be replaced in macro body by passed argument.

<blockquote class="code"><pre>
macro <font color=#333399>&lt;</font>name<font color=#333399>&gt;</font> <font color=#333399>&lt;</font>argument<font color=#333399>&gt;</font> <font color=#333399>{</font> <font color=#333399>&lt;</font>body<font color=#333399>&gt;</font> <font color=#333399>}</font>
</pre></blockquote>

<br>
Example:

<blockquote class="code"><pre>
macro add5 where
<font color=#333399>{</font>
  add where<font color=#333399>,</font><font color=#339933>5</font>
<font color=#333399>}</font>
add5 ax
add5 <font color=#333399>[</font>variable<font color=#333399>]</font>
add5 ds
add5 ds<font color=#333399>+</font><font color=#339933>2</font>
</pre></blockquote>

to

<blockquote class="code"><pre>
add ax<font color=#333399>,</font><font color=#339933>5</font>
add <font color=#333399>[</font>variable<font color=#333399>],</font><font color=#339933>5</font>
add ds<font color=#333399>,</font><font color=#339933>5</font> <font color=#777777>;there is no such instruction, but its not task of preprocessor</font>
	 <font color=#777777>;to check it. It will be preprocessed to this form, and will</font>
	 <font color=#777777>;throw error at assembling stage.</font>
add ds<font color=#333399>+</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>5</font> <font color=#777777>;like previous, but this is also syntactically wrong, so it'll</font>
	   <font color=#777777>;throw error at parsing stage.</font>
</pre></blockquote>

(of course there won't be those comments in preprocessed file :)
<br><br><br>

<a name="more_arg"></a>
<b>5.2. Macros with more arguments</b><br>
Macros can have more arguments, separated with comma (<code>,</code>):
<blockquote class="code"><pre>
macro movv where<font color=#333399>,</font>what
<font color=#333399>{</font>
  push what
  pop  where
<font color=#333399>}</font>
movv ax<font color=#333399>,</font>bx
movv ds<font color=#333399>,</font>es
movv <font color=#333399>[</font>var1<font color=#333399>],[</font>var2<font color=#333399>]</font>
</pre></blockquote>

preprocessed to

<blockquote class="code"><pre>
push bx
pop ax
push es
pop ds
push <font color=#333399>[</font>var2<font color=#333399>]</font>
pop <font color=#333399>[</font>var1<font color=#333399>]</font>
</pre></blockquote>

If more arguments have same name, first one is used :).

<br><br>
If you specify less arguments than you listed in macro declaration, then
value of not-specified arguments is blank:

<blockquote class="code"><pre>
macro pupush a1<font color=#333399>,</font>a2<font color=#333399>,</font>a3<font color=#333399>,</font>a4
<font color=#333399>{</font>
  push a1 a2 a3 a4
  pop a4 a3 a2 a1
<font color=#333399>}</font>
pupush eax<font color=#333399>,</font>dword <font color=#333399>[</font><font color=#339933>3</font><font color=#333399>]</font>
</pre></blockquote>

to

<blockquote class="code"><pre>
push eax dword <font color=#333399>[</font><font color=#339933>3</font><font color=#333399>]</font>
pop dword <font color=#333399>[</font><font color=#339933>3</font><font color=#333399>]</font> eax
</pre></blockquote>

<br>
If you want to include comma (<code>,</code>) in macro argument, you must enclose argument in
brackets <code>&lt;</code>,<code>&gt;</code>.

<blockquote class="code"><pre>
macro safe_declare name<font color=#333399>,</font>what
<font color=#333399>{</font>
  if used name
    name what
  end if
<font color=#333399>}</font>
safe_declare var1<font color=#333399>,</font> db <font color=#339933>5</font>
safe_declare array5<font color=#333399>,</font> <font color=#333399>&lt;</font>dd <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>&gt;</font>
safe_declare string<font color=#333399>,</font> <font color=#333399>&lt;</font>db <font color=#bb0000>"hi, i'm stupid string"</font><font color=#333399>,</font><font color=#339933>0</font><font color=#333399>&gt;</font>
</pre></blockquote>

to

<blockquote class="code"><pre>
if used var1
  var1 db <font color=#339933>5</font>
end if
if used array5
  array5 dd <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>
end if
if used string
  string db <font color=#bb0000>"hi, i'm stupid string"</font><font color=#333399>,</font><font color=#339933>0</font>
end if
</pre></blockquote>

<br>
You can use <code>&lt;</code> and <code>&gt;</code> in macro body too, of course:

<blockquote class="code"><pre>
macro a arg <font color=#333399>{</font>db arg<font color=#333399>}</font>
macro b arg1<font color=#333399>,</font>arg2 <font color=#333399>{</font>a <font color=#333399>&lt;</font>arg1<font color=#333399>,</font>arg2<font color=#333399>,</font><font color=#339933>3</font><font color=#333399>&gt;}</font>
b <font color=#333399>&lt;</font><font color=#339933>1</font><font color=#333399>,</font><font color=#339933>1</font><font color=#333399>&gt;,</font><font color=#339933>2</font>
</pre></blockquote>

is preprocessed to
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>1</font><font color=#333399>,</font><font color=#339933>2</font><font color=#333399>,</font><font color=#339933>3</font>
</pre></blockquote>

<br><br>
<a name="local"></a>
<b>5.3. Directive "local"</b><br>

You may want to declare some label inside macro body:
<blockquote class="code"><pre>
macro pushstr string
<font color=#333399>{</font>
  call behind <font color=#777777>;pushes address of string and jumps to behind</font>
  db string<font color=#333399>,</font><font color=#339933>0</font>
  behind<font color=#333399>:</font>
<font color=#333399>}</font>
</pre></blockquote>

but if you use this macro twice, label "behind" will be defined twice and
that will be error. You can solve this by making label "behind" local to
macro. For that preprocessor directive "local" is used.

<blockquote class="code"><pre>
local <font color=#333399>&lt;</font>name<font color=#333399>&gt;</font>
</pre></blockquote>

<br>
It must be inside macro body. It makes all following occurences of &lt;name&gt;
inside macro body local to macro. Thus, if macro is used twice 

<blockquote class="code"><pre>
macro pushstr string
<font color=#333399>{</font>
  local behind
  call behind
  db string<font color=#333399>,</font><font color=#339933>0</font>
  behind<font color=#333399>:</font>
<font color=#333399>}</font>
pushstr <font color=#bb0000>'aaaaa'</font>
pushstr <font color=#bb0000>'bbbbbbbb'</font>
call something
</pre></blockquote>

this won't cause any problems. This is done by replacing <code>behind</code> with
<code>behind?XXXXXXXX</code> where <code>XXXXXXXX</code> is some hexadecimal number
generated by preprocessor. Last example can be for example preprocessed to

<blockquote class="code"><pre>
call behind<font color=#333399>?</font><font color=#339933>00000001</font>
db <font color=#bb0000>'aaaaa'</font><font color=#333399>,</font><font color=#339933>0</font>
behind<font color=#333399>?</font><font color=#339933>00000001</font><font color=#333399>:</font>
call behind<font color=#333399>?</font><font color=#339933>00000002</font>
db <font color=#bb0000>'bbbbbbbb'</font><font color=#333399>,</font><font color=#339933>0</font>
behind<font color=#333399>?</font><font color=#339933>00000002</font><font color=#333399>:</font>
call something
</pre></blockquote>

<br>
Note that you can't directly access names containing <code>?</code>, as it is special
symbol for fasm, for this reason it is used with local names. For example
<code>aa?bb</code> is considered as symbol <code>aa</code>, special symbol
<code>?</code> and symbol <code>bb</code>.<br><br>

If you want more local labels you dont have to use two locals, you can list
them all in one <code>local</code> directive, separated by commas (<code>,</code>):

<blockquote class="code"><pre>
macro pushstr string  <font color=#777777>;does same job as previous macro</font>
<font color=#333399>{</font>
  local addr<font color=#333399>,</font>behind
  push addr
  jmp behind
  addr db string<font color=#333399>,</font><font color=#339933>0</font>
  behind<font color=#333399>:</font>
<font color=#333399>}</font>
</pre></blockquote>

<br>
It is always good to start all macro local label names with two dots (<code>..</code>)
which means they wont change current global label. For example:

<blockquote class="code"><pre>
macro pushstr string
<font color=#333399>{</font>
  local behind
  call behind
  db string<font color=#333399>,</font><font color=#339933>0</font>
  behind<font color=#333399>:</font>
<font color=#333399>}</font>
MyProc<font color=#333399>:</font>
  pushstr <font color=#bb0000>'aaaa'</font>
  .a<font color=#333399>:</font>
</pre></blockquote>

will be preprocessed to
<blockquote class="code"><pre>
MyProc<font color=#333399>:</font>
call behind<font color=#333399>?</font><font color=#339933>00000001</font>
db <font color=#bb0000>'aaaa'</font><font color=#333399>,</font><font color=#339933>0</font>
behind<font color=#333399>?</font><font color=#339933>00000001</font><font color=#333399>:</font>
.a<font color=#333399>:</font>
</pre></blockquote>

and so it will create <code>behind?00000001.a</code> label instead of
<code>MyProc.a</code>. But names that start with two dots (<code>..</code>) do not change
current global label, so in following case <code>MyProc.a</code> would be declared:

<blockquote class="code"><pre>
macro pushstr string
<font color=#333399>{</font>
  local ..behind
  call ..behind
  db string<font color=#333399>,</font><font color=#339933>0</font>
  ..behind<font color=#333399>:</font>
<font color=#333399>}</font>
MyProc<font color=#333399>:</font>
  pushstr <font color=#bb0000>'aaaa'</font>
  .a<font color=#333399>:</font>
</pre></blockquote>

<br><br>
<a name="concat"></a>
<b>5.4. Operator <code>#</code> (symbol concatenation)</b><br>
Other fasm's macrolanguage feature is manipulation with symbols. This is
done with symbol concatenation operator <code>#</code>, which concatenates two
symbols into one, for example <code>a#b</code> will become <code>ab</code>,
or <code>aaa bbb#ccc ddd</code> -> <code>aaa bbbccc ddd</code>. 

This operator can be used only inside macro body, and concatenating symbol
will be done after replacing macro arguments, so you can use this to
create some symbol from macro argument.

<br><br>
Example:
<blockquote class="code"><pre>
macro string name<font color=#333399>,</font> data
<font color=#333399>{</font>
  local ..start
  ..start<font color=#333399>:</font>
  name db data<font color=#333399>,</font><font color=#339933>0</font>
  sizeof.<font color=#333399>#</font>name <font color=#333399>=</font>  <font color=#339933>$</font> <font color=#333399>-</font> ..start
<font color=#333399>}</font>
string s1<font color=#333399>,<font color=#bb0000>'macros are stupid'</font></font>
string s2<font color=#333399>,&lt;<font color=#bb0000>'here i am'</font>,</font><font color=#339933>13</font><font color=#333399>,</font><font color=#339933>10</font><font color=#333399>,<font color=#bb0000>'rock you like a hurricane'</font>&gt;</font>
</pre></blockquote>

to

<blockquote class="code"><pre>
..start<font color=#333399>?</font><font color=#339933>00000001</font><font color=#333399>:</font>
s1 db <font color=#bb0000>'macros are stupid'</font><font color=#333399>,</font><font color=#339933>0</font>
sizeof.s1 <font color=#333399>=</font> <font color=#339933>$</font> <font color=#333399>-</font> ..start<font color=#333399>?</font><font color=#339933>00000001</font>
..start<font color=#333399>?</font><font color=#339933>00000002</font><font color=#333399>:</font>
s2 db <font color=#bb0000>'here i am'</font><font color=#333399>,</font><font color=#339933>13</font><font color=#333399>,</font><font color=#339933>10</font><font color=#333399>,<font color=#bb0000>'rock you like a hurricane'</font>,</font><font color=#339933>0</font>
sizeof.s2 <font color=#333399>=</font> <font color=#339933>$</font> <font color=#333399>-</font> ..start<font color=#333399>?</font><font color=#339933>00000002</font>
</pre></blockquote>

so for all strings defined by macro, symbol <code>"sizeof.&lt;name of string&gt;</code> gets defined.

<br><br>
This operator can also concatenate quoted strings:

<blockquote class="code"><pre>
macro name name
<font color=#333399>{</font>
  db <font color=#bb0000>'name: '</font><font color=#333399>#</font>b<font color=#333399>,</font><font color=#339933>0</font>
<font color=#333399>}</font>
debug <font color=#bb0000>'1'</font>
debug <font color=#bb0000>'barfoo'</font>
</pre></blockquote>

to

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -