Gforth に含まれる 386 アセンブラーは Bernd Paysan によって書かれ、 GPL の下で入手可能で、 元々は bigFORTH の一部でした。
Gforth に含まれる 386 逆アセンブラーは Andrew McKewan によって作成され、 パブリック・ドメインです。
逆アセンブラーは、 Intel のようなプレフィックス構文(Intel-like prefix syntax)でコードを表示します。
アセンブラーは、 AT&T スタイルのパラメーター順序(つまり、宛先が最後;destination last)で後置構文(postfix syntax)を使用します。
アセンブラーには、 Athlon のすべての命令、 つまり 486 コア命令や、Pentium および PPro
拡張機能や、浮動小数点、MMX、3Dnow! が含まれていますが、 ISSE は含まれていません。 これは、16 ビットおよび 32
ビットの統合アセンブラーです。デフォルトは 32 ビットですが、 .86
で 16 ビットに切り替え、.386
で 32
ビットに戻すことができます。
異なる操作サイズを切り替えるためのプレフィックスがいくつかあります。 バイト・アクセスの場合は .b
、 ワード・アクセスの場合は
.w
、 ダブルワード・アクセスの場合は .d
です。 アドレッシング・モードは、 16 ビットアドレスの場合は
.wa
、32 ビットアドレスの場合は .da
で切り替えることができます。 (AL
など、
)バイト・レジスター名のプレフィックスは必要ありません 。
浮動小数点演算の場合、 プレフィックスは .fs
(IEEE single)、.fl
(IEEE
double)、.fx
(extended)、.fw
(word)、 .fd
(double-word)、
.fq
(quad-word)。 デフォルトは .fx
であるため、 Gforth FP 値を扱うときは
.fl
を明示的に指定する必要があります。
MMX オペコードにはサイズのプレフィックスはなく、 Intel アセンブラーと同じように記述されます。 メモリー間での移動の代わりに、 PLDQ/PLDD と PSTQ/PSTD があります。
レジスターには「e」接頭辞がありません。 32 ビット モードでも、 eax は ax と呼ばれます。 即値は、#
を接尾辞として付けることによって示されます(例: 3 #
)。 以下に、 さまざまな構文でのアドレス指定モードの例をいくつか示します:
Gforth Intel (NASM) AT&T (gas) Name .w ax ax %ax register (16 bit) ax eax %eax register (32 bit) 3 # offset 3 $3 immediate 1000 #) byte ptr 1000 1000 displacement bx ) [ebx] (%ebx) base 100 di d) 100[edi] 100(%edi) base+displacement 20 ax *4 i#) 20[eax*4] 20(,%eax,4) (index*scale)+displacement di ax *4 i) [edi][eax*4] (%edi,%eax,4) base+(index*scale) 4 bx cx di) 4[ebx][ecx] 4(%ebx,%ecx) base+index+displacement 12 sp ax *2 di) 12[esp][eax*2] 12(%esp,%eax,2) base+(index*scale)+displacement
D)
と DI)
の代わりに L)
と LI)
を使用して、32 ビット
displacement フィールドを強制できます(後のパッチ適用に役立ちます)。
いくつかの命令の例は以下のとおりです:
ax bx mov \ move ebx,eax 3 # ax mov \ mov eax,3 100 di d) ax mov \ mov eax,100[edi] 4 bx cx di) ax mov \ mov eax,4[ebx][ecx] .w ax bx mov \ mov bx,ax
バイナリ命令では以下の形式がサポートされています:
<reg> <reg> <inst> <n> # <reg> <inst> <mem> <reg> <inst> <reg> <mem> <inst> <n> # <mem> <inst>
シフト/ローテート の構文は以下のとおりです:
<reg/mem> 1 # shl \ shortens to shift without immediate <reg/mem> 4 # shl <reg/mem> cl shl
バイト・バージョンを取得するには、 (movs
などの)文字列命令(string instructions)の前に .b
を付けます。
制御構造ワードの IF
や UNTIL
などの前に、 次の条件のいずれかを指定する必要があります: vs vc
u< u>= 0= 0<> u<= u> 0< 0>= ps pc < >= <= >
(注意: code
ワードなど、 検索パス内で
assembler
が forth
の前にある場合、 これらのワードのほとんどは Forth
ワードの一部を隠してしまう事に注意してください)。 現在、 制御構造ワードは 1 つのスタック項目を使用しているため、 それらをいじるには
cs-roll
の代わりに roll
を使用する必要があります(swap
などを使用することもできます)。
Intel ABI (Linux で使用)に基づいて、abi-code
ワードは 4 sp d)
でデータ・スタック・ポインターを見つけ、 8 sp d)
で FP スタック・ポインターのアドレスを見つけることができます;
データ・スタック・ポインターは ax
で返されます。 Ax
や cx
や dx
は呼び出し元で保存されるため、 ワード内に値を保存する必要はありません。 ret
を使用してワードから戻ることができます。
パラメーターは呼び出し元によってクリーンアップされます。
386 の abi-code
ワードの例については、 Definitions in assembly language