式
式は、NASM 側で計算され、計算結果の値に置き換えられます。
値は 64bit 整数として評価され、その後、適切なサイズに調整されます (浮動小数点での計算は行えません)。
bool 値は、真 (true) は 1、偽 (false) は 0 となります。
NASM では、それが式であることを明確にするために、常に () で囲むと、わかりやすくなります。
値は 64bit 整数として評価され、その後、適切なサイズに調整されます (浮動小数点での計算は行えません)。
bool 値は、真 (true) は 1、偽 (false) は 0 となります。
NASM では、それが式であることを明確にするために、常に () で囲むと、わかりやすくなります。
mov eax, (100+10*5) ; mov eax, 150 mov eax, ((1<<8) - 100) ; mov eax, 156 (256 - 100)
演算子一覧
優先度の低い順に並んでいます。
( ) を使うことができます。
( ) を使うことができます。
?<..>:<..> | 三項演算子。 ※シンボル名の ? と区別するため、? の前後には、空白を入れることが推奨されます。 |
---|---|
|| | 比較 OR |
^^ | 比較 XOR |
&& | 比較 AND |
= == | 等しい |
!= <> | 等しくない |
< <= > >= | 比較 |
<=> | 等しい場合は 0。< の場合は -1。> の場合は 1 |
| | 論理演算 OR |
^ | 論理演算 XOR |
& | 論理演算 AND |
<< <<< >> >>> | ビットシフト。 <<, >> は符号なし。 <<<, >>> は符号あり |
+ - | 加算、減算 |
* / // % %% | 乗算、除算、剰余。 / は符号なし、// は符号あり。 % は符号なし、%% は符号あり。 ※% は NASM ではよく使用されるため、前後に空白を入れること。 |
-(N) | 符号変換 |
+(N) | 結果として何もしない |
~(N) | ビット反転 |
! | 否定 |
$, $$
$ と $$ は、式において使用できる、特殊なトークンです。
$ は、現在のセクションの位置を示します。
$$ は、現在のセクションの先頭位置を示します。
($ - $$) として式を記述すると、現在のセクションの先頭からのオフセット位置を、値として指定することができます。
この場合、戻り値は 7 になります。
data のラベル位置の ($ - $$) の計算の結果は、.text セクション先頭から data までのオフセット位置になります。
先頭に 7 byte の命令コードがあるため、data の位置は 7 となります。
$ は、現在のセクションの位置を示します。
$$ は、現在のセクションの先頭位置を示します。
($ - $$) として式を記述すると、現在のセクションの先頭からのオフセット位置を、値として指定することができます。
global testfunc section .text testfunc: mov eax, [rel data] ; 8b 05 01 00 00 00 ret ; c3 data: dd ($ - $$)
この場合、戻り値は 7 になります。
data のラベル位置の ($ - $$) の計算の結果は、.text セクション先頭から data までのオフセット位置になります。
先頭に 7 byte の命令コードがあるため、data の位置は 7 となります。
アドレス指定について
mov eax, [rbx] mov eax, [rip+100] mov eax, [rsi+10+rax*2]
オペランドで、メモリ位置のアドレスを指定する際の、[ ] 内の式は、NASM の式ではなく、CPU 命令の一部です。
オペランドでアドレスを指定する場合、「base + offset + index * scale」の形式で指定することができます。
(base, offset, index * scale は、それぞれ指定しなくても良い)
base と index は、任意のレジスタ (2つは同じサイズであること)。
offset は、符号付き 8bit、または符号付き 32bit の即値。
scale は、1, 2, 4, 8 のいずれか。