4

ベース インデックス式を使用して 16 ビット リアル モードでメモリを操作しようとすると、コンパイル エラーが発生します。

movw    $0xd000, -2(%sp)
movw    $0, -4(%sp)
movw    $1, -6(%sp)

でコンパイル

gcc -c -Wa,--32 $(DIR_BS_SRC)/mbr.S -o $(DIR_BS_SRC)/mbr.o
ld -nostdlib --oformat binary --Ttext 0x7c00 $(DIR_BS_SRC)/mbr.o -o $(DIR_B$

次のエラーが発生します。

bootsector/src/mbr.S:20: Error: `-2(%sp)' is not a valid base/index expression
bootsector/src/mbr.S:21: Error: `-4(%sp)' is not a valid base/index expression
bootsector/src/mbr.S:22: Error: `-6(%sp)' is not a valid base/index expression

16 ビット リアル モードでも、これは有効な構文だと思いましたか?

4

2 に答える 2

5

16 ビット アドレッシング モードでは、SP をベース レジスタまたはインデックス レジスタとして使用することはできません。32 ビット アドレッシング モードとは異なり、許可されるモードは、使用できるレジスタに関して非常に制限されています。

次のモードに制限されています(%bx)(%bp)(%si)(%di)(%bx,%si)、および。これらはすべて、オプションの 8 ビットまたは 16 ビットの変位を持つことができます。(厳密に言えば、変位が必要ですが、アセンブラは変位を指定しない場合は 0 を使用します) BP をベースとして使用するアドレッシング モードも、データ セグメント (DS) ではなくスタック セグメント (SS) にデフォルト設定されることに注意してください。 .(%bx,%di)(%bp,%si)(%bp,%di)(%bp)

あなたの場合の部分的な解決策は、代わりに BP をベースとして使用し、最初に SP から値をコピーすることです。または、ESP をベースとして使用して、許可されている場合は 32 ビット アドレス指定を使用することもできます。

ただし、あなたが試みていることにはまだ根本的な問題があります。スタック ポインターの下のアドレスに値を格納しようとしています。これらのアドレスは、将来のプッシュと呼び出しによって上書きされ、予期せず割り込みによって上書きされます。割り込みを無効にし、スタックを使用する命令を使用していない場合でも、使用しているメモリにスタック上のスペースを適切に割り当てることをお勧めします。

例えば:

movw    %sp, %bp
subw    $6, %sp
movw    $0xd000, -2(%bp)
movw    $0, -4(%bp)
movw    $1, -6(%bp)
于 2015-12-17T22:57:43.937 に答える
0

16 ビットでは、アドレッシング モード用のレジスタの選択肢が非常に限られています。https://stackoverflow.com/tags/x86/info /メモリ ロケーションの内容の参照を参照してください。(x86 アドレッシング モード) .

の任意のサブセット[reg1 + reg2 + displacement]が有効です。ここで、 はreg1BX または BP、および/またはreg2SI または DI です。

16 ビットは SIB バイトを使用できないため、すべての 1 および 2 reg アドレッシング モードを mod/rm バイトにエンコードする必要があります。これではあまり余裕がありません。

于 2015-12-17T22:57:15.707 に答える