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

📄 preproc.html

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

to
<blockquote class="code"><pre>
l_1<font color=#333399>:</font>
l_3<font color=#333399>:</font>
l_5<font color=#333399>:</font>
l_2<font color=#333399>:</font>
l_4<font color=#333399>:</font>
l_6<font color=#333399>:</font>
</pre></blockquote>

<br>
Another example:
<blockquote class="code"><pre>
macro ErrorList <font color=#333399>[</font>name<font color=#333399>,</font>value<font color=#333399>]</font>
<font color=#333399>{</font>
  forward
    ERROR_<font color=#333399>#</font>name <font color=#333399>=</font> value
<font color=#333399>}</font>
ErrorList <font color=#333399>\</font>
 NONE<font color=#333399>,</font><font color=#339933>0</font><font color=#333399>,\</font>
 OUTOFMEMORY<font color=#333399>,</font><font color=#339933>10</font><font color=#333399>,\</font>
 INTERNAL<font color=#333399>,</font><font color=#339933>20</font>
</pre></blockquote>

to
<blockquote class="code"><pre>
ERROR_NONE <font color=#333399>=</font> <font color=#339933>0</font>
ERROR_OUTOFMEMORY <font color=#333399>=</font> <font color=#339933>10</font>
ERROR_INTERNAL <font color=#333399>=</font> <font color=#339933>20</font>
</pre></blockquote>

<br>
Of course there can be more than 2 group arguments:

<blockquote class="code"><pre>
macro a <font color=#333399>[</font>g1<font color=#333399>,</font>g2<font color=#333399>,</font>g3<font color=#333399>]</font>
<font color=#333399>{</font>
  common
    db g1
    db g2
    db g3
<font color=#333399>}</font>
a <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><font color=#333399>,</font><font color=#339933>10</font><font color=#333399>,</font><font color=#339933>11</font>
</pre></blockquote>

to
<blockquote class="code"><pre>
db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>4</font><font color=#333399>,</font><font color=#339933>7</font><font color=#333399>,</font><font color=#339933>10</font>
db <font color=#339933>2</font><font color=#333399>,</font><font color=#339933>5</font><font color=#333399>,</font><font color=#339933>8</font><font color=#333399>,</font><font color=#339933>11</font>
db <font color=#339933>3</font><font color=#333399>,</font><font color=#339933>6</font><font color=#333399>,</font><font color=#339933>9</font>
</pre></blockquote>
<br><br><br>

<a name="cond"></a>
<b>7. Preprocessor conditionals</b><br>
In fact, there is no preprocessor conditional syntax in FASM (too bad). But
assembly directive <code>if</code> can be used in conjuction with preprocessor to
acheive same results as with preprocessor conditionals (but this way it
wastes more time and memory).<br><br>

As you know, <code>if</code> is assembly-time statement. That means statement is
checked after preprocessing, and that allows some special conditional
operators to work.<br><br>

I won't describe it's assembly-time behavior (conditional operators like
<code>&</code>, <code>|</code> etc), read FASM's docs for this. I will describe
only operators that are used with preprocessor here.
<br><br><br>

<a name="eq"></a>
<b>7.1. Operator <code>eq</code></b><br>
Simplest is <code>eq</code>. It just compares two symbols if they are same. Value of
<code>abcd eq abcd</code> is true, value of <code>abcd eq 1</code> is false etc. It is useful to
compare symbol that will be preprocessed, like:

<blockquote class="code"><pre>
STRINGS equ ASCII
if STRINGS eq ASCII
  db <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else if STRINGS eq UNICODE
  du <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else
  display <font color=#bb0000>'unknown string type'</font>
end if
</pre></blockquote>

after preprocessing it will be

<blockquote class="code"><pre>
if ASCII eq ASCII
  db <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else if ASCII eq UNICODE
  du <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else
  display <font color=#bb0000>'unknown string type'</font>
end if
</pre></blockquote>

so first condition (<code>ASCII eq ASCII</code>) is true, so only <code>db 'Oh yeah',0</code> will
get assembled.

<br><br>
Other case:

<blockquote class="code"><pre>
STRINGS equ UNICODE	  <font color=#777777>;only difference here, UNICODE instead of ASCII</font>
if STRINGS eq ASCII
  db <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else if STRINGS eq UNICODE
  du <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else
  display <font color=#bb0000>'unknown string type'</font>
end if
</pre></blockquote>

after preprocessing it will be

<blockquote class="code"><pre>
if UNICODE eq ASCII
  db <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else if UNICODE eq UNICODE
  du <font color=#bb0000>'Oh yeah'</font><font color=#333399>,</font><font color=#339933>0</font>
else
  display <font color=#bb0000>'unknown string type'</font>
end if
</pre></blockquote>

now first condition (<code>UNICODE eq ASCII</code>) will be false, second one (<code>UNICODE eq
UNICODE</code>) will be true and so <code>du 'Oh yeah',0</code> will get assembled.<br><br>

Better usage of this is checking macro arguments, like
<blockquote class="code"><pre>
macro item type<font color=#333399>,</font>value
<font color=#333399>{</font>
  if type eq BYTE
    db value
  else if type eq WORD
    dw value
  else if type eq DWORD
    dd value
  else if type eq STRING
    db value<font color=#333399>,</font><font color=#339933>0</font>
  end if
<font color=#333399>}</font>
item BYTE<font color=#333399>,</font><font color=#339933>1</font>
item STRING<font color=#333399>,<font color=#bb0000>'aaaaaa'</font></font>
</pre></blockquote>

to
<blockquote class="code"><pre>
if BYTE eq BYTE
  db <font color=#339933>1</font>
else if BYTE eq WORD
  dw <font color=#339933>1</font>
else if BYTE eq DWORD
  dd <font color=#339933>1</font>
else if BYTE eq STRING
  db <font color=#339933>1</font><font color=#333399>,</font><font color=#339933>0</font>
end if
if STRING eq BYTE
  db <font color=#bb0000>'aaaaaa'</font>
else if STRING eq WORD
  dw <font color=#bb0000>'aaaaaa'</font>
else if STRING eq DWORD
  dd <font color=#bb0000>'aaaaaa'</font>
else if STRING eq STRING
  db <font color=#bb0000>'aaaaaa'</font><font color=#333399>,</font><font color=#339933>0</font>
end if
</pre></blockquote>
so only these two commands will get assembled:
<blockquote class="code"><pre>
db <font color=#339933>1</font>
db <font color=#bb0000>'aaaaaa'</font><font color=#333399>,</font><font color=#339933>0</font>
</pre></blockquote>

<br>
<code>eq</code> (like all other preprocessor operators) can also work with blank
arguments. That means, for example, that <code>if eq</code> is true, and
<code>if 5 eq </code> is
false etc.

Example macro:
<blockquote class="code"><pre>
macro mov dest<font color=#333399>,</font>src<font color=#333399>,</font>src2
<font color=#333399>{</font>
  if src2 eq
    mov dest<font color=#333399>,</font>src
  else
    mov dest<font color=#333399>,</font>src
    mov src<font color=#333399>,</font>src2
  end if
<font color=#333399>}</font>
</pre></blockquote>

<br><br>
<a name="eqtype"></a>
<b>7.2. Operator <code>eqtype</code></b><br>
Other operator is <code>eqtype</code>. It compares whether symbols are of same type.
Types are:
<li>individual quoted strings (those not being a part of numerical expression)
<li>floating point numbers
<li>any numerical expression (note that any unknown word will be treated as
      label, so it also will be seen as such expression),
<li>addresses - the numerical expressions in square brackets (with size
      operators and segment prefixes)
<li>instruction mnemonics
<li>registers
<li>size operators
<li>near/far operators,
<li>use16/use32 operators
<li>blank space
<br><br>
Example of macro which allows SHL instruction with memory variable as count,
like <code>shl ax,[myvar]</code>
<blockquote class="code"><pre>
macro shl dest<font color=#333399>,</font>count
<font color=#333399>{</font>
  if count eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>	<font color=#777777>;if count is memory variable</font>
    push cx
    mov cl<font color=#333399>,</font>count
    shl dest<font color=#333399>,</font>cl
    pop cx
  else			<font color=#777777>;if count is of another type</font>
    shl dest<font color=#333399>,</font>count	<font color=#777777>;just use original shl</font>
  end if
<font color=#333399>}</font>
shl ax<font color=#333399>,</font><font color=#339933>5</font>
byte_variable db <font color=#339933>5</font>
shl ax<font color=#333399>,[</font>byte_variable<font color=#333399>]</font>
</pre></blockquote>

to
<blockquote class="code"><pre>
if <font color=#339933>5</font> eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>
  push cx
  mov cl<font color=#333399>,</font><font color=#339933>5</font>
  shl ax<font color=#333399>,</font>cl
  pop cx
else
  shl ax<font color=#333399>,</font><font color=#339933>5</font>
end if
byte_variable db <font color=#339933>5</font>
if <font color=#333399>[</font>byte_variable<font color=#333399>]</font> eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>
  push cx
  mov cl<font color=#333399>,[</font>byte_variable<font color=#333399>]</font>
  shl ax<font color=#333399>,</font>cl
  pop cx
else
  shl ax<font color=#333399>,[</font>byte_variable<font color=#333399>]</font>
end if
</pre></blockquote>

and so, due to conditions, it will be assembled to
<blockquote class="code"><pre>
shl ax<font color=#333399>,</font><font color=#339933>5</font>
byte_variable db <font color=#339933>5</font>
push cx
mov cl<font color=#333399>,[</font>byte variable<font color=#333399>]</font>
shl ax<font color=#333399>,</font>cl
pop cx
</pre></blockquote>
Note that <code>shl ax,byte [variable]</code> wouldn't work with this macro, because
condition <code>byte [variable] eqtype [0]</code> isn't true, read further.

<br><br>
<code>eqtype</code> operands doesn't work only with two operands. It just compares
whether types of operands on left side and same to type of operands on right
side of <code>eqtype</code>. For example <code>if eax 4 eqtype ebx name</code>
is true (<code>name</code> is label and thus it is number too).<br><br>

Example of extending <code>mov</code> intruction so it allows moving between memory
variables:

<blockquote class="code"><pre>
macro mov dest<font color=#333399>,</font>src
<font color=#333399>{</font>
  if dest src eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font> <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>
    push src
    pop dest
  else
    mov dest<font color=#333399>,</font>src
  end if
<font color=#333399>}</font>
mov <font color=#333399>[</font>var1<font color=#333399>],</font><font color=#339933>5</font>
mov <font color=#333399>[</font>var1<font color=#333399>],[</font>var2<font color=#333399>]</font>
</pre></blockquote>

will be preprocessed to
<blockquote class="code"><pre>
if <font color=#333399>[</font>var1<font color=#333399>]</font> <font color=#339933>5</font> eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font> <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>  <font color=#777777>;false</font>
  push <font color=#339933>5</font>
  pop <font color=#333399>[</font>var1<font color=#333399>]</font>
else
  mov <font color=#333399>[</font>var1<font color=#333399>],</font><font color=#339933>5</font>
end if
if <font color=#333399>[</font>var1<font color=#333399>]</font> <font color=#333399>[</font>var2<font color=#333399>]</font> eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font> <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>]</font>  <font color=#777777>;true</font>
  push <font color=#333399>[</font>var2<font color=#333399>]</font>
  pop <font color=#333399>[</font>var1<font color=#333399>]</font>
else
  mov <font color=#333399>[</font>var1<font color=#333399>],[</font>var2<font color=#333399>]</font>
end if
</pre></blockquote>

and assembled to
<blockquote class="code"><pre>
mov <font color=#333399>[</font>var1<font color=#333399>],</font><font color=#339933>5</font>
push <font color=#333399>[</font>var2<font color=#333399>]</font>
pop <font color=#333399>[</font>var1<font color=#333399>]</font>
</pre></blockquote>
Anyway, better (more readable) way to write such macro is to use <code>&</code>
operator (not described in this document, see FASM documentation), like:

<blockquote class="code"><pre>
macro mov dest<font color=#333399>,</font>src
<font color=#333399>{</font>
  if <font color=#333399>(</font>dest eqtype <font color=#333399>[</font><font color=#339933>0</font><font color=#333399>])</font> & <font color=#333399>(</font>src eqtype <font color=#333399>[</font><font color=#33993

⌨️ 快捷键说明

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