問題タブ [stack-pointer]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
assembly - %esp と CDECL のインクリメント
私は x86 スタックと CDECL 規則について読んでいて、私を混乱させる何かを読みました。
リストされた呼び出し元の責任の中には、パラメーターのポップ、パラメーターの使用、または単純に %esp をインクリメントしてパラメーターを削除することがありました。
その最後の部分はどのように機能しますか?
たとえば、%esp の初期値が 0x105000 で、現在のスタック フレームに対して $0x1c だけデクリメントするとします。いくつかのデータを割り当ててから、それをインクリメントして戻します。その場合、そのデータはまだメモリ内に浮かんでいませんか? メモリはどのようにクリアされますか? 0x104FF4 にアクセスするとセグメンテーション違反が発生しますか?もしそうなら、何がデータをクリアしたのでしょうか?
assembly - アセンブリでプッシュとポップがどのように機能するか
pop
アセンブリで実際に何をするのか混乱しています。pop
値PUSH
ed を最後にスタックに移動するか(つまりMOV
、最後の要素PUSH
ed の後に値がある場合は適用されません)、スタックの最後にある値をポップします (したがって、 と の両方に適用されますMOV
) PUSH
、またはスタックポインタが指す値をポップしますか? 次のコードを検討してください。
したがって、このコードでは、ポップさebp
れる値は 4、5、または が指す未知の値になりesp
ますか?
assembly - 関数を呼び出すときにスタック ポインターをデクリメントする必要があるのはなぜですか
私はしばらくの間アセンブリを勉強しており、コツをつかみ始めていますが、理解できないように見えることの 1 つは、ローカルのローミングを終了するためにスタック ポインターをデクリメントする必要がある理由です。変数については、次のコードを見てください: (64 ビット GNU コンパイラ、AT&T 構文でコンパイルされたコード)
この小さなプログラムでは、esp を 48 ずつデクリメントする必要なく、これらすべてを実行できると想像できます。ベース ポインターを使用してスタックから値を移動したり、スタックに値を移動したり、esp を同じ位置にポイントさせて ebp をポップする準備ができているだけです。そして戻る。誰かがローカル変数のために「余地」を残す必要がある理由を明確にすることができますか? ありがとう!!これがばかげた質問のように思われる場合は、お詫び申し上げます
assembly - esp レジスタの使用
アセンブリでスタックを使用する方法を理解しようとしていたところ、SO の質問の 1 つで次のコードに出くわしました。
この場合、ecx は数値を保持しており、作成者は (間違っている場合は訂正してください!) 最初にスタック ポインターを ecx に移動し、次に ecx がメモリ アドレスに 48 を追加して数値を ASCII 文字に変換することによって数値を表示しています。指しています。彼は同じことを「pop ecx」で実行してから ascii に変換できたでしょうか? 著者がなぜこのように進めているのか、私にはよくわかりません。どんな助けでも大歓迎です。
c++ - vector、sfml、および「関数呼び出し全体で esp の値が適切に保存されませんでした」というエラー
構造体「Layer」とクラス「LayerHandler」があります。レイヤーは、テクスチャ、スプライト、および 2 つのコンストラクター (1 つはデフォルト、もう 1 つは参照パラメーター付き) のみで構成されます。LayerHandler クラスは、すべてのレイヤーの描画を処理するクラスです。このクラスにレイヤーを追加し、後で win.draw(layerhandler_object) を使用してすべてを描画します。そのために、LayerHandler は Drawable から継承し、virtual void draw() をオーバーライドします。
LayerHandler.h:
LayerHandler.cpp:
およびmain.cpp:
複雑ではなく、すべて問題なく実行できたと思いますが、「関数呼び出し全体で ESP の値が適切に保存されていませんでした」というエラーが表示されます。なぜこのエラーが発生するのかわかりません。呼び出し規約の不一致が原因である可能性があることはわかっていますが、コードにそのようなものは見当たりません...このエラーが発生したのはこれが初めてであり、完全にアウトです対処方法のアイデアです。何か助けはありますか?
assembly - Motorola 68k のユーザー スタック ポインターとシステム スタック ポインターを理解する
アセンブリ言語 (Motorola 68k) でのスタックの使用法と実装を理解しようとしています。
MC 68k には 8 つのアドレス レジスタがあり、A7 は特別なものです。2 つのスタック ポインタであるため、「システム スタック ポインタ」の名前を共有します。
また、ユーザー状態とスーパーバイザー状態の 2 つの状態があります。どこ:
supervisor state-
今、これらの2つの質問に答える方法がわかりません:
68000 に 2 つのハードウェア スタック ポインタがあるのはなぜですか?
コードを書く
レジスタ D1、D3、A2 ~ A6 のロングワード値をランタイムスタックに保存します。
/li>
これは正しいでしょうか?
ここで、「runtimestack」と呼ばれるものが何であるかわかりません。また、(SP) と (A7) の実際の違いが何であるかもわかりません。どんな助けでも大歓迎です。
assembly - どのように esp レジスタは移動しますか?
次のようなコードがあります。
xxx(1234);
私は gdb を使用して、ESP レジスタの値と、行にブレークポイントを作成することによってどのように機能するかを示しますc=b;
。
プログラムを実行し、最初のブレークポイントで停止し、 と を使用i r esp
しx/x $esp
ます。esp が 0xbbbbefff などを指しており、このアドレスには 0xbb33bb33 などのその他の値が含まれていることを示しています。2 番目のブレークポイントに進みます。上記の 2 つのコマンドを繰り返して、アドレス 0xbbbbefff の値を調べると、0x000004d2 (10 進数で 1234) が表示されます。
ESP がスタックの先頭を指していることはわかっています。値をスタックにプッシュすると、下位アドレスに移動し、そのアドレスのメモリに値が格納されます。たとえば、最初のブレークポイントで ESP がアドレス 0xbbbbefff を指している場合、2 番目のブレークポイントで ESP は 0xbbbbefff-4=0xbbbbeffa のような場所を指し、0x000004d2 を含み、0xbbbbefff のメモリにはまだ 0xbb33bb33 が含まれている必要があります。しかし、gdb で 0x000004d2 値が 0xbbbbefff (xxx 関数を呼び出す前の前のトップ スタック) に含まれていることがわかりました。
スタックについて間違って理解していますか?
function - C コール スタックは "ebp" を使用して変数にアクセスしますが、"esp" は冗長に見えますか?
C 関数は、呼び出しスタック (スタック フレーム) を使用して、関数呼び出しの前後にレジスタをプッシュ/ポップします。ebp がスタック上のすべての変数を参照するために使用されるフレーム ポインターである場合、esp は冗長に見えますか?
では、なぜ関数呼び出しのプロローグ/エピローグで、esp と ebp の両方を操作するのでしょうか? この仕事をするために1つのレジスターだけを使用すると、不便な場所はありますか?
ありがとう。