FreeBASIC マニュアルのトップに戻る

FreeBASIC Asm

目次→言語文書→その他→ASM←オリジナル・サイト
目次→教本→プログラマーのための案内ASM←オリジナル・サイト

ASM 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

構造特有の命令を使えるようにするためのコード・ブロック

構文:
Asm
構造に依存する命令
End Asm

または

Asm 構造に依存する命令

記述:
Asm ブロックは、プログラムに特定の機械コード命令を挿入するために、使用されます。
目的は、言語の特徴を使って実現できない操作を実行するため、あるいは、性能敏感なコードのセクションを手で最適化するためです。

現在の FreeBASIC コンパイラは、現在、インテルの 80x86-ベースのマシンのためのコードを、生成するだけです。
しかし、将来、同じ命令セットをサポートしないプラットホームに、コンパイラを移植するかもしれません。
したがって、Asm ブロックは、必要最小限で使用すべきです。そして、できれば、FreeBASIC だけでの代替手段を活用すべきです。

関数の戻り値は、下の例に示すように、角括弧の中で Function キーワードを使って、設定します。

Asm ブロックのコメントは、通常の FreeBASIC の コメント と、同じ構文です。
FreeBASIC のように、" ' " コメント とします。通常の ASM のような、" ; " ではありません。

x86 特定:

構文
インライン・アセンブラの構文は、インテル構文の簡易形式です。
インテル構文は、MASM、TASM、NASM、YASM、FASM などの x86 アセンブラの大部分で、使われます。
一般に、命令の行き先は、最初に、置かれます。その後ろに、ソースを続けます。
プログラムで定義された変数と関数は、Asm ブロックで、参照をつけられます。
FreeBASIC で使われるアセンブラは、GAS で、.intel_syntax noprefix 命令型を使います。そして、ASM ブロックは、スタック・フレーム参照のための局所変数名の代替以外は、変更せずに渡されます。コメントは、取り除かれます。

命令構文は、FASM 使用と、ほとんど同じです。1つの重要な違いは、GAS は、"ptr"という言葉を、サイズ設定の後ろに付ける必要がある点です。

' "n" と仮定するのは、FB の、グローバルまたはローカルの ULONG 変数です
mov  eax, [n]        ' OK: サイズは eax から明らかです。
inc  [n]             ' Not OK: サイズは与えられていません。
inc  dword [n]       ' Not OK: サイズは与えられましたが、GAS でまだ受け取られていません。
inc  dword Ptr [n]   ' OK: "ptr" は、ここで GAS によって必要です。
 

レジスタを保存する
ASM ブロックが開かれるとき、レジスタの ebx, esi, edi は、スタックに押されます。ブロックが閉じられるとき、これらのレジスタは、スタックから元に戻ります。
これは、これらのレジスタが、x86 CPU を使用する、大部分、またはすべての OS で、保存される必要があるからです。
したがって、これらのレジスタを、自分で明示的に保存しなくても、使用できます。
espebp は、通常、局所変数を記述するのに使われるので、espebp を変えるべきではありません。
注意: Naked 手続き内では、このようなレジスタの保存は行われません。

レジスタ名
x86 構造のためのレジスタの名前は、下の通り Asm ブロックに書かれています:
  • 4バイトの整数レジスタ: eax, ebx, ecx, edx, ebp, esp, edi, esi
  • 2バイトの整数レジスタ: ax, bx, cx, dx, bp, sp, di, si (4-byte e- レジスタの下位ワード)
  • 1バイトの整数レジスタ: al, ah, bl, bh, cl, ch, dl, dh (2-byte -x レジスタの、下位と上位のバイト)
  • 浮動小数点レジスタ: st(0), st(1), st(2), st(3), st(4), st(5), st(6), st(7)
  • MMX レジスタ (浮動小数点レジスタの別名):
    mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7
  • SSE レジスタ: xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7

命令セット
以下の外部リンクを参照ください:

危険な指示
FreeBASIC コンパイラは、通常、非特権ユーザレベルで実行する x86 のために、32ビットのプロテクト・モード・コードを生成することに、注意してください。
したがって、特権があって敏感な命令は、アッセンブルできても、正しく動かないかもしれません。あるいは、実行時に、「一般保護違反」、「違法命令」、SIGILL エラーを引き起こすかもしれません。
下は、インテルPentium 4 と Xeon で、特権があって敏感な命令です:
  • cli *1
  • clts
  • hlt
  • in *1
  • ins *1
  • int *1
  • into *1
  • invd
  • invlpg
  • lgdt
  • lidt
  • lldt
  • lmsw
  • ltr
  • mov to/from CRn, DRn, TRn
  • out *1
  • outs *1
  • rdmsr
  • rdpmc *2
  • rdtsc *2
  • sti *1
  • str
  • wbinvd
  • wrmsr
  • すべての SSE2 と、より高い命令 *2
*1:IOPL に敏感で、DOS でうまく行きます。
*2:CR4 で許可ビットに敏感です。下を参照下さい。

特権命令は、DOSで、Ring 0 DPMI カーネルで動くとき、「正しく」働くでしょう。これは、CWSDPMIか、WDOSXか、D3Xの(非デフォルト) Ring 0 バージョンと似ています。それにもかかわらず、DPMIコードから実行される場合、特権命令の大部分は、実際に役に立たなくて、危険です。
RDTSC (タイム・スタンプ・カウンターを読む)は、大部分、あるいは、すべての OS によって許容されて、見ることができます。

しかし、RDTSC の有用性は、マルチコアで、休止(ハイバーネイト)する CPU の出現によって、減少しました。
SSE2 と、より高い命令は、通常、CPU初期化後、「デフォルトで」障害があります。Windows と Linux は、それらを可能にします。DOSでは、それは、DPMI ホストの仕事です:
HDPMI32 は、それらを可能にして、CWSDPMIは、そうしないでしょう。
INT 命令は、DOSバージョン/目標だけで使用可能です。INT 命令は、リアルモードの DOS とわずかに異なった動きをする点に、注意して下さい。FaqDOS を参照下さい。

セグメント・レジスタ(cs, ds, es, fs, gs)を、Asm ブロックから変えるべきではありません。DOS ポートのあるケースを除いて(これらが、リアルモード DOS と同じように働いていないことに、注意してください。FaqDOS を参照下さい。)。
オペレーティング・システムや、DPMI ホストは、メモリ管理に責任があります。
プロテクト・モードにおけるセグメント(セレクタ)の意味は、リアルモード・メモリ・アドレッシングと、極めて異なっています。

これらの「危険な」命令は、不十分な特権で走らせた場合でも、必ず「目に見える」クラッシュを起こすとは限らないことに注意して下さい。 - OS か DPMI ホストは、それらを、機能的に(HDPMI32の下で働く、いくらかの CRx から読む)か、ダミー(何も起こらないで、命令は黙って渡されます。NOP のように)として、「模倣する」と決めることができます。

例:
'' これは x86構造 のための例です。
Function AddFive(ByVal num As Long) As Long
    Asm
        mov eax, [num]
        add eax, 5
        mov [Function], eax
    End Asm
End Function

Dim i As Long = 4

Print "4 + 5 ="; AddFive(i)
Sleep


4 + 5 = 9


FreeBASIC の Assembler は、AS / GAS、GCC のアセンブラで、外部プログラムです。
若干の癖が、あてはまります:

方言差:

QBからの違い:

参照:
目次に戻る
プログラマーのための案内にに戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2021-05-19 15:39:41
日本語翻訳:WATANABE Makoto、原文著作者:SysOp

ホームページのトップに戻る

表示-非営利-継承