インラインasmからの新しいコールスタック(ESP)としてC配列を設定しますか?

Anton9988

私のタイトルから示唆されているように、C配列を割り当て、それに応じてESPレジスタを指すことでスタックのように動作させることができるかどうかに興味があります。

いくつかのコード例...

void foo(){
   int x = 99;
   int y = 89;
   return;
}
char myStack[1024];
void main(){
     int main_num = 66;
     __asm volatile("movl %0, %%esp": : "rm" (&myStack+1)); //Move ESP to the end of the array
     foo();
     return 0;
}

このコードの背後にある考え方は、最初にESPをmyStack配列の最後にポイントし(スタックは下位アドレスに向かって成長するため)、次にfoo()を呼び出して、特にfoo()用に別のスタックを作成することです。この新しいスタック(C配列)に格納されているリターンアドレスとローカル変数。

そのようなアプローチも可能だろうか?もしそうなら、それを達成する方法は?

上記のコードを実装しようとしているときに、スタックに関する情報を確認するためにGDBを実行しました(例:GDBのinfo stackコマンド)。「スタックなし」が表示され続けました。これは、スタックポインタが深淵に送信されたことを意味します。

PS:私はこれをカーネルレベルのコードとして実装しています

ピーター・コーデス

たぶん、これはおもちゃの実験でのみ機能する巨大な危険なハックとして機能する可能性があります。新しいスタックを設定する場合は、C関数を呼び出す前に、手書きのasmで設定してください。

このハックはへの呼び出しで機能する可能性がありますがfoo()、どうreturn 0;ですか?コンパイラで生成されたコードは、現在の%espからリターンアドレスをポップしようとします。

(または、最適化が無効になっている場合は、保存されたEBPをポップする前にleaveどのセットを使用ESP = EBPます。これにより、初期スタックに戻ります。したがって、動作は最適化レベルによって異なります。これは望ましくありません。)

GDBを使用してコードをシングルステップし、実際にreg値が変化するのを監視します(例:layout reg

しかし、はい、&myStack + 1は配列の最後の1つのアドレスでありmovl $myStack+1024, %eax、asmステートメントのセットアップとして生成されます(コンパイラがオペランドにそのレジスタを選択したため、テンプレート内%0展開さ%eax"rm"ます。あなたはしませんでした即時定数のオプションを指定するか、)を使用してそれを実行しmovl $myStack+1024, %espます。

https://godbolt.org/z/Nz6DgAは、それが「機能」し、最適化を有効にしてretに到達するとすぐにクラッシュすることを示しています。これは、popESPがの最後の1つを指しているためですmyStack

私は現在、カーネルレベルでのスレッドの実装をいじっています。したがって、スレッドごとに個別のスタックを割り当て、それらの間でシフトするというアイデアがあります。

特にmain実際returnに必要な場合、はい、スタックを設定してから何か使用する必要がありますcallそうしないと、その最終的なリターンアドレスが間違ったスタックになります。

たとえば、Linuxでは、pthreadライブラリは、に割り当てて、mmap()そのスタックアドレスをオペランドとしてに渡すことにより、新しいスタックで新しいスレッドを作成clone()ます。したがって、新しいスレッドは親のスタックを使用することはなく、独自のスタックのみを使用します。新しいタスクのカーネル側のスレッドスタックの作成も同様だと思います。あなたは、新しいスタックを割り当て、その後、新しいスレッドコンテキストのためにそれを使用します。

新しいスレッドで呼び出された最初の関数が実際にスレッド出口/クリーンアップ関数に戻るように、先頭に「リターンアドレス」を置くことができます。おそらくそのためのいくつかのasmで。または、実際のスレッドエントリポイントを返さない関数にします。代わりに、スレッドコンテキストをクリーンアップして別のスレッドに切り替えるか、スケジューラなどを呼び出します。

それは私が目指していることの一種であり、メインのスタックではなく独自のスタックを使用するスレッドを持っています。ただし、ページングを有効にしていないため、今のところスタック作成をできるだけ簡単に実装したいと思います(したがって、C配列は簡単な解決策のように見えました)

残念ながら、これは単純すぎて実際には機能しません。

はい、スレッドスタックにC配列を使用できます(余分なスレッドが1つしかない場合は...)、問題はそれに切り替える方法です。

ある時点で、あるレジスタコンテキストを保存して別のレジスタコンテキストをロードするコンテキストスイッチ関数を作成する必要があります。(たとえば、Googleは、Stack Overflowでいくつか見つけることができ、おそらくhttps://www.osdev.org/で何かを見つけることができます。)

スタックポインタがスレッドスタックの最上位を指し、EIPがスレッドエントリポイントを指すように、メモリ内に新しいスレッドコンテキスト構造体を作成します。コンテキストスイッチ関数を呼び出して、その新しいコンテキストに切り替えます。

CコンパイラのPOVからは、コンテキストスイッチ関数は他の関数呼び出しと同じように見えます。最終的には戻り、グローバルに到達可能なCオブジェクトが変更された可能性があります。一時的にESPが別の場所を指していることは問題ではありません。「他の関数呼び出しと同様に」には、call-clobberedレジスタのクラバリングが含まれるため、EAX / ECX / EDXを保存/復元する必要はありません。コンテキストスイッチ関数の呼び出し元は、すでにそれらが破棄されていると想定しています。

通常、インラインasmではなくasmで手書きする必要があります。インラインasmからESPを変更することは危険を伴い、GCCでサポートされていないものとして公式に文書化されています。

これは、コンパイラが、asmステートメントの後のスタックポインタの値が、ステートメントへのエントリ時と同じである必要があるためです。

https://gcc.gnu.org/wiki/DontUseInlineAsmも参照してください

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

データベースからのPHP配列、配列タイトルとして行を設定します

分類Dev

各配列の最初の要素をインデックスとして設定し、残りを配列の配列のデータとして設定します

分類Dev

各配列の最初の要素をインデックスとして設定し、残りを配列の配列のデータとして設定します

分類Dev

データフレームの新しい列に値を割り当てると、「データフレームからのスライスのコピーに値を設定しようとしています」というエラーが発生します。

分類Dev

コールバックを受け入れるテンプレート関数を使用してCスタイルの配列を設定します

分類Dev

外部関数/クラスから動的配列の新しいサイズを設定しますか?

分類Dev

Foreach配列を作成し、インデックスに基づいて新しい配列を作成してから、それをループします

分類Dev

jQueryプラグインのコールバックでAPIから新しいデータを取得します

分類Dev

PHP配列からクラスの新しいインスタンスを取得します(POSTを介して送信されます)

分類Dev

マップ使用時のパンダの警告:DataFrameからのスライスのコピーに値を設定しようとしています

分類Dev

配列クラス属性からコールバックを設定して実行します

分類Dev

ボタンの背景を配列からランダムな色に設定しようとしています

分類Dev

インクルードからプライベート静的配列内の変数をエコーしようとしています

分類Dev

一度に多くの配列インデックスを設定しますか?複合リテラル?

分類Dev

パンダは、新しいインデックスとして列の分割を使用してインデックスを設定します

分類Dev

WPFコンボボックスのスタイルを設定して、以前のバージョンのように見せることはできますか?

分類Dev

テキストボックス、ラジオボタン、スライダーコントロールwpfから値を取得しようとしています。

分類Dev

numpy配列からPandasデータフレームを作成し、配列の最初の列をインデックスとして使用します

分類Dev

PHP配列からドロップダウンリストのインデックスを設定します

分類Dev

配列のインデックス(ランダムに選択されてからスプライスされている)を別の配列にコピーして、スプライスされた順序がわかるようにします

分類Dev

Cのスイッチケースラベルとして定数インデックスを持つ定数配列を使用する方法はありますか?

分類Dev

VS2015のパッケージマネージャーコンソールからEntityframework7をインストールしているときに、Nugetエラー「オブジェクト参照がオブジェクトのインスタンスに設定されていません」

分類Dev

HTMLはユーザーからのファイルを使用し、バックグラウンドとして設定しますか?

分類Dev

実行ボックスを使用してWindows10で使いやすいカーソルとポインターの設定を開きますか?

分類Dev

MySqlワークベンチでタイムスタンプとして列を設定しますか?

分類Dev

パンダのタプルインデックスとして2つの列を設定します

分類Dev

インターフェイスの配列から統計情報をプルしていますか?

分類Dev

pandas:DataFrameからのスライスのコピーに値を設定しようとしています

分類Dev

SettingWithCopyWarning:DataFrameからのスライスのコピーに値を設定しようとしています警告

Related 関連記事

  1. 1

    データベースからのPHP配列、配列タイトルとして行を設定します

  2. 2

    各配列の最初の要素をインデックスとして設定し、残りを配列の配列のデータとして設定します

  3. 3

    各配列の最初の要素をインデックスとして設定し、残りを配列の配列のデータとして設定します

  4. 4

    データフレームの新しい列に値を割り当てると、「データフレームからのスライスのコピーに値を設定しようとしています」というエラーが発生します。

  5. 5

    コールバックを受け入れるテンプレート関数を使用してCスタイルの配列を設定します

  6. 6

    外部関数/クラスから動的配列の新しいサイズを設定しますか?

  7. 7

    Foreach配列を作成し、インデックスに基づいて新しい配列を作成してから、それをループします

  8. 8

    jQueryプラグインのコールバックでAPIから新しいデータを取得します

  9. 9

    PHP配列からクラスの新しいインスタンスを取得します(POSTを介して送信されます)

  10. 10

    マップ使用時のパンダの警告:DataFrameからのスライスのコピーに値を設定しようとしています

  11. 11

    配列クラス属性からコールバックを設定して実行します

  12. 12

    ボタンの背景を配列からランダムな色に設定しようとしています

  13. 13

    インクルードからプライベート静的配列内の変数をエコーしようとしています

  14. 14

    一度に多くの配列インデックスを設定しますか?複合リテラル?

  15. 15

    パンダは、新しいインデックスとして列の分割を使用してインデックスを設定します

  16. 16

    WPFコンボボックスのスタイルを設定して、以前のバージョンのように見せることはできますか?

  17. 17

    テキストボックス、ラジオボタン、スライダーコントロールwpfから値を取得しようとしています。

  18. 18

    numpy配列からPandasデータフレームを作成し、配列の最初の列をインデックスとして使用します

  19. 19

    PHP配列からドロップダウンリストのインデックスを設定します

  20. 20

    配列のインデックス(ランダムに選択されてからスプライスされている)を別の配列にコピーして、スプライスされた順序がわかるようにします

  21. 21

    Cのスイッチケースラベルとして定数インデックスを持つ定数配列を使用する方法はありますか?

  22. 22

    VS2015のパッケージマネージャーコンソールからEntityframework7をインストールしているときに、Nugetエラー「オブジェクト参照がオブジェクトのインスタンスに設定されていません」

  23. 23

    HTMLはユーザーからのファイルを使用し、バックグラウンドとして設定しますか?

  24. 24

    実行ボックスを使用してWindows10で使いやすいカーソルとポインターの設定を開きますか?

  25. 25

    MySqlワークベンチでタイムスタンプとして列を設定しますか?

  26. 26

    パンダのタプルインデックスとして2つの列を設定します

  27. 27

    インターフェイスの配列から統計情報をプルしていますか?

  28. 28

    pandas:DataFrameからのスライスのコピーに値を設定しようとしています

  29. 29

    SettingWithCopyWarning:DataFrameからのスライスのコピーに値を設定しようとしています警告

ホットタグ

アーカイブ