与push一样的指令序列

rar*_*dea 4 x86 assembly stack x86-16

我想知道是否有可能(如果是这样,如何)编写一系列具有相同效果的指令push.例如,如果内容ax是1200,我做了push ax,我还可以用什么其他指令来完成什么push ax呢?

nrz*_*nrz 7

其他一些答案[sp]用于堆栈寻址,但在16位模式下,也不可能在32位或64位模式下.但是,在32位模式下,您可以使用[esp]和在x86-64中[rsp]用于存储器寻址,但在16位模式下,没有使用的存储器寻址sp.有关16位模式下可能的存储器寻址模式,请参见此处.

那么,您需要做什么:存储bp某处的值,复制spbp,然后bp用于寻址堆栈,最后恢复原始值bp.

如果你有一个存放的地方bp,这很容易(这是YASM/NASM语法):

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

...

bp_storage dw 0
Run Code Online (Sandbox Code Playgroud)

使用寄存器而不是像bp_storage这里的存储器地址也是微不足道的.

编辑:添加不修改标志的版本(如下),push也不修改标志.

上面的代码修改了标志,push ax而不修改任何标志.这可以通过首先存储要解决ah到存储器中,然后加载标志成ahlahf,然后从存储的标志ah到存储器,然后修改如上堆叠,然后通过事后从恢复存储器标志ah,通过使用sahf最后恢复ah从存储器.

编辑:push ax在不更改标志的情况下进行模拟,ah必须先保存lahf并在之前加载mov [bp],ax.固定.

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
Run Code Online (Sandbox Code Playgroud)

sub修改AF,CF,OF,PF,SF,ZF,而lahf负载和sahf只存储AF,CF,PF,SF,ZF(无OF).但是,sp永远不应该在正常的堆栈使用中溢出.

但是,如果你不能访问内存,并希望使用堆栈存储,bp你可以这样做,但如果你既没有免费的寄存器可供使用,事情变得复杂.但是,如果您使用的是实模式操作系统,则可以阻止中断cli,交换bpsp使用bp堆栈寻址,交换bpsp再次允许中断sti.

编辑:价值sp2中减去模拟的需求push ax.固定.此版本不会修改标志(中断标志除外).

cli
xchg bp,sp
lea bp,[bp-2]
mov [bp],ax
xchg bp,sp
sti
Run Code Online (Sandbox Code Playgroud)