-1

最近、アセンブリ言語とともに C++ プログラミングを始めました。いくつかのことを明確にしたいと思います。

私が読んだことから、命令ポインターは、retn命令から次に実行するアドレスを取得します。命令ポインターも設定するjmpので、 a を実行するのと同じではありませんか?jmp

私が正しければ、 と はどう違いretnますjmpか? 私が間違っている場合、誰かが C 疑似コードで説明できますか?

無限ループに相当するアセンブリは何ですか?

互換性があると読みましたEAX,EBX,ECX,EDXが、違いはありますか?もしそうなら、どのシナリオで具体的に使用する必要がありますかEAX/EBX/ECX/EDX.

4

3 に答える 3

3

あなたはサブルーチン呼び出しについて話しているようです。そのため、ここにその詳細を示します。

サブルーチンを呼び出すと、次のようになります (アドレスは異なりますが、可変長命令と混同したくなかったためです)。

1234  call 8888
1235  <next instruction>

何が起こるかというと、call最初に次の命令ポインタをスタック (後入れ先出しデータ構造) に配置し、この場合1235、命令ポインタを呼び出しているものに設定します。8888

後で、リターンはで行われ8889ます:

8888  mov eax, 0
8889  ret

return が行うことは、スタックから最初の値 (つまり、1235呼び出しによってプッシュされた) を単純にポップし、それを命令ポインターにロードすることです。したがって、どこに行くべきかを伝える戻り値ではなく、呼び出しによってスタックにプッシュされた情報です。

サブルーチンの最後に命令がある場合jmp、コード内の 1 つのポイントにしか戻ることができません (現時点では、他のアドレッシング モードで実行できるすべての素晴らしいことを割り引いてください)。

8889  jmp 1235

return を使用すると、どこにいても元の場所に戻ります。


無限ループのアセンブラーは、次のように単純にすることができます。

loopy:
    jmp loopy

レジスタに関しては、eaxebxecxおよびedxは汎用レジスタと見なされます。これにより、スタック ポインター、ベース ポインター、ソースおよびデスティネーション インデックスなど、用途に応じて特殊な命令を持つ、より特殊な目的のレジスターとは区別されます。

axx86 アーキテクチャの非常に初期のイテレーションで追加の機能が追加された可能性がありますが、それがまだ当てはまるかどうかはわかりません。独自のものをコーディングしている場合は、ほとんどの場合、それらを互換的に使用できるはずです。API または ABI に従っている場合は、それが課す規則 (eaxシステム コール番号を保持する Linux システム コール インターフェイスなど) に従う必要があります。

于 2013-08-02T06:03:52.673 に答える
1

C/C++ 関数のretとの違いは次のようになります。jmp

int foo()
{
   int x = 3+4;

   if(x < 10)
      goto Quit;    <- similar to jmp

   x += 10;

 Quit:
   return x;     <- similar to ret

}

C で行う場合return、マシン レベルで実際に何が起こるかはもう少し複雑です。たとえば、戻り値を入れてeaxスタックをクリーンアップするなど、追加のコードが頻繁に実行されるためです。C++ ではローカル オブジェクトも同様に破棄されますが、関数の最後とはret命令になります。

無限ループに相当するアセンブリは何ですか?

while(1);

のようなものです

000000 jmp 000000

以上

00000  inc ecx
00001  jmp 00000

汎用レジスタ。場合によっては、レジスタを混在させて、必要に応じて使用できます。一部の命令では、特定のレジスタを使用することを想定しています。これがどこに当てはまるかを確認するには、取扱説明書を調べる必要があります。

1 つの例は で、これにはとmovswを使用する必要があるため、この場合は自由に選択できません。追加でご利用の場合はこちらもご利用ください。通常、アセンブラは命令に対して有効なレジスタを認識し、エラー メッセージを表示しますが、アセンブラがエラーをスローできない場合、予期しない結果が生じる可能性があるため、マニュアルを参照して確認する必要があります。(E)SI(E)DIrep movsw(E)CX

于 2013-08-02T10:18:45.930 に答える
0

eaxandedxは、除算の暗黙のオペランドであり、乗算のワイド結果バージョンの int です。rax(オペコード 98) の一部のみで動作する、または (オペコード 99) に符号拡張eaxする特別な符号拡張命令もありますedx:eax。10 進数の演算命令はすべて の一部で機能しeaxます。

ecx(cl実際には十分に近い) は、Haswell ( を導入しsarxshlxそのshrxすべてが任意の GPR によってシフトできる) の前にシフトできる唯一のレジスタです。ecxrep-prefixes によるカウンターとしても使用されます。pcmp*stri長さを に入れecxます。

多くの専用命令には明示的なオペランドがありませんが、代わりに特定の GPR に特別な意味cpuidを割り当てます。通常は、しばしば同様に、非常にまれです。おそらく、これらに多く対処する必要はありません。rdpmcrdtscwrmsrxgetbvxsaveedx:eaxecxebx

于 2013-08-02T07:43:41.523 に答える