其他一些答案[sp]用于堆栈寻址,但在16位模式下,也不可能在32位或64位模式下.但是,在32位模式下,您可以使用[esp]和在x86-64中[rsp]用于存储器寻址,但在16位模式下,没有使用的存储器寻址sp.有关16位模式下可能的存储器寻址模式,请参见此处.
那么,您需要做什么:存储bp某处的值,复制sp到bp,然后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到存储器中,然后加载标志成ah与lahf,然后从存储的标志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,交换bp和sp使用bp堆栈寻址,交换bp并sp再次允许中断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)