Next: , Previous: , Up: Assembler and Code Words   [Contents][Index]


6.29.4 386 Assembler

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 を付けます。

制御構造ワードの IFUNTIL などの前に、 次の条件のいずれかを指定する必要があります: vs vc u< u>= 0= 0<> u<= u> 0< 0>= ps pc < >= <= > (注意: code ワードなど、 検索パス内で assemblerforth の前にある場合、 これらのワードのほとんどは Forth ワードの一部を隠してしまう事に注意してください)。 現在、 制御構造ワードは 1 つのスタック項目を使用しているため、 それらをいじるには cs-roll の代わりに roll を使用する必要があります(swap などを使用することもできます)。

Intel ABI (Linux で使用)に基づいて、abi-code ワードは 4 sp d) でデータ・スタック・ポインターを見つけ、 8 sp d) で FP スタック・ポインターのアドレスを見つけることができます; データ・スタック・ポインタは ax で返されます。 Axcxdx は呼び出し元で保存されるため、 ワード内に値を保存する必要はありません。 ret を使用してワードから戻ることができます。 パラメータは呼び出し元によってクリーンアップされます。

386 の abi-code ワードの例については、 Definitions in assembly language


Next: AMD64 (x86_64) Assembler, Previous: Common Disassembler, Up: Assembler and Code Words   [Contents][Index]