1

さて、スタックはどのように機能しますか?たとえば、命令:

push ax

に等しい:

sub sp, 4
mov sp, ax

ここで、sp はスタック ポインタです。そうですか?

私の質問は、sp レジスタから 4 を減算するポイントは何ですか?

4

4 に答える 4

6

読むべきだと思う

sub  sp, 2       ; AX is only 2 bytes wide, not 4
mov [sp], ax     ; store to memory, not writing the register

つまり、ax の値を sp が指すメモリに入れます。

おそらくsub sp, 4、32ビットレジスタをプッシュしたことから来ましたか? スタック ポインタは常にプッシュ オペランド サイズだけ減少します。

push(は、 とは異なり、FLAGS を変更しないことに注意してくださいsub。この疑似コード / 同等のものは、厳密には同等ではなく、大文字と小文字の区別もありません。これらの場合でも動作する疑似コードについては、 Intel のマニュアルまたはこの Q&Apush spを参照してください。)

于 2013-07-02T20:53:55.680 に答える
1

それはどのようにpush ax機能するかではありません。それが「等しい」ことのコード例は次のとおりです。

sub sp, 2
mov [ss:sp], ax

SP の値を AX で上書きしません。代わりに、SS:SP が指すメモリ アドレスに AX をコピーします (データ セグメントではなく、スタック セグメントを使用します)。ただし、実際には、これは正確ではありません。本当に必要なのは次のようなものです。

mov [tmp], sp
pushf          ;push FLAGS
sub [tmp], 2
popf
mov sp, [tmp]
mov [ss:sp], ax

基本的に、push非常に単純なことを行いますが、その単純なことにまつわる詳細は、独自の説明を作成する価値があります。push word [bp - 4]特に、ローカル変数をまだロードしていない場合にローカル変数をプッシュするなどの命令を使用して、メモリからメモリにコピーできること。

[ss:sp]16 ビット アドレッシング モードとしてエンコードできない架空のアドレッシング モードを必要とせず、使用しない代替コード。

mov internal_tmp, sp
lea internal_tmp, [internal_tmp - 2]   ; sub without FLAGS
mov [internal_tmp], SRC_OPERAND        ; even for a memory source, or for push sp
mov sp, internal_tmp
于 2013-07-02T20:55:07.753 に答える
0

違いはsub esp, 4フラグを設定しますが、プッシュはフラグを設定しません。また、それはする必要がありますmov [esp],eax。表示されている 16 ビット バージョンは、非常に古い本を使用していることを示しています。16 ビット マシンでプログラミングする人はもういません (おそらく、組み込みマイクロコントローラーを除く)。

x86 では、OF、SF、ZF、ZF、PF、および CF フラグは減算によって設定されますが、フラグは a の影響を受けませんPUSH

于 2013-07-02T20:55:38.237 に答える
0

の値をax次に利用可能なスタック フレームに移動しています。スタック ポインターは下方に構築されるため (値が多すぎる場合、ゼロを超えてアンダーフローし、重要なものにオーバーフローする代わりにエラーが発生します)、次に利用可能なスタック フレームの位置は、現在の位置の 1 ワード (4 バイト) 前になります。

于 2013-07-02T20:55:01.827 に答える