1

私の16ビットプログラムでは、GASは次のような指示に呆然としています。

movw %ip, %dx

セグメントレジスタの移動は正常に機能するため、これは奇妙だと思います。たとえば、次のようになります。

movw %ss, %ax

完全なエラーメッセージは次のとおりです。

エラー:不正なレジスタ名 `%ip '

そして私のバージョン文字列は次のとおりです。

GNUアセンブラ(GNU Binutils)2.22

4

1 に答える 1

5

残念ながら、すべてのレジスタに簡単にアクセスできるわけではありません。いくつかの制限があります。

x86 ウィキブックの GPR セクションにリストされているように、x86 には 8 つの汎用レジスタ (GPR) があります: AX、CX、DX、BX、SP、BP、SI、DI であり、多くのコマンドで使用できます。これらは 3 ビットとしてエンコードされます。また、命令エンコーディングには、EIP (IP) や EFLAGS (FLAGS) などの特殊レジスタをエンコードするためのスペースがありません。

ウィキブックを下にスクロールすると、IP に関するセクションがあります。

命令ポインタ

EIP レジスタには、分岐が行われない場合に実行される次の命令のアドレスが含まれています。

EIP は、call 命令の後にのみスタックから読み取ることができます。

したがって、mov を使用して IP を読み取ることは本当に違法です。

call次にpop %axシーケンスを使用して ip を読み取る例がいくつかあります。

更新: SS レジスターの読み取りについて:

実際には、mov 命令のエンコードにはさまざまなバリエーションがあります。たとえば、このでは、セグメントの読み取りが見られます。

 mnemonic   op1 op2 po     o    description, notes 
 MOV    Sreg    r/m16   8E     r        Move

または制御レジスタの書き込み:

 MOV    r32 CRn 0F20   r ...    Move to Control Registers

しかし、IP 登録用の MOV はまだありません。

Update2: x86_64 では、https://stackoverflow.com/a/1047968/196561 によると、LEA を使用した EIP の読み取りがあります。

于 2012-10-11T00:05:13.517 に答える