27

x86 アセンブリに関するウィキペディアの記事には、「プログラマは IP レジスタに直接アクセスできない」と書かれています。

直接とは、mov や add などの命令を使用することを意味します。

なぜだめですか?この背後にある理由は何ですか? 技術的な制限は何ですか?

4

4 に答える 4

33

正当なユースケースがないため、直接アクセスすることはできません。命令を任意に変更eipすると、分岐予測が非常に難しくなり、セキュリティ上の問題が多数発生する可能性があります。

、またはeipを使用して編集できます。通常の操作を使用して直接読み書きすることはできませんjmpcallreteip

レジスタへの設定eipは簡単jmp eaxです。push eax; retの値をスタックにプッシュしてeaxから返す (つまり、ポップしてジャンプする)こともできます。3 番目のオプションはcall eax、eax のアドレスへの呼び出しを行うものです。

読み取りは次のように実行できます。

call get_eip
  get_eip:
pop eax ; eax now contains the address of this instruction
于 2011-11-30T21:51:53.360 に答える
13

これは、x86 の可能な設計でした。ARM は、読み取り/書き込み用のプログラム カウンターを R15 として公開します。しかし、それは珍しいことです。

これにより、非常にコンパクトな関数のプロローグ/エピローグが可能になり、1 つの命令で複数のレジスタをプッシュまたはポップする機能 ( push {r5, lr}開始時とpop {r5, pc}復帰時) が可能になります。(リンク レジスタの保存された値をプログラム カウンタにポップする)。

ただし、高パフォーマンス/順不同の ARM 実装の利便性が低下するため、AArch64 では削除されました。


可能ですが、レジスタの 1 つを使い果たします。32 ビット ARM には 16 個の整数レジスタ (PC を含む) があるため、レジスタ番号は ARM マシン コードでエンコードするのに 4 ビットかかります。別のレジスタはほとんどの場合、スタック ポインタとして結び付けられているため、ARM には 14 個の汎用整数レジスタがあります。(LRはスタックに保存できるため、関数本体内の汎用レジスタとして使用できます)。

最新の x86 のほとんどは 8086 から継承されています。かなりコンパクトな可変長命令エンコーディングで設計されており、8 つのレジスタしかなく、マシン コードの各 src および dst レジスタに 3 ビットしか必要としません。

オリジナルの 8086 では、それらはあまり汎用的ではなく、SP 相対アドレッシングは 16 ビット モードでは不可能であるため、本質的に 2 つのレジスタ (SP と BP) がスタック スタッフに結び付けられています。これにより、ある程度汎用的なレジスタが 6 つしか残されず、そのうちの 1 つを汎用ではなく PC にすると、使用可能なレジスタが大幅に減少し、典型的なコードでのスピル/リロードの量が大幅に増加します。


AMD64 では、r8-r15 と RIP 相対アドレッシング モードが追加されました。 lea rsi, [rip+whatever]、および静的データと定数に直接アクセスするための RIP 相対アドレッシング モードだけで、効率的な位置に依存しないコードを作成できます。RIP への書き込みには、間接的な JMP 命令で十分です。

整数レジスタと間接ジャンプでいつでも同じことができるので、任意の命令を使用して PC を読み書きできるようにしても、実際には何も得られません。x86-64 の R15 が RIP と同じであることは、特にコンパイラ ターゲットとしてのアーキテクチャのパフォーマンスにとって、ほぼ純粋な欠点です。(手書きの asm の奇妙なものは、AMD64 が設計された 2000 年までには、すでに非常に珍しいニッチなものでした。)

つまり、AMD64 は、x86 が ARM のように完全に公開されたプログラム カウンターを獲得できた初めてのケースですが、それを行わない十分な理由がたくさんありました。

于 2016-12-14T18:51:51.573 に答える
4

jmp will set the EIP register.

this code will set eip to 00401000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

and for getting EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret
于 2015-08-25T11:42:08.440 に答える
3

他のレジスタにアクセスするのと同じ方法で IP レジスタに直接アクセスできないことを意味していたと思います。プログラマーは、たとえばジャンプ命令を発行することによって、確実に IP に書き込むことができます。

于 2011-11-30T21:53:35.930 に答える