4

と同じ効果を持つ一連の命令を書くことが可能かどうか(もしそうなら、どのように)を知りたいですpush。たとえば、の内容axが1200で、を実行したpush ax場合、他にどのような命令を使用して何を実行できpush axますか?

4

4 に答える 4

7

他のいくつかの回答[sp]はスタックアドレス指定に使用されますが、16ビットモードでも、32ビットまたは64ビットモードでも不可能です。ただし、32ビットモードでは使用でき[esp]、x86-64[rsp]ではメモリアドレス指定に使用できますが、16ビットモードではを使用するメモリアドレス指定はありませんsp。16ビットモードで可能なメモリアドレッシングモードについては、ここを参照してください。

So, what you need to do: store the value of bp somewhere, copy sp into bp, then use bp for addressing the stack, and finally restore the original value of bp.

If you have a place where to store bp, that's easy (this is in YASM/NASM syntax):

mov [bp_storage], bp
sub sp,2
mov bp,sp
mov [bp],ax
mov bp,[bp_storage]

...

bp_storage dw 0

Using a register instead of memory address like bp_storage here is trivial too.

Edit: Added version that does not modify flags (below), as push doesn't modify flags either.

The code above modifies flags, whereas push ax does not modify any flags. That can be solved by storing first ah into memory, then loading flags into ah with lahf, then storing the flags from ah to memory, then modifying the stack as above, and then afterwards restoring flags from memory via ah by using sahf and finally restoring ah from memory.

Edit: To simulate push ax without changes in flags, ah must be saved before lahf and loaded before mov [bp],ax. Fixed.

mov [ah_storage],ah
lahf
mov [flags_storage],ah
mov [bp_storage],bp
sub sp,2
mov bp,sp
mov ah,[ah_storage]
mov [bp],ax
mov bp,[bp_storage]
mov ah,[flags_storage]
sahf
mov ah,[ah_storage]

...

bp_storage    dw 0
ah_storage    db 0
flags_storage db 0

sub modifies AF, CF, OF, PF, SF, ZF, whereas lahf loads and sahf stores only AF, CF, PF, SF, ZF (no OF). However, sp should never overflow in normal stack usage.

But, if you can't access memory, and want to use stack to store bp you can do that, but if you neither have free registers to use, things get complicated. But if you are using a real mode OS, you can block interrupts with cli, exchange bp and sp, use bp for stack addressing, exchange bp and sp again and allow interrupts again with sti.

Edit: the value of sp needs to subtracted by 2 to simulate push ax. Fixed. This version does not modify flags (except interrupt flag).

cli
xchg bp,sp
lea bp,[bp-2]
mov [bp],ax
xchg bp,sp
sti
于 2013-02-14T18:39:31.790 に答える
2

少なくともメモリが機能する場合、それはほぼ次のようになります。

sub sp, 2
mov [sp], ax
于 2013-02-14T18:05:19.950 に答える
1

spから必要なデータ書き込みのサイズに等しい値を減算し、必要なオブジェクトをスタック上で移動/書き込みします。コンパイラは常にこの種のことを行います。例については、-S出力を参照してください。これを行う場合は、アトミック/スレッドの問題に注意してください...

于 2013-02-14T18:08:11.670 に答える
1

Intel構文を忘れていない場合:

lea sp, [sp-2]
mov [sp], ax

私は以前はlea触れないようにしていますFLAGS(触れたり触れpushたりすることはありませんが、そうします)。movleasubdec

編集:私はもっと重要なことを忘れていることがわかりました:[sp]アドレッシングモードはありません。正解は@nrzによるもので、私のものは80386以降に適用できますespeaxそうなるでしょうlea esp,[esp-4])。

于 2013-02-14T18:09:52.177 に答える